Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] clk: mvebu: fix clk init order
From: Thomas Petazzoni @ 2014-01-27 14:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390673950-4521-1-git-send-email-sebastian.hesselbarth@gmail.com>

Dear Sebastian Hesselbarth,

On Sat, 25 Jan 2014 19:19:06 +0100, Sebastian Hesselbarth wrote:
> This patch set fixes clk init order that went upside-down with
> v3.14. I haven't really investigated what caused this, but I assume
> it is related with DT node reordering by addresses.
> 
> Anyway, with v3.14 for MVEBU SoCs, the clock gating driver gets
> registered before core clocks driver. Unfortunately, we cannot
> return -EPROBE_DEFER in drivers initialized by clk_of_init. As the
> init order for our drivers is always core clocks before clock gating,
> we maintain init order ourselves by hooking CLK_OF_DECLARE to one
> init function that will register core clocks before clock gating
> driver.
> 
> This patch is based on pre-v3.14-rc1 mainline and should go in as
> fixes for it. As we now send MVEBU clk pull-requests to Mike directly,
> I suggest Jason picks it up as a topic branch.

I'm not sure I really like the solution you're proposing here. I'd very
much prefer to keep one CLK_OF_DECLARE() per clock type, associated to
one function registering only this clock type.

Instead, shouldn't the clock framework be improved to *not* register a
clock until its parent have been registered? If the DT you have the
gatable clocks that depend on the core clocks, then the gatable clocks
should not be registered if the core clocks have not yet been
registered.

Do you think this is possible? Am I missing something here?

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH 1/9] ARM: dts: imx6qdl: remove the use of pingrp macros
From: Russell King - ARM Linux @ 2014-01-27 14:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390668191-20289-2-git-send-email-shawn.guo@linaro.org>

On Sun, Jan 26, 2014 at 12:43:03AM +0800, Shawn Guo wrote:
>  arch/arm/boot/dts/imx6dl-hummingboard.dts  |    5 +-
>  arch/arm/boot/dts/imx6qdl-microsom.dtsi    |    5 +-

I've merged your changes here into my local copy of these just to reduce
the conflicts - unfortunately, it's taken soo long to deal with the above
that the cubox-i has now been released, which has prompted some
reorganisation between the above two files.

I would much rather you dropped these two entirely, and let me push them
upstream, rather than having some nasty conflicts which result from this.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH v5 07/14] ahci-platform: "Library-ise" ahci_probe functionality
From: Roger Quadros @ 2014-01-27 14:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E642F7.3000308@redhat.com>

On 01/27/2014 01:28 PM, Hans de Goede wrote:
> Hi,
> 
> On 01/27/2014 12:03 PM, Roger Quadros wrote:
>> On 01/27/2014 12:51 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 01/27/2014 11:39 AM, Roger Quadros wrote:
>>>> Hi,
>>>>
>>>> On 01/22/2014 09:04 PM, Hans de Goede wrote:
>>>
>>> <snip>
>>>
>>>>> --- a/include/linux/ahci_platform.h
>>>>> +++ b/include/linux/ahci_platform.h
>>>>> @@ -20,7 +20,13 @@
>>>>>    struct device;
>>>>>    struct ata_port_info;
>>>>>    struct ahci_host_priv;
>>>>> +struct platform_device;
>>>>>
>>>>> +/*
>>>>> + * Note ahci_platform_data is deprecated. New drivers which need to override
>>>>> + * any of these, should instead declare there own platform_driver struct, and
>>>>> + * use ahci_platform* functions in their own probe, suspend and resume methods.
>>>>> + */
>>>>>    struct ahci_platform_data {
>>>>>        int (*init)(struct device *dev, struct ahci_host_priv *hpriv);
>>>>>        void (*exit)(struct device *dev);
>>>>> @@ -35,5 +41,13 @@ int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
>>>>>    void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
>>>>>    int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
>>>>>    void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
>>>>> +struct ahci_host_priv *ahci_platform_get_resources(
>>>>> +    struct platform_device *pdev);
>>>>
>>>> Why not use 'struct device' as the argument?
>>>
>>> Because of calls to platform_get_resource inside the function.
>>>
>>>>> +void ahci_platform_put_resources(struct ahci_host_priv *hpriv);
>>>>
>>>> Can we have 'struct device' as the argument? Else it becomes
>>>> impossible to get 'struct device' from 'hpriv' if we need to call e.g.
>>>> pm_runtime_*() APIs.
>>>
>>> The plan for is for this function to go away once we have a
>>> devm version of of_clk_get, so if you need to put pm_runtime_calls
>>> somewhere, please don't put them here. This sounds like something which
>>> should go in enable / disable resources instead ?
>>
>> OK. I need to add pm_runtime_enable() + pm_runtime_get_sync() during
>> initialization and pm_runtime_put_sync() + pm_runtime_disable() during cleanup.
> 
> Note that enable / disable resources will get called by (the default implementations
> of) suspend / resume too.
> 
> If that is undesirable then I take back what I said before and
> ahci_platform_put_resources' prototype should be changed to:
> 
> void ahci_platform_put_resources(struct device *dev, struct ahci_host_priv *hpriv);
> 
> And we will need to keep it around even after we get devm_of_clk_get.
> 
>> If ahci_platform_enable/disable_resources is the right place then we must be
>> able to access struct device from there.
> 
> Right, and if not we need to access it from ahci_platform_put_resources(),
> which is in essence the same problem.
> 
>> Is it a good to add 'struct device *dev' into the 'struct ahci_host_priv'?
>> Then you can leave this series as is and i'll add a new patch for that.
> 
> Normally we get a device * as argument, and get to hpriv like this:
> 
>         struct ata_host *host = dev_get_drvdata(dev);
>         struct ahci_host_priv *hpriv = host->private_data;
> 
> So having a dev * in hpriv is normally not useful.
> 
> But the ata_host gets allocated after the first ahci_platform_enable_resources
> call, so we cannot use this there. Likewise disable_resources / put_resources
> is used in error handling paths in probe where we don't have an ata_host yet,
> so my vote goes to adding a "struct device *dev" as first argument, like I
> suggested above for ahci_platform_put_resources.
> 
> This can be done as an add-on patch (if you do don't forget to also fix
> ahci_sunxi.c and ahci_imx.c), or I can respin my series to have this from
> day one.
> 
> If you want me to do a respin, please let me know which fix you'll need
> (the put_resources or the enable/disable one).
> 

For now I'm using get/put_resources to enable runtime PM and enable the device
like in the below patch.

I'll make the necessary changes to ahci_platform_put_resources();

cheers,
-roger

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 5ec6fe6..965f4b4 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/libata.h>
 #include <linux/ahci_platform.h>
+#include <linux/pm_runtime.h>
 #include "ahci.h"
 
 static void ahci_host_stop(struct ata_host *host);
@@ -233,6 +234,9 @@ struct ahci_host_priv *ahci_platform_get_resources(
                }
        }
 
+       pm_runtime_enable(dev);
+       pm_runtime_get_sync(dev);
+
        return hpriv;
 
 free_clk:
@@ -246,6 +250,9 @@ void ahci_platform_put_resources(struct ahci_host_priv *hpriv)
 {
        int c;
 
+       pm_runtime_put_sync(dev);
+       pm_runtime_disable(dev);
+
        for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
                clk_put(hpriv->clks[c]);
 }
@@ -478,6 +485,11 @@ int ahci_platform_resume(struct device *dev)
        if (rc)
                goto disable_resources;
 
+       /* We resumed so update PM runtime state */
+       pm_runtime_disable(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+
        return 0;
 
 disable_resources:

^ permalink raw reply related

* [PATCH RFC 4/6] net: rfkill: gpio: add device tree support
From: Maxime Ripard @ 2014-01-27 14:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1389941251-32692-5-git-send-email-wens@csie.org>

Hi,

On Fri, Jan 17, 2014 at 02:47:29PM +0800, Chen-Yu Tsai wrote:
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
>  .../devicetree/bindings/rfkill/rfkill-gpio.txt     | 26 ++++++++++++++++++++++
>  net/rfkill/rfkill-gpio.c                           | 23 +++++++++++++++++++
>  2 files changed, 49 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt
> 
> diff --git a/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt b/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt
> new file mode 100644
> index 0000000..8a07ea4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rfkill/rfkill-gpio.txt
> @@ -0,0 +1,26 @@
> +GPIO controlled RFKILL devices
> +
> +Required properties:
> +- compatible	: Must be "rfkill-gpio".
> +- rfkill-name	: Name of RFKILL device
> +- rfkill-type	: Type of RFKILL device: 1 for WiFi, 2 for BlueTooth
> +- NAME_shutdown-gpios	: GPIO phandle to shutdown control
> +			  (phandle must be the second)

Can't it be handled by a regulator?

> +- NAME_reset-gpios	: GPIO phandle to reset control

And this one using the reset framework?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140127/fbf86da7/attachment-0001.sig>

^ permalink raw reply

* [PATCH 2/2] dmaengine: at_hdmac: run callback function with no lock held nor interrupts disabled
From: Nicolas Ferre @ 2014-01-27 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1390832343.git.nicolas.ferre@atmel.com>

Now, submission from callbacks are permitted as per dmaengine framework. So we
shouldn't hold any spinlock nor disable IRQs while calling callbacks.
As locks were taken by parent routines, spin_lock_irqsave() has to be called
inside all routines, wherever they are required.

The little used atc_issue_pending() function is made void.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/dma/at_hdmac.c | 121 +++++++++++++++++++++++++++++--------------------
 1 file changed, 71 insertions(+), 50 deletions(-)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index b28759b6d1ca..f7bf4065636c 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -268,10 +268,14 @@ static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan,
 static int atc_get_bytes_left(struct dma_chan *chan)
 {
 	struct at_dma_chan      *atchan = to_at_dma_chan(chan);
-	struct at_desc *desc_first = atc_first_active(atchan);
+	struct at_desc *desc_first;
 	struct at_desc *desc_cur;
+	unsigned long flags;
 	int ret = 0, count = 0;
 
+	spin_lock_irqsave(&atchan->lock, flags);
+	desc_first = atc_first_active(atchan);
+
 	/*
 	 * Initialize necessary values in the first time.
 	 * remain_desc record remain desc length.
@@ -311,6 +315,7 @@ static int atc_get_bytes_left(struct dma_chan *chan)
 	}
 
 out:
+	spin_unlock_irqrestore(&atchan->lock, flags);
 	return ret;
 }
 
@@ -318,12 +323,14 @@ out:
  * atc_chain_complete - finish work for one transaction chain
  * @atchan: channel we work on
  * @desc: descriptor at the head of the chain we want do complete
- *
- * Called with atchan->lock held and bh disabled */
+ */
 static void
 atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 {
 	struct dma_async_tx_descriptor	*txd = &desc->txd;
+	unsigned long			flags;
+
+	spin_lock_irqsave(&atchan->lock, flags);
 
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
@@ -337,6 +344,8 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 	/* move myself to free_list */
 	list_move(&desc->desc_node, &atchan->free_list);
 
+	spin_unlock_irqrestore(&atchan->lock, flags);
+
 	dma_descriptor_unmap(txd);
 	/* for cyclic transfers,
 	 * no need to replay callback function while stopping */
@@ -344,10 +353,6 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 		dma_async_tx_callback	callback = txd->callback;
 		void			*param = txd->callback_param;
 
-		/*
-		 * The API requires that no submissions are done from a
-		 * callback, so we don't need to drop the lock here
-		 */
 		if (callback)
 			callback(param);
 	}
@@ -362,15 +367,17 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
  * Eventually submit queued descriptors if any
  *
  * Assume channel is idle while calling this function
- * Called with atchan->lock held and bh disabled
  */
 static void atc_complete_all(struct at_dma_chan *atchan)
 {
 	struct at_desc *desc, *_desc;
 	LIST_HEAD(list);
+	unsigned long flags;
 
 	dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
 
+	spin_lock_irqsave(&atchan->lock, flags);
+
 	/*
 	 * Submit queued descriptors ASAP, i.e. before we go through
 	 * the completed ones.
@@ -382,6 +389,8 @@ static void atc_complete_all(struct at_dma_chan *atchan)
 	/* empty queue list by moving descriptors (if any) to active_list */
 	list_splice_init(&atchan->queue, &atchan->active_list);
 
+	spin_unlock_irqrestore(&atchan->lock, flags);
+
 	list_for_each_entry_safe(desc, _desc, &list, desc_node)
 		atc_chain_complete(atchan, desc);
 }
@@ -389,23 +398,35 @@ static void atc_complete_all(struct at_dma_chan *atchan)
 /**
  * atc_advance_work - at the end of a transaction, move forward
  * @atchan: channel where the transaction ended
- *
- * Called with atchan->lock held and bh disabled
  */
 static void atc_advance_work(struct at_dma_chan *atchan)
 {
+	unsigned long	flags;
+
 	dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
 
-	if (atc_chan_is_enabled(atchan))
+	spin_lock_irqsave(&atchan->lock, flags);
+
+	if (atc_chan_is_enabled(atchan)) {
+		spin_unlock_irqrestore(&atchan->lock, flags);
 		return;
+	}
 
 	if (list_empty(&atchan->active_list) ||
 	    list_is_singular(&atchan->active_list)) {
+		spin_unlock_irqrestore(&atchan->lock, flags);
 		atc_complete_all(atchan);
 	} else {
-		atc_chain_complete(atchan, atc_first_active(atchan));
+		struct at_desc *desc_first = atc_first_active(atchan);
+
+		spin_unlock_irqrestore(&atchan->lock, flags);
+		atc_chain_complete(atchan, desc_first);
+		barrier();
 		/* advance work */
-		atc_dostart(atchan, atc_first_active(atchan));
+		spin_lock_irqsave(&atchan->lock, flags);
+		desc_first = atc_first_active(atchan);
+		atc_dostart(atchan, desc_first);
+		spin_unlock_irqrestore(&atchan->lock, flags);
 	}
 }
 
@@ -413,13 +434,14 @@ static void atc_advance_work(struct at_dma_chan *atchan)
 /**
  * atc_handle_error - handle errors reported by DMA controller
  * @atchan: channel where error occurs
- *
- * Called with atchan->lock held and bh disabled
  */
 static void atc_handle_error(struct at_dma_chan *atchan)
 {
 	struct at_desc *bad_desc;
 	struct at_desc *child;
+	unsigned long flags;
+
+	spin_lock_irqsave(&atchan->lock, flags);
 
 	/*
 	 * The descriptor currently at the head of the active list is
@@ -452,6 +474,8 @@ static void atc_handle_error(struct at_dma_chan *atchan)
 	list_for_each_entry(child, &bad_desc->tx_list, desc_node)
 		atc_dump_lli(atchan, &child->lli);
 
+	spin_unlock_irqrestore(&atchan->lock, flags);
+
 	/* Pretend the descriptor completed successfully */
 	atc_chain_complete(atchan, bad_desc);
 }
@@ -459,19 +483,27 @@ static void atc_handle_error(struct at_dma_chan *atchan)
 /**
  * atc_handle_cyclic - at the end of a period, run callback function
  * @atchan: channel used for cyclic operations
- *
- * Called with atchan->lock held and bh disabled
  */
 static void atc_handle_cyclic(struct at_dma_chan *atchan)
 {
-	struct at_desc			*first = atc_first_active(atchan);
-	struct dma_async_tx_descriptor	*txd = &first->txd;
-	dma_async_tx_callback		callback = txd->callback;
-	void				*param = txd->callback_param;
+	struct at_desc			*first;
+	struct dma_async_tx_descriptor	*txd;
+	dma_async_tx_callback		callback;
+	void				*param;
+	u32				dscr;
+	unsigned long			flags;
+
+	spin_lock_irqsave(&atchan->lock, flags);
+	first = atc_first_active(atchan);
+	dscr = channel_readl(atchan, DSCR);
+	spin_unlock_irqrestore(&atchan->lock, flags);
+
+	txd = &first->txd;
+	callback = txd->callback;
+	param = txd->callback_param;
 
 	dev_vdbg(chan2dev(&atchan->chan_common),
-			"new cyclic period llp 0x%08x\n",
-			channel_readl(atchan, DSCR));
+			"new cyclic period llp 0x%08x\n", dscr);
 
 	if (callback)
 		callback(param);
@@ -482,17 +514,13 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)
 static void atc_tasklet(unsigned long data)
 {
 	struct at_dma_chan *atchan = (struct at_dma_chan *)data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&atchan->lock, flags);
 	if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status))
 		atc_handle_error(atchan);
 	else if (atc_chan_is_cyclic(atchan))
 		atc_handle_cyclic(atchan);
 	else
 		atc_advance_work(atchan);
-
-	spin_unlock_irqrestore(&atchan->lock, flags);
 }
 
 static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
@@ -1013,6 +1041,11 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 		spin_unlock_irqrestore(&atchan->lock, flags);
 	} else if (cmd == DMA_TERMINATE_ALL) {
 		struct at_desc	*desc, *_desc;
+
+		/* Disable interrupts */
+		atc_disable_chan_irq(atdma, chan->chan_id);
+		tasklet_disable(&atchan->tasklet);
+
 		/*
 		 * This is only called when something went wrong elsewhere, so
 		 * we don't really care about the data. Just disable the
@@ -1033,14 +1066,22 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 		list_splice_init(&atchan->active_list, &list);
 
 		/* Flush all pending and queued descriptors */
-		list_for_each_entry_safe(desc, _desc, &list, desc_node)
+		list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+			spin_unlock_irqrestore(&atchan->lock, flags);
 			atc_chain_complete(atchan, desc);
+			spin_lock_irqsave(&atchan->lock, flags);
+		}
 
 		clear_bit(ATC_IS_PAUSED, &atchan->status);
 		/* if channel dedicated to cyclic operations, free it */
 		clear_bit(ATC_IS_CYCLIC, &atchan->status);
 
 		spin_unlock_irqrestore(&atchan->lock, flags);
+
+		/* Re-enable channel for future operations */
+		tasklet_enable(&atchan->tasklet);
+		atc_enable_chan_irq(atdma, chan->chan_id);
+
 	} else if (cmd == DMA_SLAVE_CONFIG) {
 		return set_runtime_config(chan, (struct dma_slave_config *)arg);
 	} else {
@@ -1065,8 +1106,6 @@ atc_tx_status(struct dma_chan *chan,
 		dma_cookie_t cookie,
 		struct dma_tx_state *txstate)
 {
-	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
-	unsigned long		flags;
 	enum dma_status		ret;
 	int bytes = 0;
 
@@ -1080,13 +1119,9 @@ atc_tx_status(struct dma_chan *chan,
 	if (!txstate)
 		return DMA_ERROR;
 
-	spin_lock_irqsave(&atchan->lock, flags);
-
 	/*  Get number of bytes left in the active transactions */
 	bytes = atc_get_bytes_left(chan);
 
-	spin_unlock_irqrestore(&atchan->lock, flags);
-
 	if (unlikely(bytes < 0)) {
 		dev_vdbg(chan2dev(chan), "get residual bytes error\n");
 		return DMA_ERROR;
@@ -1101,24 +1136,10 @@ atc_tx_status(struct dma_chan *chan,
 }
 
 /**
- * atc_issue_pending - try to finish work
+ * atc_issue_pending - void function
  * @chan: target DMA channel
  */
-static void atc_issue_pending(struct dma_chan *chan)
-{
-	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
-	unsigned long		flags;
-
-	dev_vdbg(chan2dev(chan), "issue_pending\n");
-
-	/* Not needed for cyclic transfers */
-	if (atc_chan_is_cyclic(atchan))
-		return;
-
-	spin_lock_irqsave(&atchan->lock, flags);
-	atc_advance_work(atchan);
-	spin_unlock_irqrestore(&atchan->lock, flags);
-}
+static void atc_issue_pending(struct dma_chan *chan) {}
 
 /**
  * atc_alloc_chan_resources - allocate resources for DMA channel
-- 
1.8.2.2

^ permalink raw reply related

* [PATCH 1/2] dmaengine: at_hdmac: remove the call to issue_pending from tx_status
From: Nicolas Ferre @ 2014-01-27 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1390832343.git.nicolas.ferre@atmel.com>

Triggering the dmaengine from tx_status call seems awkward.
If data are remaining in the DMA FIFO, the normal operations
should drain them anyway.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/dma/at_hdmac.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index e2c04dc81e2a..b28759b6d1ca 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -268,8 +268,6 @@ static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan,
 static int atc_get_bytes_left(struct dma_chan *chan)
 {
 	struct at_dma_chan      *atchan = to_at_dma_chan(chan);
-	struct at_dma           *atdma = to_at_dma(chan->device);
-	int	chan_id = atchan->chan_common.chan_id;
 	struct at_desc *desc_first = atc_first_active(atchan);
 	struct at_desc *desc_cur;
 	int ret = 0, count = 0;
@@ -311,11 +309,6 @@ static int atc_get_bytes_left(struct dma_chan *chan)
 				<< (desc_first->tx_width);
 		ret = atchan->remain_desc - count;
 	}
-	/*
-	 * Check fifo empty.
-	 */
-	if (!(dma_readl(atdma, CHSR) & AT_DMA_EMPT(chan_id)))
-		atc_issue_pending(chan);
 
 out:
 	return ret;
-- 
1.8.2.2

^ permalink raw reply related

* [RFC PATCH 0/2] dmaengine: at_hdmac: fix locking according to slave DMA requirements
From: Nicolas Ferre @ 2014-01-27 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <C9F8415089354E4FB76F4548B3515AF484286F61@edb1.wapice.localdomain>

Hi,

This is an attempt to solve the locking issue that we currently have with the
Atmel at_hdmac dmaengine driver.
I tested these patches with several drivers but may need more coverage before
making them permanent...

Comments welcome.

Nicolas Ferre (2):
  dmaengine: at_hdmac: remove the call to issue_pending from tx_status
  dmaengine: at_hdmac: run callback function with no lock held nor
    interrupts disabled

 drivers/dma/at_hdmac.c | 128 +++++++++++++++++++++++++++----------------------
 1 file changed, 71 insertions(+), 57 deletions(-)

-- 
1.8.2.2

^ permalink raw reply

* [PATCH V7 2/2] ARM: dts: Enable ahci sata and sata phy
From: Yuvaraj Kumar C D @ 2014-01-27 14:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390832366-23454-1-git-send-email-yuvaraj.cd@samsung.com>

This patch adds dt entry for ahci sata controller and its
corresponding phy controller.phy node has been added w.r.t
new generic phy framework.

Signed-off-by: Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
---
Changes since V6:none

Changes since V5:none

Changes since V4:
	1.Used the new phandle "sata_phy_i2c" in the DT entry. 
	2.Updated binding document.

Changes since V3:
	1.Moved the binding info to the /bindings/phy/

Changes since V2:
	1.Used syscon interface to PMU handling.
	2.Changed "sata-phy-i2c" to "exynos-sataphy-i2c".

Changes since V1:
	1.Minor changes to node name convention.
	2.Updated binding document.

 .../devicetree/bindings/ata/exynos-sata-phy.txt    |   14 --------
 .../devicetree/bindings/ata/exynos-sata.txt        |   25 +++++++++-----
 .../devicetree/bindings/phy/samsung-phy.txt        |   36 ++++++++++++++++++++
 arch/arm/boot/dts/exynos5250-arndale.dts           |   11 ++++++
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |    8 ++---
 arch/arm/boot/dts/exynos5250.dtsi                  |   17 ++++++---
 6 files changed, 78 insertions(+), 33 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/ata/exynos-sata-phy.txt

diff --git a/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt b/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt
deleted file mode 100644
index 37824fa..0000000
--- a/Documentation/devicetree/bindings/ata/exynos-sata-phy.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-* Samsung SATA PHY Controller
-
-SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
-Each SATA PHY controller should have its own node.
-
-Required properties:
-- compatible        : compatible list, contains "samsung,exynos5-sata-phy"
-- reg               : <registers mapping>
-
-Example:
-        sata at ffe07000 {
-                compatible = "samsung,exynos5-sata-phy";
-                reg = <0xffe07000 0x1000>;
-        };
diff --git a/Documentation/devicetree/bindings/ata/exynos-sata.txt b/Documentation/devicetree/bindings/ata/exynos-sata.txt
index 0849f10..b2adb1f 100644
--- a/Documentation/devicetree/bindings/ata/exynos-sata.txt
+++ b/Documentation/devicetree/bindings/ata/exynos-sata.txt
@@ -4,14 +4,21 @@ SATA nodes are defined to describe on-chip Serial ATA controllers.
 Each SATA controller should have its own node.
 
 Required properties:
-- compatible        : compatible list, contains "samsung,exynos5-sata"
-- interrupts        : <interrupt mapping for SATA IRQ>
-- reg               : <registers mapping>
-- samsung,sata-freq : <frequency in MHz>
+- compatible		: compatible list, contains "samsung,exynos5-sata"
+- interrupts		: <interrupt mapping for SATA IRQ>
+- reg			: <registers mapping>
+- samsung,sata-freq	: <frequency in MHz>
+- phys			: as mentioned in phy-bindings.txt
+- phy-names		: as mentioned in phy-bindings.txt
 
 Example:
-        sata at ffe08000 {
-                compatible = "samsung,exynos5-sata";
-                reg = <0xffe08000 0x1000>;
-                interrupts = <115>;
-        };
+	sata at 122f0000 {
+		compatible = "snps,dwc-ahci";
+		samsung,sata-freq = <66>;
+		reg = <0x122f0000 0x1ff>;
+		interrupts = <0 115 0>;
+		clocks = <&clock 277>, <&clock 143>;
+		clock-names = "sata", "sclk_sata";
+		phys = <&sata_phy>;
+		phy-names = "sata-phy";
+	};
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index c0fccaa..a937f75 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -20,3 +20,39 @@ Required properties:
 - compatible : should be "samsung,exynos5250-dp-video-phy";
 - reg : offset and length of the Display Port PHY register set;
 - #phy-cells : from the generic PHY bindings, must be 0;
+
+Samsung SATA PHY Controller
+---------------------------
+
+SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
+Each SATA PHY controller should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "samsung,exynos5250-sata-phy"
+- reg : offset and length of the SATA PHY register set;
+- #phy-cells : from the generic phy bindings;
+
+Example:
+	sata_phy: sata-phy at 12170000 {
+		compatible = "samsung,exynos5250-sata-phy";
+		reg = <0x12170000 0x1ff>;
+		clocks = <&clock 287>;
+		clock-names = "sata_phyctrl";
+		#phy-cells = <0>;
+		samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+		samsung,syscon-phandle = <&pmu_syscon>;
+	};
+
+Device-Tree bindings for sataphy i2c client driver
+--------------------------------------------------
+
+Required properties:
+compatible: Should be "samsung,exynos-sataphy-i2c"
+- reg: I2C address of the sataphy i2c device.
+
+Example:
+
+	sata_phy_i2c:sata-phy at 38 {
+		compatible = "samsung,exynos-sataphy-i2c";
+		reg = <0x38>;
+	};
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index b42e658..d9c9eaf 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -370,6 +370,17 @@
 		};
 	};
 
+	i2c at 121D0000 {
+		samsung,i2c-sda-delay = <100>;
+		samsung,i2c-max-bus-freq = <40000>;
+		samsung,i2c-slave-addr = <0x38>;
+
+		sata_phy_i2c:sata-phy at 38 {
+			compatible = "samsung,exynos-sataphy-i2c";
+			reg = <0x38>;
+		};
+	};
+
 	mmc_0: mmc at 12200000 {
 		status = "okay";
 		num-slots = <1>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 3e69837..e52eed8 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -96,16 +96,12 @@
 		samsung,i2c-slave-addr = <0x38>;
 		status = "okay";
 
-		sata-phy {
-			compatible = "samsung,sata-phy";
+		sata_phy_i2c:sata-phy at 38 {
+			compatible = "samsung,exynos-sataphy-i2c";
 			reg = <0x38>;
 		};
 	};
 
-	sata at 122F0000 {
-		samsung,sata-freq = <66>;
-	};
-
 	i2c at 12C80000 {
 		samsung,i2c-sda-delay = <100>;
 		samsung,i2c-max-bus-freq = <66000>;
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index dbb4a47..550d59e 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -46,6 +46,7 @@
 		i2c6 = &i2c_6;
 		i2c7 = &i2c_7;
 		i2c8 = &i2c_8;
+		i2c9 = &i2c_9;
 		pinctrl0 = &pinctrl_0;
 		pinctrl1 = &pinctrl_1;
 		pinctrl2 = &pinctrl_2;
@@ -231,16 +232,24 @@
 	};
 
 	sata at 122F0000 {
-		compatible = "samsung,exynos5-sata-ahci";
+		compatible = "snps,dwc-ahci";
+		samsung,sata-freq = <66>;
 		reg = <0x122F0000 0x1ff>;
 		interrupts = <0 115 0>;
 		clocks = <&clock 277>, <&clock 143>;
 		clock-names = "sata", "sclk_sata";
+		phys = <&sata_phy>;
+		phy-names = "sata-phy";
 	};
 
-	sata-phy at 12170000 {
-		compatible = "samsung,exynos5-sata-phy";
+	sata_phy: sata-phy at 12170000 {
+		compatible = "samsung,exynos5250-sata-phy";
 		reg = <0x12170000 0x1ff>;
+		clocks = <&clock 287>;
+		clock-names = "sata_phyctrl";
+		#phy-cells = <0>;
+		samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+		samsung,syscon-phandle = <&pmu_syscon>;
 	};
 
 	i2c_0: i2c at 12C60000 {
@@ -358,7 +367,7 @@
 		status = "disabled";
 	};
 
-	i2c at 121D0000 {
+	i2c_9: i2c at 121D0000 {
                 compatible = "samsung,exynos5-sata-phy-i2c";
                 reg = <0x121D0000 0x100>;
                 #address-cells = <1>;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V7 1/2] PHY: Exynos: Add Exynos5250 SATA PHY driver
From: Yuvaraj Kumar C D @ 2014-01-27 14:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390832366-23454-1-git-send-email-yuvaraj.cd@samsung.com>

This patch adds the SATA PHY driver for Exynos5250.Exynos5250 SATA
PHY comprises of CMU and TRSV blocks which are of I2C register Map.
So this patch also adds a i2c client driver, which is used configure
the CMU and TRSV block of exynos5250 SATA PHY.

This patch incorporates the generic PHY framework to deal with SATA
PHY.

This patch depends on the below patches
	[1].drivers: phy: add generic PHY framework
		by Kishon Vijay Abraham I<kishon@ti.com>
	[2].ata: ahci_platform: Manage SATA PHY
		by Roger Quadros <rogerq@ti.com>

Signed-off-by: Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
Signed-off-by: Girish K S <ks.giri@samsung.com>
Signed-off-by: Vasanth Ananthan <vasanth.a@samsung.com>
---
Changes from V6:
	1.Removed phy-exynos5250-sata-i2c.c,as it is not required
	  after moving to of_find_i2c_device_by_node().
	2.Changed struct __iomem *pmureg tp struct regmap *pmureg.
	3.Changed the wait_for_reg_status() to return 0 or -EFAULT.

Changes from V5:
	1.Rebased on latest generic PHY framework for-next tree.
	2.Minor nits such as indentations.

Changes from V4:
	1.Made Exynos5250 SATA PHY driver by default selects
	CONFIG_I2C and CONFIG_I2C_S3C2410, as SATA PHY driver
	depends on I2C.
	2.struct i2c_driver sataphy_i2c_driver made static which
	was earlier global type.
	3.Renamed the files to phy-exynos5250-sata.c and 
	phy-exynos5250-sata-i2c.c and CONFIG_EXYNOS5250_SATA_PHY
	to CONFIG_PHY_EXYNOS5250_SATA. 

Changes from V3:
	1.Moved devm_phy_create before to devm_phy_provider_register.

Changes from V2:
	1.Removed of_match_table
	2.Moved to syscon interface for PMU handling.

Changes from V1:
	1.Adapted to latest version of Generic PHY framework
	2.Removed exynos_sata_i2c_remove function.
 
 drivers/phy/Kconfig               |   13 ++
 drivers/phy/Makefile              |    1 +
 drivers/phy/phy-exynos5250-sata.c |  244 +++++++++++++++++++++++++++++++++++++
 3 files changed, 258 insertions(+)
 create mode 100644 drivers/phy/phy-exynos5250-sata.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index d0611b8..df79150 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -57,4 +57,17 @@ config PHY_EXYNOS_DP_VIDEO
 	help
 	  Support for Display Port PHY found on Samsung EXYNOS SoCs.
 
+config PHY_EXYNOS5250_SATA
+	tristate "Exynos5250 Sata SerDes/PHY driver"
+	depends on SOC_EXYNOS5250
+	select GENERIC_PHY
+	select I2C
+	select I2C_S3C2410
+	select MFD_SYSCON
+	help
+	  Enable this to support SATA SerDes/Phy found on Samsung's
+	  Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s,
+	  SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
+	  port to accept one SATA device.
+
 endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 4e4adc9..5d93dc9 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
 obj-$(CONFIG_PHY_MVEBU_SATA)		+= phy-mvebu-sata.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
+obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
diff --git a/drivers/phy/phy-exynos5250-sata.c b/drivers/phy/phy-exynos5250-sata.c
new file mode 100644
index 0000000..b35168d
--- /dev/null
+++ b/drivers/phy/phy-exynos5250-sata.c
@@ -0,0 +1,244 @@
+/*
+ * Samsung SATA SerDes(PHY) driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Authors: Girish K S <ks.giri@samsung.com>
+ *         Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <linux/mfd/syscon.h>
+
+#define EXYNOS5_SATA_RESET		0x4
+#define RESET_CMN_RST_N			(1 << 1)
+#define LINK_RESET			0xf0000
+#define EXYNOS5_SATA_MODE0		0x10
+#define EXYNOS5_SATAPHY_PMU_ENABLE	(1 << 0)
+#define SATA_SPD_GEN3			(2 << 0)
+#define EXYNOS5_SATA_CTRL0		0x14
+#define CTRL0_P0_PHY_CALIBRATED_SEL	(1 << 9)
+#define CTRL0_P0_PHY_CALIBRATED		(1 << 8)
+#define EXYNOS5_SATA_PHSATA_CTRLM	0xe0
+#define PHCTRLM_REF_RATE		(1 << 1)
+#define PHCTRLM_HIGH_SPEED		(1 << 0)
+#define EXYNOS5_SATA_PHSATA_STATM	0xf0
+#define PHSTATM_PLL_LOCKED		(1 << 0)
+#define EXYNOS_SATA_PHY_EN		(1 << 0)
+#define SATAPHY_CONTROL_OFFSET		0x0724
+
+#define PHY_PLL_TIMEOUT (usecs_to_jiffies(1000))
+
+struct exynos_sata_phy {
+	struct phy *phy;
+	struct clk *phyclk;
+	void __iomem *regs;
+	struct regmap *pmureg;
+	struct i2c_client *client;
+};
+
+static int wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit,
+				u32 status)
+{
+	unsigned long timeout = jiffies + PHY_PLL_TIMEOUT;
+
+	while (time_before(jiffies, timeout)) {
+		if ((readl(base + reg) & checkbit) == status)
+			return 0;
+	}
+
+	return -EFAULT;
+}
+
+static int exynos_sata_phy_power_on(struct phy *phy)
+{
+	struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
+
+	return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
+			EXYNOS5_SATAPHY_PMU_ENABLE, EXYNOS_SATA_PHY_EN);
+
+}
+
+static int exynos_sata_phy_power_off(struct phy *phy)
+{
+	struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
+
+	return regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
+			EXYNOS5_SATAPHY_PMU_ENABLE, ~EXYNOS_SATA_PHY_EN);
+
+}
+
+static int exynos_sata_phy_init(struct phy *phy)
+{
+	u32 val = 0;
+	int ret = 0;
+	u8 buf[] = { 0x3a, 0x0b };
+	struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
+
+	ret = regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
+			EXYNOS5_SATAPHY_PMU_ENABLE, EXYNOS_SATA_PHY_EN);
+	if (ret != 0)
+		dev_err(&sata_phy->phy->dev, "phy init failed\n");
+
+	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
+	val |= 0xff;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
+	val |= LINK_RESET;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
+	val |= RESET_CMN_RST_N;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
+	val &= ~PHCTRLM_REF_RATE;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
+
+	/* High speed enable for Gen3 */
+	val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
+	val |= PHCTRLM_HIGH_SPEED;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_CTRL0);
+	val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_CTRL0);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_MODE0);
+	val |= SATA_SPD_GEN3;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_MODE0);
+
+	ret = i2c_master_send(sata_phy->client, buf, sizeof(buf));
+	if (ret < 0)
+		return ret;
+
+	/* release cmu reset */
+	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
+	val &= ~RESET_CMN_RST_N;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
+
+	val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
+	val |= RESET_CMN_RST_N;
+	writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
+
+	ret = wait_for_reg_status(sata_phy->regs,
+				EXYNOS5_SATA_PHSATA_STATM,
+				PHSTATM_PLL_LOCKED, 1);
+	if (ret < 0)
+		dev_err(&sata_phy->phy->dev,
+			"PHY PLL locking failed\n");
+	return ret;
+}
+
+static struct phy_ops exynos_sata_phy_ops = {
+	.init		= exynos_sata_phy_init,
+	.power_on	= exynos_sata_phy_power_on,
+	.power_off	= exynos_sata_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int exynos_sata_phy_probe(struct platform_device *pdev)
+{
+	struct exynos_sata_phy *sata_phy;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct phy_provider *phy_provider;
+	struct device_node *node;
+	int ret = 0;
+
+	sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
+	if (!sata_phy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	sata_phy->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(sata_phy->regs))
+		return PTR_ERR(sata_phy->regs);
+
+	sata_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
+					"samsung,syscon-phandle");
+	if (IS_ERR(sata_phy->pmureg)) {
+			dev_err(dev, "syscon regmap lookup failed.\n");
+			return PTR_ERR(sata_phy->pmureg);
+		}
+
+	node = of_parse_phandle(dev->of_node,
+			"samsung,exynos-sataphy-i2c-phandle", 0);
+	if (!node)
+		return -EINVAL;
+
+	sata_phy->client = of_find_i2c_device_by_node(node);
+	if (!sata_phy->client)
+		return -EPROBE_DEFER;
+
+	dev_set_drvdata(dev, sata_phy);
+
+	sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl");
+	if (IS_ERR(sata_phy->phyclk)) {
+		dev_err(dev, "failed to get clk for PHY\n");
+		return PTR_ERR(sata_phy->phyclk);
+	}
+
+	ret = clk_prepare_enable(sata_phy->phyclk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable source clk\n");
+		return ret;
+	}
+
+	sata_phy->phy = devm_phy_create(dev, &exynos_sata_phy_ops, NULL);
+	if (IS_ERR(sata_phy->phy)) {
+		clk_disable_unprepare(sata_phy->phyclk);
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(sata_phy->phy);
+	}
+
+	phy_set_drvdata(sata_phy->phy, sata_phy);
+
+	phy_provider = devm_of_phy_provider_register(dev,
+					of_phy_simple_xlate);
+	if (IS_ERR(phy_provider)) {
+		clk_disable_unprepare(sata_phy->phyclk);
+		return PTR_ERR(phy_provider);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id exynos_sata_phy_of_match[] = {
+	{ .compatible = "samsung,exynos5250-sata-phy" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, exynos_sata_phy_of_match);
+
+static struct platform_driver exynos_sata_phy_driver = {
+	.probe	= exynos_sata_phy_probe,
+	.driver = {
+		.of_match_table	= exynos_sata_phy_of_match,
+		.name  = "samsung,sata-phy",
+		.owner = THIS_MODULE,
+	}
+};
+module_platform_driver(exynos_sata_phy_driver);
+
+MODULE_DESCRIPTION("Samsung SerDes PHY driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Girish K S <ks.giri@samsung.com>");
+MODULE_AUTHOR("Yuvaraj C D <yuvaraj.cd@samsung.com>");
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH V7 0/2] Exynos5250 SATA Support
From: Yuvaraj Kumar C D @ 2014-01-27 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series enable the SATA support on Exynos5250 based boards.
It incorporates the generic phy framework to deal with sata phy.

This patch depends on the below patches
	[1]. drivers: phy: add generic PHY framework
		by Kishon Vijay Abraham I<kishon@ti.com>
	[2]. ata: ahci_platform: Manage SATA PHY
		by Roger Quadros <rogerq@ti.com>
	[3].ARM: dts: Add pmu sysreg node to exynos5250 and
		exynos5420 dtsi files
		by Leela Krishna Amudala <l.krishna@samsung.com>
	[4]. i2c: s3c2410 : Add polling mode support
		by Vasanth Ananthan <vasanth.a@samsung.com>

Changes from V6:
	1.Removed phy-exynos5250-sata-i2c.c,as it is not required
	  after moving to of_find_i2c_device_by_node().
	2.Changed struct __iomem pmureg tp struct regmap pmureg.
	3.Changed the wait_for_reg_status() to return 0 or -EFAULT.

Changes from V5:
	1.Rebased on latest generic PHY framework for-next tree.
	2.Minor nits such as indentations.

Changes from V4:
	1.Made Exynos5250 SATA PHY driver by default selects
	CONFIG_I2C and CONFIG_I2C_S3C2410, as SATA PHY driver
	depends on I2C.
	2.Used the new phandle "sata_phy_i2c" in the DT entry. 
	3.struct i2c_driver sataphy_i2c_driver made static which
	was earlier global type. 

Changes from V3:
	1.Moved the devicetree binding documentation
	from /bindings/ata/ to bindings/phy/ .
	2.Moved devm_phy_create call before to 
	the devm_phy_provider_register. 

Changes from V2:
	1.Removed of_match_table
	2.Moved to syscon interface for PMU handling.

Changes from V1:
	1. Dropped the patch 
	ahci: exynos: add ahci sata support on Exynos platform

	2.Adapt to latest generic PHY framework available in 
	git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git next
Yuvaraj Kumar C D (2):
  PHY: Exynos: Add Exynos5250 SATA PHY driver
  ARM: dts: Enable ahci sata and sata phy

 .../devicetree/bindings/ata/exynos-sata-phy.txt    |   14 --
 .../devicetree/bindings/ata/exynos-sata.txt        |   25 +-
 .../devicetree/bindings/phy/samsung-phy.txt        |   36 +++
 arch/arm/boot/dts/exynos5250-arndale.dts           |   11 +
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |    8 +-
 arch/arm/boot/dts/exynos5250.dtsi                  |   17 +-
 drivers/phy/Kconfig                                |   13 ++
 drivers/phy/Makefile                               |    1 +
 drivers/phy/phy-exynos5250-sata.c                  |  244 ++++++++++++++++++++
 9 files changed, 336 insertions(+), 33 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/ata/exynos-sata-phy.txt
 create mode 100644 drivers/phy/phy-exynos5250-sata.c

-- 
1.7.9.5

^ permalink raw reply

* at_hdmac does not release lock before the callback - deadlock
From: Jouko Haapaluoma @ 2014-01-27 14:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <C9F8415089354E4FB76F4548B3515AF484286F61@edb1.wapice.localdomain>

After further investigation it seems that the deadlocks  would happen only when CONFIG_SMP is enabled or RT_PREEMPT patch is used. When CONFIG_SMP or RT_PREEMPT is not used, the spinlocks will only disable preemption which does not cause a deadlock. However, with the CONFIG_SMP or the RT_PREEMPT patch spinlocks are actual locks and deadlocks can occur.

This might explain why this problem hasn't been noticed before. At least the Atmel serial driver from linux4sam git causes deadlocks with the RT_PREEMPT because of this issue. 

BR,
Jouko Haapaluoma

^ permalink raw reply

* [PATCH 0/9] ARM: dts: imx: remove the use of pingrp macros
From: Rob Herring @ 2014-01-27 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390668191-20289-1-git-send-email-shawn.guo@linaro.org>

On Sat, Jan 25, 2014 at 10:43 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> Hi Rob,
>
> In order to solve a pinctrl data efficiency problem, we introduced
> pingrp macros [1] in this development cycle as the base of board dts
> support.  The whole imx-dt-3.14 pull request has been held by Olof for
> a few weeks because he wants to get a general approval from DT folks
> on this change.  But unfortunately it appears that you are not fond of
> this change.
>
> I just spent the day to create a patch series against imx-dt-3.14 to
> remove these pingrp macros.  May I get your nod on this quick
> turn-around, so that we do not miss the merge window?

I've only skimmed thru some of the patches, but in general it looks fine to me:

Acked-by: Rob Herring <robh@kernel.org>

Rob

> Hi Olof,
>
> I guess we do not have to shut the door for imx-dt-3.14 if you and DT
> folks are happy with this patch series, which is a quite straight
> forward search&replace change?
>
> Shawn
>
> [1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/275912/
>
> Shawn Guo (9):
>   ARM: dts: imx6qdl: remove the use of pingrp macros
>   ARM: dts: imx6sl: remove the use of pingrp macros
>   ARM: dts: imx53: remove the use of pingrp macros
>   ARM: dts: imx51: remove the use of pingrp macros
>   ARM: dts: imx50: remove the use of pingrp macros
>   ARM: dts: imx35: remove the use of pingrp macros
>   ARM: dts: imx25: remove the use of pingrp macros
>   ARM: dts: imx27: remove the use of pingrp macros
>   ARM: dts: vf610: remove the use of pingrp macros
>
>  arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi       |   17 +-
>  .../boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts  |   56 ++-
>  arch/arm/boot/dts/imx25-pingrp.h                   |   81 ---
>  arch/arm/boot/dts/imx25.dtsi                       |    2 +-
>  arch/arm/boot/dts/imx27-apf27.dts                  |   26 +-
>  arch/arm/boot/dts/imx27-apf27dev.dts               |   65 ++-
>  arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts   |   27 +-
>  arch/arm/boot/dts/imx27-phytec-phycard-s-som.dts   |   26 +-
>  arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts     |   23 +-
>  arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi    |   38 +-
>  arch/arm/boot/dts/imx27-pingrp.h                   |  151 ------
>  arch/arm/boot/dts/imx27.dtsi                       |    2 +-
>  arch/arm/boot/dts/imx35-pingrp.h                   |  104 ----
>  arch/arm/boot/dts/imx35.dtsi                       |    1 -
>  arch/arm/boot/dts/imx50-evk.dts                    |   28 +-
>  arch/arm/boot/dts/imx50-pingrp.h                   |  146 ------
>  arch/arm/boot/dts/imx50.dtsi                       |    2 +-
>  arch/arm/boot/dts/imx51-apf51.dts                  |   26 +-
>  arch/arm/boot/dts/imx51-apf51dev.dts               |   64 ++-
>  arch/arm/boot/dts/imx51-babbage.dts                |  142 +++++-
>  arch/arm/boot/dts/imx51-eukrea-cpuimx51.dtsi       |   26 +-
>  .../boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts  |   31 +-
>  arch/arm/boot/dts/imx51-pingrp.h                   |  249 ---------
>  arch/arm/boot/dts/imx51.dtsi                       |    2 +-
>  arch/arm/boot/dts/imx53-ard.dts                    |   18 +-
>  arch/arm/boot/dts/imx53-evk.dts                    |   51 +-
>  arch/arm/boot/dts/imx53-m53evk.dts                 |  128 ++++-
>  arch/arm/boot/dts/imx53-pingrp.h                   |  352 -------------
>  arch/arm/boot/dts/imx53-qsb.dts                    |   88 +++-
>  arch/arm/boot/dts/imx53-smd.dts                    |   77 ++-
>  arch/arm/boot/dts/imx53-tqma53.dtsi                |   89 +++-
>  arch/arm/boot/dts/imx53-voipac-bsb.dts             |   21 +-
>  arch/arm/boot/dts/imx53-voipac-dmm-668.dtsi        |   47 +-
>  arch/arm/boot/dts/imx53.dtsi                       |    2 +-
>  arch/arm/boot/dts/imx6dl-hummingboard.dts          |    5 +-
>  arch/arm/boot/dts/imx6dl.dtsi                      |    1 -
>  arch/arm/boot/dts/imx6q-arm2.dts                   |   81 ++-
>  arch/arm/boot/dts/imx6q-cm-fx6.dts                 |   44 +-
>  arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts            |   47 +-
>  arch/arm/boot/dts/imx6q-gw5400-a.dts               |   75 ++-
>  arch/arm/boot/dts/imx6q-phytec-pfla02.dtsi         |   53 +-
>  arch/arm/boot/dts/imx6q-sbc6x.dts                  |   37 +-
>  arch/arm/boot/dts/imx6q-udoo.dts                   |   33 +-
>  arch/arm/boot/dts/imx6q.dtsi                       |    1 -
>  arch/arm/boot/dts/imx6qdl-gw51xx.dtsi              |   77 ++-
>  arch/arm/boot/dts/imx6qdl-gw52xx.dtsi              |   88 +++-
>  arch/arm/boot/dts/imx6qdl-gw53xx.dtsi              |   93 +++-
>  arch/arm/boot/dts/imx6qdl-gw54xx.dtsi              |   93 +++-
>  arch/arm/boot/dts/imx6qdl-microsom.dtsi            |    5 +-
>  arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi          |   56 ++-
>  arch/arm/boot/dts/imx6qdl-pingrp.h                 |  532 --------------------
>  arch/arm/boot/dts/imx6qdl-sabreauto.dtsi           |  139 ++++-
>  arch/arm/boot/dts/imx6qdl-sabrelite.dtsi           |   56 ++-
>  arch/arm/boot/dts/imx6qdl-sabresd.dtsi             |   86 +++-
>  arch/arm/boot/dts/imx6qdl-wandboard.dtsi           |   78 ++-
>  arch/arm/boot/dts/imx6sl-evk.dts                   |  120 ++++-
>  arch/arm/boot/dts/imx6sl-pingrp.h                  |  148 ------
>  arch/arm/boot/dts/imx6sl.dtsi                      |    1 -
>  arch/arm/boot/dts/vf610-cosmic.dts                 |   17 +-
>  arch/arm/boot/dts/vf610-pingrp.h                   |  127 -----
>  arch/arm/boot/dts/vf610-twr.dts                    |   42 +-
>  arch/arm/boot/dts/vf610.dtsi                       |    2 +-
>  62 files changed, 2163 insertions(+), 2182 deletions(-)
>  delete mode 100644 arch/arm/boot/dts/imx25-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx27-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx35-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx50-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx51-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx53-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx6qdl-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/imx6sl-pingrp.h
>  delete mode 100644 arch/arm/boot/dts/vf610-pingrp.h
>
> --
> 1.7.9.5
>
>

^ permalink raw reply

* [PATCH V6 1/2] PHY: Exynos: Add Exynos5250 SATA PHY driver
From: Yuvaraj Kumar @ 2014-01-27 13:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52D00C33.4060305@samsung.com>

On Fri, Jan 10, 2014 at 8:35 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> Hi Yuvaraj,
>
> In general this version looks pretty good, but I have some questions inline.
>
> On 10.01.2014 08:00, Yuvaraj Kumar C D wrote:
> [snip]
>
>> diff --git a/drivers/phy/phy-exynos5250-sata-i2c.c
>> b/drivers/phy/phy-exynos5250-sata-i2c.c
>> new file mode 100644
>> index 0000000..206e337
>> --- /dev/null
>> +++ b/drivers/phy/phy-exynos5250-sata-i2c.c
>> @@ -0,0 +1,40 @@
>> +/*
>> + * Copyright (C) 2013 Samsung Electronics Co.Ltd
>> + * Author:
>> + *     Yuvaraj C D <yuvaraj.cd@samsung.com>
>> + *
>> + * This program is free software; you can redistribute  it and/or modify
>> it
>> + * under  the terms of  the GNU General  Public License as published by
>> the
>> + * Free Software Foundation;  either version 2 of the  License, or (at
>> your
>> + * option) any later version.
>> + *
>> + */
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +
>> +static int exynos_sata_i2c_probe(struct i2c_client *client,
>> +               const struct i2c_device_id *i2c_id)
>> +{
>> +       return 0;
>> +}
>> +
>> +static const struct i2c_device_id sataphy_i2c_device_match[] = {
>> +       { "exynos-sataphy-i2c", 0 },
>> +};
>> +
>> +static struct i2c_driver sataphy_i2c_driver = {
>> +       .probe          = exynos_sata_i2c_probe,
>> +       .id_table       = sataphy_i2c_device_match,
>> +       .driver   = {
>> +               .name = "exynos-sataphy-i2c",
>> +               .owner = THIS_MODULE,
>> +       },
>> +};
>> +
>> +static int __init exynos5250_phy_i2c_init(void)
>> +{
>> +       return i2c_add_driver(&sataphy_i2c_driver);
>> +}
>> +module_init(exynos5250_phy_i2c_init);
>
>
> Hmm, is this driver even necessary now?
>
> Wolfram, would it be possible to use an i2c_client without a driver bound to
> it?
>
>
>> diff --git a/drivers/phy/phy-exynos5250-sata.c
>> b/drivers/phy/phy-exynos5250-sata.c
>> new file mode 100644
>> index 0000000..6e5ff8d
>> --- /dev/null
>> +++ b/drivers/phy/phy-exynos5250-sata.c
>> @@ -0,0 +1,238 @@
>> +/*
>> + * Samsung SATA SerDes(PHY) driver
>> + *
>> + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
>> + * Authors: Girish K S <ks.giri@samsung.com>
>> + *         Yuvaraj Kumar C D <yuvaraj.cd@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/i2c.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/mfd/syscon.h>
>> +
>> +#define EXYNOS5_SATA_RESET             0x4
>> +#define RESET_CMN_RST_N                        (1 << 1)
>> +#define LINK_RESET                     0xF0000
>
>
> nit: Lowercase is preferred in hexadecimal notation.
> + all other occurrences in this file.
>
>
>> +#define EXYNOS5_SATA_MODE0             0x10
>> +#define EXYNOS5_SATAPHY_PMU_ENABLE     (1 << 0)
>> +#define SATA_SPD_GEN3                  (2 << 0)
>> +#define EXYNOS5_SATA_CTRL0             0x14
>> +#define CTRL0_P0_PHY_CALIBRATED_SEL    (1 << 9)
>> +#define CTRL0_P0_PHY_CALIBRATED                (1 << 8)
>> +#define EXYNOS5_SATA_PHSATA_CTRLM      0xE0
>> +#define PHCTRLM_REF_RATE               (1 << 1)
>> +#define PHCTRLM_HIGH_SPEED             (1 << 0)
>> +#define EXYNOS5_SATA_PHSATA_STATM      0xF0
>> +#define PHSTATM_PLL_LOCKED             (1 << 0)
>> +#define EXYNOS_SATA_PHY_EN             (1 << 0)
>> +#define SATAPHY_CONTROL_OFFSET         0x0724
>> +
>> +struct exynos_sata_phy {
>> +       struct phy *phy;
>> +       struct clk *phyclk;
>> +       void __iomem *regs;
>> +       void __iomem *pmureg;
>> +       struct i2c_client *client;
>> +};
>> +
>> +static bool wait_for_reg_status(void __iomem *base, u32 reg, u32
>> checkbit,
>> +                               u32 status)
>> +{
>> +       unsigned long timeout = jiffies + usecs_to_jiffies(1000);
>
>
> nit: It would be better to define the timeout using a macro to not use magic
> numbers.
>
>
>> +
>> +       while (time_before(jiffies, timeout)) {
>> +               if ((readl(base + reg) & checkbit) == status)
>> +                       return true;
>> +       }
>> +
>> +       return false;
>> +}
>> +
>> +static int exynos_sata_phy_power_on(struct phy *phy)
>> +{
>> +       struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
>> +
>> +       regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
>> +                       EXYNOS5_SATAPHY_PMU_ENABLE, EXYNOS_SATA_PHY_EN);
>
>
> regmap_update_bits can return an error. Wouldn't it be better to return it
> as return value of this function instead of returning 0 all the time? As a
> side effect, this would make the function smaller by two lines.
>
>
>> +
>> +       return 0;
>> +}
>> +
>> +static int exynos_sata_phy_power_off(struct phy *phy)
>> +{
>> +       struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
>> +
>> +       regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
>> +                       EXYNOS5_SATAPHY_PMU_ENABLE, ~EXYNOS_SATA_PHY_EN);
>
>
> Same here.
>
>
>> +
>> +       return 0;
>> +}
>> +
>> +static int exynos_sata_phy_init(struct phy *phy)
>> +{
>> +       u32 val = 0;
>> +       int ret = 0;
>> +       u8 buf[] = { 0x3A, 0x0B };
>> +       struct exynos_sata_phy *sata_phy = phy_get_drvdata(phy);
>> +
>> +       regmap_update_bits(sata_phy->pmureg, SATAPHY_CONTROL_OFFSET,
>> +                       EXYNOS5_SATAPHY_PMU_ENABLE, EXYNOS_SATA_PHY_EN);
>
>
> regmap_update_bits returns an error code.
>
>
>> +
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
>> +       val |= 0xFF;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
>> +       val |= LINK_RESET;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
>> +       val |= RESET_CMN_RST_N;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
>> +       val &= ~PHCTRLM_REF_RATE;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
>> +
>> +       /* High speed enable for Gen3 */
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
>> +       val |= PHCTRLM_HIGH_SPEED;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_PHSATA_CTRLM);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_CTRL0);
>> +       val |= CTRL0_P0_PHY_CALIBRATED_SEL | CTRL0_P0_PHY_CALIBRATED;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_CTRL0);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_MODE0);
>> +       val |= SATA_SPD_GEN3;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_MODE0);
>> +
>> +       ret = i2c_master_send(sata_phy->client, buf, sizeof(buf));
>> +       if (ret < 0)
>> +               return -ENXIO;
>
>
> Wouldn't it be better to return the same error code as i2c_master_send
> returned?
>
>
>> +
>> +       /* release cmu reset */
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
>> +       val &= ~RESET_CMN_RST_N;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
>> +
>> +       val = readl(sata_phy->regs + EXYNOS5_SATA_RESET);
>> +       val |= RESET_CMN_RST_N;
>> +       writel(val, sata_phy->regs + EXYNOS5_SATA_RESET);
>> +
>> +       return (wait_for_reg_status(sata_phy->regs,
>> EXYNOS5_SATA_PHSATA_STATM,
>> +               PHSTATM_PLL_LOCKED, 1)) ? 0 : -EINVAL;
>> +
>
>
> nit: Stray blank line.
>
> Also it might be more readable after making wait_for_reg_status() return an
> integer error code (0 and e.g. -EFAULT) and rewriting the last line to:
>
>         ret = wait_for_reg_status(sata_phy->regs,
>                                         EXYNOS5_SATA_PHSATA_STATM,
>                                         PHSTATM_PLL_LOCKED, 1);
>         if (ret < 0)
>                 dev_err(&sata_phy->client->dev,
>                         "PHY PLL locking failed\n");
>
>         return ret;
>
> By the way, isn't this initialization really needed whenever the PHY is
> powered on?
>
>
>> +}
>> +
>> +static struct phy_ops exynos_sata_phy_ops = {
>> +       .init           = exynos_sata_phy_init,
>> +       .power_on       = exynos_sata_phy_power_on,
>> +       .power_off      = exynos_sata_phy_power_off,
>> +       .owner          = THIS_MODULE,
>> +};
>> +
>> +static int exynos_sata_phy_probe(struct platform_device *pdev)
>> +{
>> +       struct exynos_sata_phy *sata_phy;
>> +       struct device *dev = &pdev->dev;
>> +       struct resource *res;
>> +       struct phy_provider *phy_provider;
>> +       struct device_node *node;
>> +       int ret = 0;
>> +
>> +       sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL);
>> +       if (!sata_phy)
>> +               return -ENOMEM;
>> +
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +
>> +       sata_phy->regs = devm_ioremap_resource(dev, res);
>> +       if (IS_ERR(sata_phy->regs))
>> +               return PTR_ERR(sata_phy->regs);
>> +
>> +       sata_phy->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
>> +                                       "samsung,syscon-phandle");
>
>
> pmureg is defined as (void __iomem *) in struct exynos_sata_phy, but
> syscon_regmap_lookup_by_phandle() returns (struct regmap *). Moreover it
> does not return NULL on error, but rather ERR_PTR(). Please correct this.
>
>
>> +       if (!sata_phy->pmureg) {
>> +               dev_err(dev, "syscon regmap lookup failed.\n");
>> +               return PTR_ERR(sata_phy->pmureg);
>> +       }
>> +
>> +       node = of_parse_phandle(dev->of_node,
>> +                       "samsung,exynos-sataphy-i2c-phandle", 0);
>> +       if (!node)
>> +               return -ENODEV;
>
>
> An error here means that a required DT property was not specified or was
> specified incorrectly. IMHO -EINVAL would be better here.
>
>
>> +
>> +       sata_phy->client = of_find_i2c_device_by_node(node);
>> +       if (!sata_phy->client)
>> +               return -EPROBE_DEFER;
>> +
>> +       dev_set_drvdata(dev, sata_phy);
>> +
>> +       sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl");
>> +       if (IS_ERR(sata_phy->phyclk)) {
>> +               dev_err(dev, "failed to get clk for PHY\n");
>> +               return PTR_ERR(sata_phy->phyclk);
>> +       }
>> +
>> +       ret = clk_prepare_enable(sata_phy->phyclk);
>> +       if (ret < 0) {
>> +               dev_err(dev, "failed to enable source clk\n");
>> +               return ret;
>> +       }
>> +
>> +       sata_phy->phy = devm_phy_create(dev, &exynos_sata_phy_ops, NULL);
>> +       if (IS_ERR(sata_phy->phy)) {
>> +               clk_disable_unprepare(sata_phy->phyclk);
>> +               dev_err(dev, "failed to create PHY\n");
>> +               return PTR_ERR(sata_phy->phy);
>> +       }
>> +
>> +       phy_set_drvdata(sata_phy->phy, sata_phy);
>> +
>> +       phy_provider = devm_of_phy_provider_register(dev,
>> +                                       of_phy_simple_xlate);
>> +       if (IS_ERR(phy_provider)) {
>> +               clk_disable_unprepare(sata_phy->phyclk);
>> +               return PTR_ERR(phy_provider);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct of_device_id exynos_sata_phy_of_match[] = {
>> +       { .compatible = "samsung,exynos5250-sata-phy" },
>> +       { },
>> +};
>> +MODULE_DEVICE_TABLE(of, exynos_sata_phy_of_match);
>> +
>> +static struct platform_driver exynos_sata_phy_driver = {
>> +       .probe  = exynos_sata_phy_probe,
>
>
> If this driver can be compiled as module, don't you also need remove?
I tried this and found as such there is no resources hold by this
driver to handle in remove case.
This driver is used by ahci_platform driver and when load
phy-exynos5250-sata,driver usage count is 1.
so if we unload ahci_platform driver first and then
phy-exynos5250-sata.ko it cleanely unload this module.
>
> Best regards,
> Tomasz

^ permalink raw reply

* [RFC/PATCH] ARM: dove: Remove UBI support from defconfig
From: Ezequiel Garcia @ 2014-01-27 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

As NAND support is not enabled by default, it's hard to see
why we'd want to have UBI support. Let's remove it.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
---
 arch/arm/configs/dove_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig
index 1101054..7242b11 100644
--- a/arch/arm/configs/dove_defconfig
+++ b/arch/arm/configs/dove_defconfig
@@ -48,7 +48,6 @@ CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_M25P80=y
-CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=1
-- 
1.8.1.5

^ permalink raw reply related

* [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
From: Srikanth Thokala @ 2014-01-27 13:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E54849.2000208@metafoo.de>

Hi Lars/Vinod,

On Sun, Jan 26, 2014 at 11:09 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
> On 01/26/2014 02:59 PM, Vinod Koul wrote:
>> On Fri, Jan 24, 2014 at 02:24:27PM +0100, Lars-Peter Clausen wrote:
>>> On 01/24/2014 12:16 PM, Srikanth Thokala wrote:
>>>> Hi Lars,
>>>>
>>>> On Thu, Jan 23, 2014 at 4:55 PM, Lars-Peter Clausen <lars@metafoo.de> wrote:
>>>>> On 01/22/2014 05:52 PM, Srikanth Thokala wrote:
>>>>> [...]
>>>>>> +/**
>>>>>> + * xilinx_vdma_device_control - Configure DMA channel of the device
>>>>>> + * @dchan: DMA Channel pointer
>>>>>> + * @cmd: DMA control command
>>>>>> + * @arg: Channel configuration
>>>>>> + *
>>>>>> + * Return: '0' on success and failure value on error
>>>>>> + */
>>>>>> +static int xilinx_vdma_device_control(struct dma_chan *dchan,
>>>>>> +                                   enum dma_ctrl_cmd cmd, unsigned long arg)
>>>>>> +{
>>>>>> +     struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
>>>>>> +
>>>>>> +     switch (cmd) {
>>>>>> +     case DMA_TERMINATE_ALL:
>>>>>> +             xilinx_vdma_terminate_all(chan);
>>>>>> +             return 0;
>>>>>> +     case DMA_SLAVE_CONFIG:
>>>>>> +             return xilinx_vdma_slave_config(chan,
>>>>>> +                                     (struct xilinx_vdma_config *)arg);
>>>>>
>>>>> You really shouldn't be overloading the generic API with your own semantics.
>>>>> DMA_SLAVE_CONFIG should take a dma_slave_config and nothing else.
>>>>
>>>> Ok.  The driver needs few additional configuration from the slave
>>>> device like Vertical
>>>> Size, Horizontal Size,  Stride etc., for the DMA transfers, in that case do you
>>>> suggest me to define a separate dma_ctrl_cmd like the one FSLDMA_EXTERNAL_START
>>>> defined for Freescale drivers?
>>>
>>> In my opinion it is not a good idea to have driver implement a generic API,
>>> but at the same time let the driver have custom semantics for those API
>>> calls. It's a bit like having a gpio driver that expects 23 and 42 as the
>>> values passed to gpio_set_value instead of 0 and 1. It completely defeats
>>> the purpose of a generic API, namely that you are able to write generic code
>>> that makes use of the API without having to know about which implementation
>>> API it is talking to. The dmaengine framework provides the
>>> dmaengine_prep_interleaved_dma() function to setup two dimensional
>>> transfers, e.g. take a look at sirf-dma.c or imx-dma.c.
>>
>> The question here i think would be waht this device supports? Is the hardware
>> capable of doing interleaved transfers, then would make sense.
>
> The hardware does 2D transfers. The parameters for a transfer are height,
> width and stride. That's only a subset of what interleaved transfers can be
> (xt->num_frames must be one for 2d transfers). But if I remember correctly
> there has been some discussion on this in the past and the result of that
> discussion was that using interleaved transfers for 2D transfers is
> preferred over adding a custom API for 2D transfers.

I went through the prep_interleaved_dma API and I see only one descriptor
is prepared per API call (i.e. per frame).  As our IP supports upto 16 frame
buffers (can be more in future), isn't it less efficient compared to the
prep_slave_sg where we get a single sg list and can prepare all the descriptors
(of non-contiguous buffers) in one go?  Correct me, if am wrong and let me
know your opinions.

Srikanth

>
> - Lars
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* [PATCH RFC v2 1/2] Documentation: arm: add cache DT bindings
From: Russell King - ARM Linux @ 2014-01-27 12:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140121114845.GA2598@e103592.cambridge.arm.com>

On Tue, Jan 21, 2014 at 11:49:01AM +0000, Dave Martin wrote:
> I do have a worry that because the kernel won't normally use this
> information, by default it will get pasted between .dts files, won't get
> tested and will be wrong rather often.  It also violates the DT principle
> that probeable information should not be present in the DT -- ePAPR
> obviously envisages systems where cache geometry information is not
> probeable, but that's not the case for architected caches on ARM, except
> in rare cases where the CLIDR is wrong.

That statement is wrong.  There are caches on ARM CPUs where there is no
CLIDR register.  I suggest reading the earlier DDI0100 revisions.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* at_hdmac does not release lock before the callback - deadlock
From: Jouko Haapaluoma @ 2014-01-27 12:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hello

It seems that the at_hdmac driver keeps the atchan->lock even when the device driver callback is called.
This will cause a deadlock in those cases when the device driver calls certain DMA Engine methods
from the callback function.

The DMA Engine documentation (https://www.kernel.org/doc/Documentation/dmaengine.txt) states:
" 
Although the async_tx API specifies that completion callback
routines cannot submit any new operations, this is not the
case for slave/cyclic DMA.

For slave DMA, the subsequent transaction may not be available
for submission prior to callback function being invoked, so
slave DMA callbacks are permitted to prepare and submit a new
transaction.

For cyclic DMA, a callback function may wish to terminate the
DMA via dmaengine_terminate_all().

Therefore, it is important that DMA engine drivers drop any
locks before calling the callback function which may cause a
deadlock.
"

According to the documentation it seems that the at_hdmac driver violates the DMA Engine API because
locking is not released before entering the callback function.

One possible deadlock situation:

atc_tasklet()
spin_lock_irqsave(&atchan->lock)
atc_handle_cyclic()
callback()
dmaengine_terminate_all()
atc_control()
spin_lock_irqsave(&atchan->lock) 


BR,
Jouko Haapaluoma

^ permalink raw reply

* [PATCH RFC v2 2/2] Documentation: arm: define DT C-states bindings
From: Antti P Miettinen @ 2014-01-27 12:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140127114125.GD16639@e102568-lin.cambridge.arm.com>

From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> That's why I defined the worst case. How did you implemented it in your
> idle drivers ? That would help generalize it, after all these bindings
> are there to simplify drivers upstreaming, feedback welcome.

Currently we do not handle this well downstream either. The problem
with worst case is that the absolute worst case can be really bad and
probability of it might be very low. Sorry - no ready answer :-)

	--Antti

^ permalink raw reply

* [PATCH 0/9] setting the table for integration of cpuidle with the scheduler
From: Peter Zijlstra @ 2014-01-27 12:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-1-git-send-email-nicolas.pitre@linaro.org>

On Mon, Jan 27, 2014 at 01:08:15AM -0500, Nicolas Pitre wrote:
> As everyone should know by now, we want to integrate the cpuidle
> governor with the scheduler for a more efficient idling of CPUs.
> In order to help the transition, this small patch series moves the
> existing interaction with cpuidle from architecture code to generic
> core code.  No functional change should have occurred yet.
> 
> The ARM, PPC, SH and X86 architectures are concerned.  Small cleanups
> to ARM and ARM64 are also included. I don't know yet the best path for
> those patches to get into mainline, but it is probably best if they
> stay together. So ACKs from architecture maintainers would be greatly
> appreciated.
> 
> 
>  arch/arm/kernel/process.c                       | 21 +++---------
>  arch/arm/kernel/setup.c                         |  7 ++++
>  arch/arm64/kernel/process.c                     |  5 ---
>  arch/arm64/kernel/setup.c                       |  7 ++++
>  arch/powerpc/platforms/pseries/processor_idle.c |  5 +++
>  arch/powerpc/platforms/pseries/setup.c          | 34 ++++++++-----------
>  arch/sh/kernel/idle.c                           |  4 +--
>  arch/x86/kernel/process.c                       |  5 +--
>  include/linux/cpu.h                             |  1 -
>  kernel/Makefile                                 |  1 -
>  kernel/cpu/Makefile                             |  1 -
>  kernel/sched/Makefile                           |  2 +-
>  kernel/{cpu => sched}/idle.c                    |  6 ++--
>  13 files changed, 44 insertions(+), 55 deletions(-)

Thomas, any objections to this? It looks like a sensible thing to do.

^ permalink raw reply

* [PATCH 1/9] ARM: get rid of arch_cpu_idle_prepare()
From: Russell King - ARM Linux @ 2014-01-27 12:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-2-git-send-email-nicolas.pitre@linaro.org>

On Mon, Jan 27, 2014 at 01:08:16AM -0500, Nicolas Pitre wrote:
> ARM and ARM64 are the only two architectures implementing
> arch_cpu_idle_prepare() simply to call local_fiq_enable().
> 
> We have secondary_start_kernel() already calling local_fiq_enable() and
> this is done a second time in arch_cpu_idle_prepare() in that case. And
> enabling FIQs has nothing to do with idling the CPU to start with.
> 
> So let's introduce init_fiq_boot_cpu() to take care of FIQs on the boot
> CPU and remove arch_cpu_idle_prepare(). This is now done a bit earlier
> at late_initcall time but this shouldn't make a difference in practice
> i.e. when FIQs are actually used.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/arm/kernel/process.c | 5 -----
>  arch/arm/kernel/setup.c   | 7 +++++++
>  2 files changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
> index 92f7b15dd2..725b8c95e0 100644
> --- a/arch/arm/kernel/process.c
> +++ b/arch/arm/kernel/process.c
> @@ -142,11 +142,6 @@ static void default_idle(void)
>  	local_irq_enable();
>  }
>  
> -void arch_cpu_idle_prepare(void)
> -{
> -	local_fiq_enable();
> -}
> -
>  void arch_cpu_idle_enter(void)
>  {
>  	ledtrig_cpu(CPU_LED_IDLE_START);
> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
> index 987a7f5bce..d027b1a6fe 100644
> --- a/arch/arm/kernel/setup.c
> +++ b/arch/arm/kernel/setup.c
> @@ -789,6 +789,13 @@ static int __init init_machine_late(void)
>  }
>  late_initcall(init_machine_late);
>  
> +static int __init init_fiq_boot_cpu(void)
> +{
> +	local_fiq_enable();
> +	return 0;
> +}
> +late_initcall(init_fiq_boot_cpu);

arch_cpu_idle_prepare() gets called from the swapper thread, and changes
the swapper thread's CPSR. init_fiq_boot_cpu() gets called from PID1, the
init thread, and changes the init thread's CPSR, which will already have
FIQs enabled by way of how kernel threads are created.

Hence, the above code fragment has no effect what so ever, and those
platforms using FIQs will not have FIQs delivered if they're idle
(because the swapper will have FIQs masked at the CPU.)

NAK.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH] arm64: add DSB after icache flush in __flush_icache_all()
From: Catalin Marinas @ 2014-01-27 12:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390823984-23046-1-git-send-email-vkale@apm.com>

On Mon, Jan 27, 2014 at 11:59:44AM +0000, Vinayak Kale wrote:
> Add DSB after icache flush operation.
> 
> Signed-off-by: Vinayak Kale <vkale@apm.com>

I think we should also mention that this function is used for user
addresses and an ISB is not required because of an exception return
before executing user instructions.

-- 
Catalin

^ permalink raw reply

* [PATCH] arm64: add DSB after icache flush in __flush_icache_all()
From: Will Deacon @ 2014-01-27 12:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390823984-23046-1-git-send-email-vkale@apm.com>

Hi Vinayak,

On Mon, Jan 27, 2014 at 11:59:44AM +0000, Vinayak Kale wrote:
> Add DSB after icache flush operation.

Please elaborate a bit on what this achieves (i.e. completion of the
maintenance operation).

> Signed-off-by: Vinayak Kale <vkale@apm.com>
> ---
>  arch/arm64/include/asm/cacheflush.h |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> index fea9ee3..88932498 100644
> --- a/arch/arm64/include/asm/cacheflush.h
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -116,6 +116,7 @@ extern void flush_dcache_page(struct page *);
>  static inline void __flush_icache_all(void)
>  {
>  	asm("ic	ialluis");

This needs a "memory" clobber to prevent re-ordering by GCC. We should
probably check the rest of the code for other occurrences of this too.

> +	dsb();

Can you make a corresponding change for arch/arm/ too, please? I think we're
missing the barrier there as well.

Will

^ permalink raw reply

* [PATCH v3] audit: Add generic compat syscall support
From: Catalin Marinas @ 2014-01-27 12:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52E5F56F.2030502@linaro.org>

On Mon, Jan 27, 2014 at 05:58:07AM +0000, AKASHI Takahiro wrote:
> Catalin and audit maintainers,
> 
> On 01/23/2014 11:51 PM, Catalin Marinas wrote:
> > On Fri, Jan 17, 2014 at 08:03:15AM +0000, AKASHI Takahiro wrote:
> >> diff --git a/lib/compat_audit.c b/lib/compat_audit.c
> >> new file mode 100644
> >> index 0000000..94f6480
> >> --- /dev/null
> >> +++ b/lib/compat_audit.c
> >> @@ -0,0 +1,51 @@
> >> +#include <linux/init.h>
> >> +#include <linux/types.h>
> >> +/* FIXME: this might be architecture dependent */
> >> +#include <asm/unistd_32.h>
> >
> > It most likely is architecture dependent.
> 
> I'm wondering what name is the most appropriate in this case.
> Most archictures have __NR_xyz definitions in "unistd_32.h",
> but arm64 doesn't have it, instead "unistd32." which contains
> only __SYSCALL(xyz, NO). Confusing?

I don't think we should introduce a new file (or at least it should be
named something containing "audit" to make it clearer).

> >> +int audit_classify_compat_syscall(int abi, unsigned syscall)
> >> +{
> >> +	switch (syscall) {
> >> +#ifdef __NR_open
> >> +	case __NR_open:
> >> +		return 2;
> >> +#endif
> >> +#ifdef __NR_openat
> >> +	case __NR_openat:
> >> +		return 3;
> >> +#endif
> >> +#ifdef __NR_socketcall
> >> +	case __NR_socketcall:
> >> +		return 4;
> >> +#endif
> >> +	case __NR_execve:
> >> +		return 5;
> >> +	default:
> >> +		return 1;
> >> +	}
> >> +}
> >
> > BTW, since they aren't many, you could get the arch code to define
> > __NR_compat_open etc. explicitly and use these. On arm64 we have a few
> > of these defined to avoid name collision in signal handling code.
> 
> Again, most architecture have their own unistd32.h for compat system calls,
> and use __NR_open-like naming.
> It's unlikely for these archs to migrate to "generic compat" auditing,
> but I believe that '__NR_open'-like naming is better because we may be able to avoid
> arch-specific changes even for future(?) syscall-related enhancements in audit.

My preference is as above, a few __NR_compat_* (just those required by
audit) defined in unistd.h but I'm not an audit maintainer.

-- 
Catalin

^ permalink raw reply

* [PATCH 6/9] PPC: remove redundant cpuidle_idle_call()
From: Preeti U Murthy @ 2014-01-27 11:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390802904-28399-7-git-send-email-nicolas.pitre@linaro.org>

Hi Nicolas,

On 01/27/2014 11:38 AM, Nicolas Pitre wrote:
> The core idle loop now takes care of it.  However a few things need
> checking:
> 
> - Invocation of cpuidle_idle_call() in pseries_lpar_idle() happened
>   through arch_cpu_idle() and was therefore always preceded by a call
>   to ppc64_runlatch_off().  To preserve this property now that
>   cpuidle_idle_call() is invoked directly from core code, a call to
>   ppc64_runlatch_off() has been added to idle_loop_prolog() in
>   platforms/pseries/processor_idle.c.
> 
> - Similarly, cpuidle_idle_call() was followed by ppc64_runlatch_off()
>   so a call to the later has been added to idle_loop_epilog().
> 
> - And since arch_cpu_idle() always made sure to re-enable IRQs if they
>   were not enabled, this is now
>   done in idle_loop_epilog() as well.
> 
> The above was made in order to keep the execution flow close to the
> original.  I don't know if that was strictly necessary. Someone well
> aquainted with the platform details might find some room for possible
> optimizations.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/powerpc/platforms/pseries/processor_idle.c |  5 ++++
>  arch/powerpc/platforms/pseries/setup.c          | 34 ++++++++++---------------
>  2 files changed, 19 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
> index a166e38bd6..72ddfe3d2f 100644
> --- a/arch/powerpc/platforms/pseries/processor_idle.c
> +++ b/arch/powerpc/platforms/pseries/processor_idle.c
> @@ -33,6 +33,7 @@ static struct cpuidle_state *cpuidle_state_table;
> 
>  static inline void idle_loop_prolog(unsigned long *in_purr)
>  {
> +	ppc64_runlatch_off();
>  	*in_purr = mfspr(SPRN_PURR);
>  	/*
>  	 * Indicate to the HV that we are idle. Now would be
> @@ -49,6 +50,10 @@ static inline void idle_loop_epilog(unsigned long in_purr)
>  	wait_cycles += mfspr(SPRN_PURR) - in_purr;
>  	get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles);
>  	get_lppaca()->idle = 0;
> +
> +	if (irqs_disabled())
> +		local_irq_enable();
> +	ppc64_runlatch_on();
>  }
> 
>  static int snooze_loop(struct cpuidle_device *dev,
> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
> index c1f1908587..7604c19d54 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -39,7 +39,6 @@
>  #include <linux/irq.h>
>  #include <linux/seq_file.h>
>  #include <linux/root_dev.h>
> -#include <linux/cpuidle.h>
>  #include <linux/of.h>
>  #include <linux/kexec.h>
> 
> @@ -356,29 +355,24 @@ early_initcall(alloc_dispatch_log_kmem_cache);
> 
>  static void pseries_lpar_idle(void)
>  {
> -	/* This would call on the cpuidle framework, and the back-end pseries
> -	 * driver to  go to idle states
> +	/*
> +	 * Default handler to go into low thread priority and possibly
> +	 * low power mode by cedeing processor to hypervisor
>  	 */
> -	if (cpuidle_idle_call()) {
> -		/* On error, execute default handler
> -		 * to go into low thread priority and possibly
> -		 * low power mode by cedeing processor to hypervisor
> -		 */
> 
> -		/* Indicate to hypervisor that we are idle. */
> -		get_lppaca()->idle = 1;
> +	/* Indicate to hypervisor that we are idle. */
> +	get_lppaca()->idle = 1;
> 
> -		/*
> -		 * Yield the processor to the hypervisor.  We return if
> -		 * an external interrupt occurs (which are driven prior
> -		 * to returning here) or if a prod occurs from another
> -		 * processor. When returning here, external interrupts
> -		 * are enabled.
> -		 */
> -		cede_processor();
> +	/*
> +	 * Yield the processor to the hypervisor.  We return if
> +	 * an external interrupt occurs (which are driven prior
> +	 * to returning here) or if a prod occurs from another
> +	 * processor. When returning here, external interrupts
> +	 * are enabled.
> +	 */
> +	cede_processor();
> 
> -		get_lppaca()->idle = 0;
> -	}
> +	get_lppaca()->idle = 0;
>  }
> 
>  /*
> 

Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>

The consequence of this would be for other Power platforms like PowerNV,
we will need to invoke ppc_runlatch_off() and ppc_runlatch_on() in each
of the idle routines since the idle_loop_prologue() and
idle_loop_epilogue() are not invoked by them, but we will take care of this.

Regards
Preeti U Murthy

^ permalink raw reply

* [PATCH] arm64: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-01-27 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Add DSB after icache flush operation.

Signed-off-by: Vinayak Kale <vkale@apm.com>
---
 arch/arm64/include/asm/cacheflush.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index fea9ee3..88932498 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -116,6 +116,7 @@ extern void flush_dcache_page(struct page *);
 static inline void __flush_icache_all(void)
 {
 	asm("ic	ialluis");
+	dsb();
 }
 
 #define flush_dcache_mmap_lock(mapping) \
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox