Re: [PATCH v6 0/8] power: add power sequence library

2016-09-19 Thread Vaibhav Hiremath



On Monday 19 September 2016 01:16 PM, Peter Chen wrote:

On Mon, Sep 19, 2016 at 01:09:10PM +0530, Vaibhav Hiremath wrote:


On Friday 09 September 2016 02:17 PM, Ulf Hansson wrote:

[...]


We had an agreement that keep mmc's pwrseq framework unchanging.
Unless Ulf and rob both agree to change.

Why 2 separate approach for same problem ?
And I see this as possible duplication of code/functionality :)

How the new kernel compatibles old dts? If we do not need to
consider this problem, the mmc can try to use power sequence library
too in future.

I think we should attempt to get both MMC and USB power seq
come on one agreement, so that it can be reused.

That would be nice. Although, to do that you would have to allow some
DT bindings to be deprecated in the new generic power seq bindings, as
otherwise you would break existing DTBs.

I guess that is what Rob was objecting to!?

yeah, thats right.

So lets adopt similar implementation for USB as well instead of
library, but keeping MMC untouched as of now.

What I am trying to propose here is,

Lets have power-sequence framework (similar to V1 of this series),
with,

pwrseq: Core framework for power sequence.
pwrseq_generic/simple: for all generic control, like reset and clock
pwrseq_emmc: probably duplication of existing code - the idea
   here is, all future code should be using this new
   binding, so that we can deprecate the
drivers/mmc/core/pwrseq
pwrseq_arche: The usecase which I am dealing with today, which is more
  complex in nature.

Then the respective drivers can add their drivers (if needed) based on
complexity.

comments ??

The key point here is DT maintainer (Rob) doesn't agree with adding new node
for power sequence at dts.



Hmmm.
We haven't heard from Rob lately especially after introduction of complex
usecases. I hope he would revisit on above proposal.

Thanks,
Vaibhav


Re: [PATCH v6 0/8] power: add power sequence library

2016-09-19 Thread Vaibhav Hiremath



On Friday 09 September 2016 02:17 PM, Ulf Hansson wrote:

[...]


We had an agreement that keep mmc's pwrseq framework unchanging.
Unless Ulf and rob both agree to change.

Why 2 separate approach for same problem ?
And I see this as possible duplication of code/functionality :)

How the new kernel compatibles old dts? If we do not need to
consider this problem, the mmc can try to use power sequence library
too in future.


I think we should attempt to get both MMC and USB power seq
come on one agreement, so that it can be reused.

That would be nice. Although, to do that you would have to allow some
DT bindings to be deprecated in the new generic power seq bindings, as
otherwise you would break existing DTBs.

I guess that is what Rob was objecting to!?


yeah, thats right.

So lets adopt similar implementation for USB as well instead of
library, but keeping MMC untouched as of now.

What I am trying to propose here is,

Lets have power-sequence framework (similar to V1 of this series),
with,

pwrseq: Core framework for power sequence.
pwrseq_generic/simple: for all generic control, like reset and clock
pwrseq_emmc: probably duplication of existing code - the idea
  here is, all future code should be using this new
  binding, so that we can deprecate the 
drivers/mmc/core/pwrseq

pwrseq_arche: The usecase which I am dealing with today, which is more
 complex in nature.

Then the respective drivers can add their drivers (if needed) based on
complexity.

comments ??


MMC Power Seq :
  It is based on platform_device/platform_driver approach,

We recently converted MMC to this. It's has a clear benefit as you can
rely on the behaviour from the driver core and PM core. So, it simply
avoids duplication of code.


Agreed.


USB Power seq :
  We are trying to propose library approach, with compatible string match.

We should try to have one approach.



   - Lets also add suspend/resume callback to struct pwrseq


Why suspend/resume can't do at related driver's suspend/resume API?

Nope...
The pwrseq library would have taken ownership of resources, so
related driver cannot suspend the device. Again it is architecture
specific, but we should have provision to handle this.

The system I am dealing with today, does need suspend/resume
callback. To be precise, suspend is close to off state for some devices
or
they could enter standby or different low power state, but to do that,
we need same resource as used for ON/OFF functionality.


Ok, I will have API for suspend/resume. You can implement it at your own
library or generic one.

As stated, using a platform device + driver would simplify this, as
you wouldn't need an API but only a driver. I guess.


Exactly.

Thanks,
Vaibhav


Re: [PATCH v6 0/8] power: add power sequence library

2016-09-06 Thread Vaibhav Hiremath

a

On Friday 02 September 2016 06:40 AM, Peter Chen wrote:

On Wed, Aug 31, 2016 at 10:28:20PM +0530, Vaibhav Hiremath wrote:


On Wednesday 31 August 2016 03:22 PM, Peter Chen wrote:

On Wed, Aug 31, 2016 at 01:46:30PM +0530, Vaibhav Hiremath wrote:

On Monday 29 August 2016 04:40 PM, Peter Chen wrote:

On Wed, Aug 24, 2016 at 04:53:35PM +0800, Peter Chen wrote:

On Tue, Aug 23, 2016 at 04:02:48PM +0530, Vaibhav Hiremath wrote:

veOn Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Hi all,

This is a follow-up for my last power sequence framework patch set [1].
According to Rob Herring and Ulf Hansson's comments[2], I use a generic
power sequence library for parsing the power sequence elements on DT,
and implement generic power sequence on library. The host driver
can allocate power sequence instance, and calls pwrseq APIs accordingly.

In future, if there are special power sequence requirements, the special
power sequence library can be created.

This patch set is tested on i.mx6 sabresx evk using a dts change, I use
two hot-plug devices to simulate this use case, the related binding
change is updated at patch [1/6], The udoo board changes were tested
using my last power sequence patch set.[3]

Except for hard-wired MMC and USB devices, I find the USB ULPI PHY also
need to power on itself before it can be found by ULPI bus.

[1]http://www.spinics.net/lists/linux-usb/msg142755.html
[2]http://www.spinics.net/lists/linux-usb/msg143106.html
[3]http://www.spinics.net/lists/linux-usb/msg142815.html

(Please ignore my response on V2)

Sorry being so late in the discussion...

If I am not missing anything, then I am afraid to say that the
generic library
implementation in this patch series is not going to solve many of
the custom
requirement of power on, off, etc...
I know you mentioned about adding another library when we come
across such platforms, but should we not keep provision (or easy
hooks/path)
to enable that ?

Let me bring in the use case I am dealing with,


   Host
|
V
USB port

|
V
   USB HUB device (May need custom on/off seq)
|
V
   =
  | |
  V V
  Device-1   Device-2
(Needs special power   (Needs special power
  on/off sequence.   on/off sequence.
  Also may need custom   Also, may need custom
  sequence for   sequence for
  suspend/resume)suspend/resume)


Note: Both Devices are connected to HUB via HSIC and may differ
   in terms of functionality, features they support.

In the above case, both Device-1 and Device-2, need separate
power on/off sequence. So generic library currently we have in this
patch series is not going to satisfy the need here.

I looked at all 6 revisions of this patch-series, went through the
review comments, and looked at MMC power sequence code;
what I can say here is, we need something similar to
MMC power sequence here, where every device can have its own
power sequence (if needed).

I know Rob is not in favor of creating platform device for
this, and I understand his comment.
If not platform device, but atleast we need mechanism to
connect each device back to its of_node and its respective
driver/library fns. For example, the Devices may support different
boot modes, and platform driver needs to make sure that
the right sequence is followed for booting.

Peter, My apologies for taking you back again on this series.
I am OK, if you wish to address this in incremental addition,
but my point is, we know that the current generic way is not
enough for us, so I think we should try to fix it in initial phase only.


Rob, it seems generic power sequence can't cover all cases.
Without information from DT, we can't know which power sequence
for which device.


Vaibhav, do you agree that I create pwrseq library list using postcore_initcall
for each library, and choose pwrseq library according to compatible
string first, if there is no compatible string for this library, just
use generic pwrseq library.


Lets hear from MMC folks. Ulf, do you agree on approach
for pwr seq ??


With above approach, I kind of agree on it, but I have couple
of comments,

  - How DTS looks like now ?? Can you put example here ?

The dts is the same with current version.

How would consumer driver get the power sequence ?
You must point to right power sequence driver.
For example, in the above example, Device-1, should
get handle to pwrseq-1, and Device-2 to pwrseq-2.

According to compatible string at device's of_node,

Re: [PATCH v6 1/8] binding-doc: power: pwrseq-generic: add binding doc for generic power sequence library

2016-09-05 Thread Vaibhav Hiremath



On Friday 02 September 2016 06:30 AM, Peter Chen wrote:

On Thu, Sep 01, 2016 at 01:33:22PM +0530, Vaibhav Hiremath wrote:


On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Add binding doc for generic power sequence library.

Signed-off-by: Peter Chen 
Acked-by: Philipp Zabel 
Acked-by: Rob Herring 
---
  .../bindings/power/pwrseq/pwrseq-generic.txt   | 48 ++
  1 file changed, 48 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt

diff --git a/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt 
b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
new file mode 100644
index 000..ebf0d47
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
@@ -0,0 +1,48 @@
+The generic power sequence library
+
+Some hard-wired devices (eg USB/MMC) need to do power sequence before
+the device can be enumerated on the bus, the typical power sequence
+like: enable USB PHY clock, toggle reset pin, etc. But current
+Linux device driver lacks of such code to do it, it may cause some
+hard-wired devices works abnormal or can't be recognized by
+controller at all. The power sequence will be done before this device
+can be found at the bus.
+
+The power sequence properties is under the device node.
+
+Optional properties:
+- clocks: the input clocks for device.
+- reset-gpios: Should specify the GPIO for reset.
+- reset-duration-us: the duration in microsecond for assert reset signal.
+
+Below is the example of USB power sequence properties on USB device
+nodes which have two level USB hubs.
+
+&usbotg1 {
+   vbus-supply = <®_usb_otg1_vbus>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&pinctrl_usb_otg1_id>;
+   status = "okay";
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+   genesys: hub@1 {
+   compatible = "usb5e3,608";
+   reg = <1>;
+
+   clocks = <&clks IMX6SX_CLK_CKO>;
+   reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* hub reset pin */
+   reset-duration-us = <10>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+   asix: ethernet@1 {
+   compatible = "usbb95,1708";

So I assume, with our recent discussion and the change
we are proposing, the library would have some knowledge
about this compatible string, right?

Yes


what I was asking on other email was, how are you connecting
multiple power sequence libraries to their respective consumers ?


The consumers has its of_node, then it can find related power sequence
library according to compatible string.



Exactly. Thats what I was referring and wanted to confirm.

Thanks,
Vaibhav


--
Thanks,
Vaibhav



Re: [PATCH v6 2/8] power: add power sequence library

2016-09-01 Thread Vaibhav Hiremath



On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

We have an well-known problem that the device needs to do some power
sequence before it can be recognized by related host, the typical
example like hard-wired mmc devices and usb devices.

This power sequence is hard to be described at device tree and handled by
related host driver, so we have created a common power sequence
library to cover this requirement. The core code has supplied
some common helpers for host driver, and individual power sequence
libraries handle kinds of power sequence for devices.

pwrseq_generic is intended for general purpose of power sequence, which
handles gpios and clocks currently, and can cover regulator and pinctrl
in future. The host driver calls pwrseq_alloc_generic to create
an generic pwrseq instance.

Signed-off-by: Peter Chen 
Tested-by Joshua Clayton 
Reviewed-by: Matthias Kaehlcke 
Tested-by: Matthias Kaehlcke 
---
  MAINTAINERS   |   9 ++
  drivers/power/Kconfig |   1 +
  drivers/power/Makefile|   1 +
  drivers/power/pwrseq/Kconfig  |  20 
  drivers/power/pwrseq/Makefile |   2 +
  drivers/power/pwrseq/core.c   |  62 +
  drivers/power/pwrseq/pwrseq_generic.c | 168 ++
  include/linux/power/pwrseq.h  |  47 ++
  8 files changed, 310 insertions(+)
  create mode 100644 drivers/power/pwrseq/Kconfig
  create mode 100644 drivers/power/pwrseq/Makefile
  create mode 100644 drivers/power/pwrseq/core.c
  create mode 100644 drivers/power/pwrseq/pwrseq_generic.c
  create mode 100644 include/linux/power/pwrseq.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1ae6c84..407254b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9283,6 +9283,15 @@ F:   include/linux/pm_*
  F:include/linux/powercap.h
  F:drivers/powercap/
  
+POWER SEQUENCE LIBRARY

+M: Peter Chen 
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git
+L: linux...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/power/pwrseq/
+F: drivers/power/pwrseq/
+F: include/linux/power/pwrseq.h/
+
  POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
  M:Sebastian Reichel 
  M:Dmitry Eremin-Solenikov 
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index acd4a15..f6aa4fd 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -515,3 +515,4 @@ endif # POWER_SUPPLY
  
  source "drivers/power/reset/Kconfig"

  source "drivers/power/avs/Kconfig"
+source "drivers/power/pwrseq/Kconfig"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index e46b75d..4ed2e12 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -74,3 +74,4 @@ obj-$(CONFIG_CHARGER_TPS65217)+= tps65217_charger.o
  obj-$(CONFIG_POWER_RESET) += reset/
  obj-$(CONFIG_AXP288_FUEL_GAUGE) += axp288_fuel_gauge.o
  obj-$(CONFIG_AXP288_CHARGER)  += axp288_charger.o
+obj-$(CONFIG_POWER_SEQUENCE)   += pwrseq/
diff --git a/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig
new file mode 100644
index 000..188729e
--- /dev/null
+++ b/drivers/power/pwrseq/Kconfig
@@ -0,0 +1,20 @@
+#
+# Power Sequence library
+#
+
+config POWER_SEQUENCE
+   bool
+
+menu "Power Sequence Support"
+
+config PWRSEQ_GENERIC
+   bool "Generic power sequence control"
+   depends on OF
+   select POWER_SEQUENCE
+   help
+ It is used for drivers which needs to do power sequence
+ (eg, turn on clock, toggle reset gpio) before the related
+ devices can be found by hardware. This generic one can be
+ used for common power sequence control.
+
+endmenu
diff --git a/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile
new file mode 100644
index 000..ad82389
--- /dev/null
+++ b/drivers/power/pwrseq/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_POWER_SEQUENCE) += core.o
+obj-$(CONFIG_PWRSEQ_GENERIC) += pwrseq_generic.o
diff --git a/drivers/power/pwrseq/core.c b/drivers/power/pwrseq/core.c
new file mode 100644
index 000..dcf96c4
--- /dev/null
+++ b/drivers/power/pwrseq/core.c
@@ -0,0 +1,62 @@
+/*
+ * core.c  power sequence core file
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Author: Peter Chen 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include 
+
+static DEFINE_MUTEX(pwrseq_list_mutex);
+static LIST_HEAD(pwrseq_list);
+
+int pwrseq_get(

Re: [PATCH v6 1/8] binding-doc: power: pwrseq-generic: add binding doc for generic power sequence library

2016-09-01 Thread Vaibhav Hiremath



On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Add binding doc for generic power sequence library.

Signed-off-by: Peter Chen 
Acked-by: Philipp Zabel 
Acked-by: Rob Herring 
---
  .../bindings/power/pwrseq/pwrseq-generic.txt   | 48 ++
  1 file changed, 48 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt

diff --git a/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt 
b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
new file mode 100644
index 000..ebf0d47
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt
@@ -0,0 +1,48 @@
+The generic power sequence library
+
+Some hard-wired devices (eg USB/MMC) need to do power sequence before
+the device can be enumerated on the bus, the typical power sequence
+like: enable USB PHY clock, toggle reset pin, etc. But current
+Linux device driver lacks of such code to do it, it may cause some
+hard-wired devices works abnormal or can't be recognized by
+controller at all. The power sequence will be done before this device
+can be found at the bus.
+
+The power sequence properties is under the device node.
+
+Optional properties:
+- clocks: the input clocks for device.
+- reset-gpios: Should specify the GPIO for reset.
+- reset-duration-us: the duration in microsecond for assert reset signal.
+
+Below is the example of USB power sequence properties on USB device
+nodes which have two level USB hubs.
+
+&usbotg1 {
+   vbus-supply = <®_usb_otg1_vbus>;
+   pinctrl-names = "default";
+   pinctrl-0 = <&pinctrl_usb_otg1_id>;
+   status = "okay";
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+   genesys: hub@1 {
+   compatible = "usb5e3,608";
+   reg = <1>;
+
+   clocks = <&clks IMX6SX_CLK_CKO>;
+   reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* hub reset pin */
+   reset-duration-us = <10>;
+
+   #address-cells = <1>;
+   #size-cells = <0>;
+   asix: ethernet@1 {
+   compatible = "usbb95,1708";


So I assume, with our recent discussion and the change
we are proposing, the library would have some knowledge
about this compatible string, right?

what I was asking on other email was, how are you connecting
multiple power sequence libraries to their respective consumers ?

Thanks,
Vaibhav


+   reg = <1>;
+
+   clocks = <&clks IMX6SX_CLK_IPG>;
+   reset-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* 
ethernet_rst */
+   reset-duration-us = <15>;
+   };
+   };
+};


--
Thanks,
Vaibhav



Re: [PATCH v6 4/8] usb: core: add power sequence handling for USB devices

2016-09-01 Thread Vaibhav Hiremath



On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Some hard-wired USB devices need to do power sequence to let the
device work normally, the typical power sequence like: enable USB
PHY clock, toggle reset pin, etc. But current Linux USB driver
lacks of such code to do it, it may cause some hard-wired USB devices
works abnormal or can't be recognized by controller at all.

In this patch, it calls power sequence library APIs to finish
the power sequence events. At first, it calls pwrseq_alloc_generic
to create a generic power sequence instance, then it will do power
on sequence at hub's probe for all devices under this hub
(includes root hub).

At hub_disconnect, it will do power off sequence which is at powered
on list.

Signed-off-by: Peter Chen 
Tested-by Joshua Clayton 
---
  drivers/usb/core/Makefile |   1 +
  drivers/usb/core/hub.c|  12 --
  drivers/usb/core/hub.h|  12 ++
  drivers/usb/core/pwrseq.c | 100 ++
  4 files changed, 122 insertions(+), 3 deletions(-)
  create mode 100644 drivers/usb/core/pwrseq.c

diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 9780877..39f2149 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -9,5 +9,6 @@ usbcore-y += port.o of.o
  
  usbcore-$(CONFIG_PCI)		+= hcd-pci.o

  usbcore-$(CONFIG_ACPI)+= usb-acpi.o
+usbcore-$(CONFIG_PWRSEQ_GENERIC) += pwrseq.o
  
  obj-$(CONFIG_USB)		+= usbcore.o

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bee1351..a346a8b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1700,6 +1700,7 @@ static void hub_disconnect(struct usb_interface *intf)
hub->error = 0;
hub_quiesce(hub, HUB_DISCONNECT);
  
+	hub_pwrseq_off(hub);

mutex_lock(&usb_port_peer_mutex);
  
  	/* Avoid races with recursively_mark_NOTATTACHED() */

@@ -1733,6 +1734,7 @@ static int hub_probe(struct usb_interface *intf, const 
struct usb_device_id *id)
struct usb_endpoint_descriptor *endpoint;
struct usb_device *hdev;
struct usb_hub *hub;
+   int ret = -ENODEV;
  
  	desc = intf->cur_altsetting;

hdev = interface_to_usbdev(intf);
@@ -1839,6 +1841,7 @@ descriptor_error:
INIT_DELAYED_WORK(&hub->leds, led_work);
INIT_DELAYED_WORK(&hub->init_work, NULL);
INIT_WORK(&hub->events, hub_event);
+   INIT_LIST_HEAD(&hub->pwrseq_on_list);
usb_get_intf(intf);
usb_get_dev(hdev);
  
@@ -1852,11 +1855,14 @@ descriptor_error:

if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND)
hub->quirk_check_port_auto_suspend = 1;
  
-	if (hub_configure(hub, endpoint) >= 0)

-   return 0;
+   if (hub_configure(hub, endpoint) >= 0) {
+   ret = hub_pwrseq_on(hub);
+   if (!ret)
+   return 0;
+   }
  
  	hub_disconnect(intf);

-   return -ENODEV;
+   return ret;
  }
  
  static int

diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index 34c1a7e..9473f6f 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -78,6 +78,7 @@ struct usb_hub {
struct delayed_work init_work;
struct work_struct  events;
struct usb_port **ports;
+   struct list_headpwrseq_on_list; /* powered pwrseq node list */
  };
  
  /**

@@ -166,3 +167,14 @@ static inline int hub_port_debounce_be_stable(struct 
usb_hub *hub,
  {
return hub_port_debounce(hub, port1, false);
  }
+
+#if IS_ENABLED(CONFIG_PWRSEQ_GENERIC)
+int hub_pwrseq_on(struct usb_hub *hub);
+void hub_pwrseq_off(struct usb_hub *hub);
+#else
+static inline int hub_pwrseq_on(struct usb_hub *hub)
+{
+   return 0;
+}
+static inline void hub_pwrseq_off(struct usb_hub *hub) {}
+#endif /* CONFIG_PWRSEQ_GENERIC */
diff --git a/drivers/usb/core/pwrseq.c b/drivers/usb/core/pwrseq.c
new file mode 100644
index 000..837fe66
--- /dev/null
+++ b/drivers/usb/core/pwrseq.c
@@ -0,0 +1,100 @@
+/*
+ * pwrseq.cUSB device power sequence management
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Author: Peter Chen 
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hub.h"
+
+struct usb_pwrseq_node {
+   struct pwrseq *pwrseq;
+   struct list_head list;
+};
+
+static int hub_of_pwrseq_on(stru

Re: [PATCH v6 0/8] power: add power sequence library

2016-08-31 Thread Vaibhav Hiremath



On Wednesday 31 August 2016 03:22 PM, Peter Chen wrote:

On Wed, Aug 31, 2016 at 01:46:30PM +0530, Vaibhav Hiremath wrote:


On Monday 29 August 2016 04:40 PM, Peter Chen wrote:

On Wed, Aug 24, 2016 at 04:53:35PM +0800, Peter Chen wrote:

On Tue, Aug 23, 2016 at 04:02:48PM +0530, Vaibhav Hiremath wrote:

On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Hi all,

This is a follow-up for my last power sequence framework patch set [1].
According to Rob Herring and Ulf Hansson's comments[2], I use a generic
power sequence library for parsing the power sequence elements on DT,
and implement generic power sequence on library. The host driver
can allocate power sequence instance, and calls pwrseq APIs accordingly.

In future, if there are special power sequence requirements, the special
power sequence library can be created.

This patch set is tested on i.mx6 sabresx evk using a dts change, I use
two hot-plug devices to simulate this use case, the related binding
change is updated at patch [1/6], The udoo board changes were tested
using my last power sequence patch set.[3]

Except for hard-wired MMC and USB devices, I find the USB ULPI PHY also
need to power on itself before it can be found by ULPI bus.

[1]http://www.spinics.net/lists/linux-usb/msg142755.html
[2]http://www.spinics.net/lists/linux-usb/msg143106.html
[3]http://www.spinics.net/lists/linux-usb/msg142815.html

(Please ignore my response on V2)

Sorry being so late in the discussion...

If I am not missing anything, then I am afraid to say that the
generic library
implementation in this patch series is not going to solve many of
the custom
requirement of power on, off, etc...
I know you mentioned about adding another library when we come
across such platforms, but should we not keep provision (or easy
hooks/path)
to enable that ?

Let me bring in the use case I am dealing with,


   Host
|
V
USB port

|
V
   USB HUB device (May need custom on/off seq)
|
V
   =
  | |
  V V
  Device-1   Device-2
(Needs special power   (Needs special power
  on/off sequence.   on/off sequence.
  Also may need custom   Also, may need custom
  sequence for   sequence for
  suspend/resume)suspend/resume)


Note: Both Devices are connected to HUB via HSIC and may differ
   in terms of functionality, features they support.

In the above case, both Device-1 and Device-2, need separate
power on/off sequence. So generic library currently we have in this
patch series is not going to satisfy the need here.

I looked at all 6 revisions of this patch-series, went through the
review comments, and looked at MMC power sequence code;
what I can say here is, we need something similar to
MMC power sequence here, where every device can have its own
power sequence (if needed).

I know Rob is not in favor of creating platform device for
this, and I understand his comment.
If not platform device, but atleast we need mechanism to
connect each device back to its of_node and its respective
driver/library fns. For example, the Devices may support different
boot modes, and platform driver needs to make sure that
the right sequence is followed for booting.

Peter, My apologies for taking you back again on this series.
I am OK, if you wish to address this in incremental addition,
but my point is, we know that the current generic way is not
enough for us, so I think we should try to fix it in initial phase only.


Rob, it seems generic power sequence can't cover all cases.
Without information from DT, we can't know which power sequence
for which device.


Vaibhav, do you agree that I create pwrseq library list using postcore_initcall
for each library, and choose pwrseq library according to compatible
string first, if there is no compatible string for this library, just
use generic pwrseq library.


Lets hear from MMC folks. Ulf, do you agree on approach
for pwr seq ??


With above approach, I kind of agree on it, but I have couple
of comments,

  - How DTS looks like now ?? Can you put example here ?

The dts is the same with current version.


How would consumer driver get the power sequence ?
You must point to right power sequence driver.
For example, in the above example, Device-1, should
get handle to pwrseq-1, and Device-2 to pwrseq-2.


  - Should we merge MMC power sequence in next series ?
We also can take this as an incremental change, to avoid further
delay :)

We had an agreement that keep mmc

Re: [PATCH v6 0/8] power: add power sequence library

2016-08-31 Thread Vaibhav Hiremath



On Monday 29 August 2016 04:40 PM, Peter Chen wrote:

On Wed, Aug 24, 2016 at 04:53:35PM +0800, Peter Chen wrote:

On Tue, Aug 23, 2016 at 04:02:48PM +0530, Vaibhav Hiremath wrote:

On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Hi all,

This is a follow-up for my last power sequence framework patch set [1].
According to Rob Herring and Ulf Hansson's comments[2], I use a generic
power sequence library for parsing the power sequence elements on DT,
and implement generic power sequence on library. The host driver
can allocate power sequence instance, and calls pwrseq APIs accordingly.

In future, if there are special power sequence requirements, the special
power sequence library can be created.

This patch set is tested on i.mx6 sabresx evk using a dts change, I use
two hot-plug devices to simulate this use case, the related binding
change is updated at patch [1/6], The udoo board changes were tested
using my last power sequence patch set.[3]

Except for hard-wired MMC and USB devices, I find the USB ULPI PHY also
need to power on itself before it can be found by ULPI bus.

[1]http://www.spinics.net/lists/linux-usb/msg142755.html
[2]http://www.spinics.net/lists/linux-usb/msg143106.html
[3]http://www.spinics.net/lists/linux-usb/msg142815.html

(Please ignore my response on V2)

Sorry being so late in the discussion...

If I am not missing anything, then I am afraid to say that the
generic library
implementation in this patch series is not going to solve many of
the custom
requirement of power on, off, etc...
I know you mentioned about adding another library when we come
across such platforms, but should we not keep provision (or easy
hooks/path)
to enable that ?

Let me bring in the use case I am dealing with,


   Host
|
V
USB port

|
V
   USB HUB device (May need custom on/off seq)
|
V
   =
  | |
  V V
  Device-1   Device-2
(Needs special power   (Needs special power
  on/off sequence.   on/off sequence.
  Also may need custom   Also, may need custom
  sequence for   sequence for
  suspend/resume)suspend/resume)


Note: Both Devices are connected to HUB via HSIC and may differ
   in terms of functionality, features they support.

In the above case, both Device-1 and Device-2, need separate
power on/off sequence. So generic library currently we have in this
patch series is not going to satisfy the need here.

I looked at all 6 revisions of this patch-series, went through the
review comments, and looked at MMC power sequence code;
what I can say here is, we need something similar to
MMC power sequence here, where every device can have its own
power sequence (if needed).

I know Rob is not in favor of creating platform device for
this, and I understand his comment.
If not platform device, but atleast we need mechanism to
connect each device back to its of_node and its respective
driver/library fns. For example, the Devices may support different
boot modes, and platform driver needs to make sure that
the right sequence is followed for booting.

Peter, My apologies for taking you back again on this series.
I am OK, if you wish to address this in incremental addition,
but my point is, we know that the current generic way is not
enough for us, so I think we should try to fix it in initial phase only.


Rob, it seems generic power sequence can't cover all cases.
Without information from DT, we can't know which power sequence
for which device.


Vaibhav, do you agree that I create pwrseq library list using postcore_initcall
for each library, and choose pwrseq library according to compatible
string first, if there is no compatible string for this library, just
use generic pwrseq library.



Lets hear from MMC folks. Ulf, do you agree on approach
for pwr seq ??


With above approach, I kind of agree on it, but I have couple
of comments,

 - How DTS looks like now ?? Can you put example here ?
 - Should we merge MMC power sequence in next series ?
   We also can take this as an incremental change, to avoid further
   delay :)
 - Lets also add suspend/resume callback to struct pwrseq


There are some comments I have on the patches,
I will respond directly on respective patches, it would be useful
for next series.


And Sorry for delayed response.

--
Thanks,
Vaibhav



Re: [PATCH v6 0/8] power: add power sequence library

2016-08-23 Thread Vaibhav Hiremath



On Monday 15 August 2016 02:43 PM, Peter Chen wrote:

Hi all,

This is a follow-up for my last power sequence framework patch set [1].
According to Rob Herring and Ulf Hansson's comments[2], I use a generic
power sequence library for parsing the power sequence elements on DT,
and implement generic power sequence on library. The host driver
can allocate power sequence instance, and calls pwrseq APIs accordingly.

In future, if there are special power sequence requirements, the special
power sequence library can be created.

This patch set is tested on i.mx6 sabresx evk using a dts change, I use
two hot-plug devices to simulate this use case, the related binding
change is updated at patch [1/6], The udoo board changes were tested
using my last power sequence patch set.[3]

Except for hard-wired MMC and USB devices, I find the USB ULPI PHY also
need to power on itself before it can be found by ULPI bus.

[1] http://www.spinics.net/lists/linux-usb/msg142755.html
[2] http://www.spinics.net/lists/linux-usb/msg143106.html
[3] http://www.spinics.net/lists/linux-usb/msg142815.html

(Please ignore my response on V2)

Sorry being so late in the discussion...

If I am not missing anything, then I am afraid to say that the generic 
library
implementation in this patch series is not going to solve many of the 
custom

requirement of power on, off, etc...
I know you mentioned about adding another library when we come
across such platforms, but should we not keep provision (or easy 
hooks/path)

to enable that ?

Let me bring in the use case I am dealing with,


  Host
   |
   V
   USB port

   |
   V
  USB HUB device (May need custom on/off seq)
   |
   V
  =
 | |
 V V
 Device-1   Device-2
(Needs special power   (Needs special power
 on/off sequence.   on/off sequence.
 Also may need custom   Also, may need custom
 sequence for   sequence for
 suspend/resume)suspend/resume)


Note: Both Devices are connected to HUB via HSIC and may differ
  in terms of functionality, features they support.

In the above case, both Device-1 and Device-2, need separate
power on/off sequence. So generic library currently we have in this
patch series is not going to satisfy the need here.

I looked at all 6 revisions of this patch-series, went through the
review comments, and looked at MMC power sequence code;
what I can say here is, we need something similar to
MMC power sequence here, where every device can have its own
power sequence (if needed).

I know Rob is not in favor of creating platform device for
this, and I understand his comment.
If not platform device, but atleast we need mechanism to
connect each device back to its of_node and its respective
driver/library fns. For example, the Devices may support different
boot modes, and platform driver needs to make sure that
the right sequence is followed for booting.

Peter, My apologies for taking you back again on this series.
I am OK, if you wish to address this in incremental addition,
but my point is, we know that the current generic way is not
enough for us, so I think we should try to fix it in initial phase only.


Thanks,
Vaibhav




Changes for v6:
- Add Matthias Kaehlcke's Reviewed-by and Tested-by. (patch [2/6])
- Change chipidea core of_node assignment for coming user. (patch [5/6])
- Applies Joshua Clayton's three dts changes for two boards,
   the USB device's reg has only #address-cells, but without #size-cells.

Changes for v5:
- Delete pwrseq_register/pwrseq_unregister, which is useless currently
- Fix the linker error when the pwrseq user is compiled as module

Changes for v4:
- Create the patch on next-20160722
- Fix the of_node is not NULL after chipidea driver is unbinded [Patch 5/6]
- Using more friendly wait method for reset gpio [Patch 2/6]
- Support multiple input clocks [Patch 2/6]
- Add Rob Herring's ack for DT changes
- Add Joshua Clayton's Tested-by

Changes for v3:
- Delete "power-sequence" property at binding-doc, and change related code
   at both library and user code.
- Change binding-doc example node name with Rob's comments
- of_get_named_gpio_flags only gets the gpio, but without setting gpio flags,
   add additional code request gpio with proper gpio flags
- Add Philipp Zabel's Ack and MAINTAINER's entry

Changes for v2:
- Delete "pwrseq" prefix and clock-names for properties at dt binding
- Should use structure not but its pointer for kzalloc
- Since chipidea core has no of_node, let core's of_node equals glue
   layer'

Re: [PATCH] USB: core: of: Check device_node before parsing in usb_of_get_child_node()

2016-08-16 Thread Vaibhav Hiremath



On Monday 15 August 2016 06:33 PM, Peter Chen wrote:

On Mon, Aug 15, 2016 at 11:31:10AM -0700, Vaibhav Hiremath wrote:

In case of HUB devices connected to USB ports, we may not have DT
node representing it inside USB, and when devices connected to hub
gets enumerated, call to usb_of_get_child_node() leads to NULL pointer
dereference.

In the usecase we have, where EHCI port is connected to USB HUB
device, and downward ports of HUB are connected to further USB
devices. When those devices gets enumerated, in order,
  1. USB HUB ->
-> Call to usb_of_get_child_node() is OK, as
parent->dev.of_node is pointing to host node.
  2. Devices connected to downward port of USB HUB
-> Call to usb_of_get_child_node() leads to NULL
pointer dereference as parent->dev.of_node = NULL,
as USB HUB DTS node may be empty.

Fix this NULL pointer dereference by adding check for pointer
device_node inside usb_of_get_child_node() fn.

Signed-off-by: Vaibhav Hiremath 
---
Testing: I have build tested it against mainline.

  drivers/usb/core/of.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c
index 2289700..dc667a3 100644
--- a/drivers/usb/core/of.c
+++ b/drivers/usb/core/of.c
@@ -34,6 +34,9 @@ struct device_node *usb_of_get_child_node(struct device_node 
*parent,
struct device_node *node;
u32 port;
  
+	if (!parent)

+   return NULL;
+
for_each_child_of_node(parent, node) {
if (!of_property_read_u32(node, "reg", &port)) {
if (port == portnum)

I am afraid I can't reproduce it, would you please show me your dump
when null pointer dereference occurs? From what I find the
__of_get_next_child checks null pointer for parent node.



Peter,
You are right, __of_get_next_child is taking care of this.

When I observed this issue with my setup [1], I only looked at changes in
the mainline for of.c and core/usb.c, did not see the anything.

Anyways, for the record, we do not need this patch. Instead I need to 
backport

below commit from mainline to my kernel base.

commit 43cb43678705e39b175b325f17938295996aefc7
Author: Florian Fainelli 
Date:   Wed May 28 10:39:02 2014 -0700

of: handle NULL node in next_child iterators

Add an early check for the node argument in __of_get_next_child and
of_get_next_available_child() to avoid dereferencing a NULL node 
pointer

a few lines after.


[1] Also I missed to mention about my kernel version, I am based on very
ancient kernel version (3.10). Do not ask me why, it is something out of my
control :)

--
Thanks,
Vaibhav



Re: [PATCH] USB: core: of: Check device_node before parsing in usb_of_get_child_node()

2016-08-15 Thread Vaibhav Hiremath



On Monday 15 August 2016 11:41 AM, Greg KH wrote:

On Mon, Aug 15, 2016 at 11:31:10AM -0700, Vaibhav Hiremath wrote:

In case of HUB devices connected to USB ports, we may not have DT
node representing it inside USB, and when devices connected to hub
gets enumerated, call to usb_of_get_child_node() leads to NULL pointer
dereference.

Really?  That seems messed up.


unfortunately yes :)


In the usecase we have, where EHCI port is connected to USB HUB
device, and downward ports of HUB are connected to further USB
devices. When those devices gets enumerated, in order,
  1. USB HUB ->
-> Call to usb_of_get_child_node() is OK, as
parent->dev.of_node is pointing to host node.
  2. Devices connected to downward port of USB HUB
-> Call to usb_of_get_child_node() leads to NULL
pointer dereference as parent->dev.of_node = NULL,
as USB HUB DTS node may be empty.

Why is the hub DTS empty?  Shouldn't that be the fix here?


Because HUB can be enumerated dynamically and one possible
reason could be you don't need to do anything to bring up HUB.
May be one of following could be the reason -

 1. HUB automatically comes up on power ON, and USB host enumerates it.
   There is no control path for HUB

 2. HUB has different control path, in our case it is over I2C.
   So HUB configuration and bringup happens as part of I2C client driver.



So you may not need DTS for HUB as a child node inside USB host.
What I am trying to say here is,


&usb_ehci {
...

status = "ok";
};

This would enumerate HUB first, and then devices connected to HUB, right?
So this will lead to kernel crash.



Reference DTS with HUB and downward devices -

&usb_ehci {
status = "ok";

usb_hub: usb_hub {
compatible = "usb";
reg = <1>;

usb_dev: usb_dev {
compatible = "usb";
reg = <1>;

...
};
   };
};


Thanks,
Vaibhav


[PATCH] USB: core: of: Check device_node before parsing in usb_of_get_child_node()

2016-08-15 Thread Vaibhav Hiremath
In case of HUB devices connected to USB ports, we may not have DT
node representing it inside USB, and when devices connected to hub
gets enumerated, call to usb_of_get_child_node() leads to NULL pointer
dereference.

In the usecase we have, where EHCI port is connected to USB HUB
device, and downward ports of HUB are connected to further USB
devices. When those devices gets enumerated, in order,
 1. USB HUB ->
-> Call to usb_of_get_child_node() is OK, as
parent->dev.of_node is pointing to host node.
 2. Devices connected to downward port of USB HUB
-> Call to usb_of_get_child_node() leads to NULL
pointer dereference as parent->dev.of_node = NULL,
as USB HUB DTS node may be empty.

Fix this NULL pointer dereference by adding check for pointer
device_node inside usb_of_get_child_node() fn.

Signed-off-by: Vaibhav Hiremath 
---
Testing: I have build tested it against mainline.

 drivers/usb/core/of.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/core/of.c b/drivers/usb/core/of.c
index 2289700..dc667a3 100644
--- a/drivers/usb/core/of.c
+++ b/drivers/usb/core/of.c
@@ -34,6 +34,9 @@ struct device_node *usb_of_get_child_node(struct device_node 
*parent,
struct device_node *node;
u32 port;
 
+   if (!parent)
+   return NULL;
+
for_each_child_of_node(parent, node) {
if (!of_property_read_u32(node, "reg", &port)) {
if (port == portnum)
-- 
2.7.4



Re: [RFD] Sharing GPIOs for input (buttons) and output (LEDs)

2016-03-22 Thread Vaibhav Hiremath



On Thursday 17 March 2016 03:48 PM, Linus Walleij wrote:

On Mon, Feb 22, 2016 at 1:14 PM, Geert Uytterhoeven
 wrote:


On the Renesas Salvator-X development board, 3 GPIO pins are connected to both
push buttons and LEDs.


Not exactly related to buttons and leds,
but recently I came across another usecase of shared gpio,

Say, for example, we have multiple external I2C peripheral which share
interrupt line over gpio (ofcourse irq line is muxed onto single gpio).

Now in kernel I would have multiple instances of driver supporting each
peripheral but gpio can not be shared for registering irq.

Do you suggest MFD driver for such simple usecases ? Should gpiolib
support SHARED gpios, and gpiolib can define all the policies over
configuration (input only, what about conflicts, bidirectional mode?)

Thanks,
Vaibhav



   - If the GPIO is configured for output, it can control the LED,
   - If the GPIO is configured for input, the push button status can be
 read. Note that the LED is on if the push button is not pressed; it is
 turned off while holding the button.


Have you asked the hardware engineer who did this construction
what s/he was thinking? And I mean seriously: what was the
usecase? Did they really design the LEDs to be used to flicker
with or just as an indication as to whether the button was being
pushed or not?

Your approach seems dedicated to use it for both usecases (also
as a stand-alone heartbeat or whatever) but was that really
intended?


 keyboard {
 compatible = "gpio-keys";

 key-a {
 gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
 label = "SW20";
 wakeup-source;
 linux,code = ;
 };
 key-b {
 gpios = <&gpio6 12 GPIO_ACTIVE_LOW>;
 label = "SW21";
 wakeup-source;
 linux,code = ;
 };
 key-c {
 gpios = <&gpio6 13 GPIO_ACTIVE_LOW>;
 label = "SW22";
 wakeup-source;
 linux,code = ;
 };
 };


I suspect that in this usecase, the GPIO should be flagged
GPIO_OPEN_DRAIN rather than GPIO_ACTIVE_LOW,
as the construction with the LED draws current fron the line.


There exist device tree bindings for LEDs connected to GPIOs, and the
following also works:

 leds {
 compatible = "gpio-leds";

 led4 {
 gpios = <&gpio6 11 GPIO_ACTIVE_HIGH>;
 label = "LED4";
 };
 led5 {
 gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
 label = "LED5";
 };
 led6 {
 gpios = <&gpio6 13 GPIO_ACTIVE_HIGH>;
 label = "LED6";
 };
 };


OK


If a GPIO is found busy during initialization, and if it's already in
use by the other half of the driver, the driver switches to a special
"polled-key-and-LED" mode. I.e. during polling, it does:
   - Save the GPIO output state,
   - Switch the GPIO to input mode,
   - Wait 5 ms (else it will read the old output state, depending on
 e.g. hardware capacitance),
   - Read the GPIO input state,
   - Switch the GPIO to output mode,
   - Restore the GPIO output state.

And it works, the LEDs can be controlled, and the push button states can
be read!


Why go to such troubles of switching the line from output to
input to read it?

Especially when a line is OPEN_DRAIN it should be perfectly legal
to read it's value even if it is set as output, but AFAICT that is
always working no matter whether the line is set as output.


However, due to the 5 ms delay, there's a visible flickering of LEDs
that are supposed to be turned off (remember, when the GPIO is
configured for input and the button is not pressed, the LED is lit).

If we go this route, adding support for non-polled GPIOs (if the GPIO is
not shared with an LED) and wake-up should be doable.


I think this actually implies OPEN_DRAIN and if you flag it as such
the core should be happy using it as input and output at the same
time.

If the hardware has a problem with reading the value from a line
that is set to output, it needs a workaround hack in the driver to
support reading and output line, *NOT* changes to gpiolib,
because the lib assumes this is always possible, i.e. it will
call the driver .get() callback no matter what.

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



Re: [PATCH-v2 0/3] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-15 Thread Vaibhav Hiremath



On Tuesday 15 September 2015 05:58 PM, Ulf Hansson wrote:

On 7 September 2015 at 13:31, Vaibhav Hiremath
 wrote:

Trivial patch-series, which fixes the tabbing issue in the driver,
uses the BIT macro for bit fields and prints notice on -EPROBE_DEFER
in sdhci_add_host() function on regulator unavailability.

V1 => V2

  - Fixed all comments from Joe, mostly alignment changes
  - Separated BIT macro usage patch into new one.
  - changed error to kernel notice for EPROBE_DEFER in sdhci_add_host()

Note: This patch-series should get merged before another series -

[PATCH-v2 0/7] mmc: sdhci-pxav3: Enable support for PXA1928 SDCHI controller

Vaibhav Hiremath (3):
   mmc: sdhci-pxav3: Fix tabbing issue
   mmc: sdhci-pxav3: Use BIT macro for bit field definitions
   mmc: sdhci: print notice on -EPROBE_DEFER in sdhci_add_host() fn

  drivers/mmc/host/sdhci-pxav3.c | 46 +-
  drivers/mmc/host/sdhci.c   |  5 -
  2 files changed, 27 insertions(+), 24 deletions(-)

--
1.9.1



Hi Vaibhav,

FYI, I won't be picking up any of these patches. Primarily because I
don't think they improves the code and other people also seems to
agree to that.

Regarding patch1 and similar patches which deals with only fixing
checkpatch warnings/errors. In most cases I don't like such changes,
as they makes it harder to use "git blame" when you want to find out
which commit that introduced a change.




Honestly, I also agree with you.
But recently I have been told to do these changed to get my
main/feature changes accepted :)

No issues, I am OK to drop them.
These are just beautification changes and as you rightly
said it makes 'git blame' difficult to find original change commit.


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


Re: [RFC 2/3] mmc: sdhci: add host_ops->voltage_switch callback for all other voltages

2015-09-14 Thread Vaibhav Hiremath



On Monday 14 September 2015 06:11 PM, Vaibhav Hiremath wrote:



On Monday 14 September 2015 04:04 PM, Ulf Hansson wrote:

On 14 September 2015 at 11:42, Vaibhav Hiremath
 wrote:



On Monday 14 September 2015 03:00 PM, Ulf Hansson wrote:


[...]



Could this be implemented by regulator API? From patch set 3/3, the
pxa1928
voltage_switch hook is to operate the IO pad registers, this
seems not
belong
to the SDHC IP core.



Not quite sure whether regulator would be right fit for this.




   From the patche[3/3], this can be achieved by abstracting the
IO PAD
as
regulators
then, we may not need to touch the core sdhci.c. But I'm not sure
whether
this
is the good solution or not.




Exactly...


sdhci Maintainers and experts may have better
suggestions.



Thats is the reason I stamped it as a RFC :)



[...]

  From an mmc core perspective it would be preferred if you implement
this as a regulator (vqmmc).

Especially since we will soon have an API for how to set the I/O
voltages - and the intelligence within that API is not something we
would like to implement for each and every host driver.
https://lkml.org/lkml/2015/8/31/367




I would still consider this as a regulator specific and may not address
the IO configuration within the SoC which are module specific.
The API regulator_set_voltage_triplet() will not have intelligence to
differentiate whether the call is coming from MMC or somewhere else.

Note that, the IO pad voltage configuration which I am referring to is
MMC specific and applicable only when pad is configured in MMC mode. So
technically it is not simply common pad voltage configuration.


And I am still not sure regulator framework would be right fit for
this. Pinctrl would have been right fit, but...since I saw f_sdh30
driver is already doing this, which is easy fit; so adopted the same.


Pinctrl would work as well, or perhaps a combination of both pinctrl
and a regulator.



Not sure, how I can propagate "call coming from MMC/SD" to both
regulator and pinctrl.
Probably pinctrl would already know, but then it doesn't know the
voltage settings.

Let me spend some time, but atleast at this point I am not sure.





On the side note,
Lets park this patch aside, till I get back with better option.

It would be nice if you could review other patches, let them notget
blocked due to this.


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


Re: [RFC 2/3] mmc: sdhci: add host_ops->voltage_switch callback for all other voltages

2015-09-14 Thread Vaibhav Hiremath



On Monday 14 September 2015 04:04 PM, Ulf Hansson wrote:

On 14 September 2015 at 11:42, Vaibhav Hiremath
 wrote:



On Monday 14 September 2015 03:00 PM, Ulf Hansson wrote:


[...]



Could this be implemented by regulator API? From patch set 3/3, the
pxa1928
voltage_switch hook is to operate the IO pad registers, this seems not
belong
to the SDHC IP core.



Not quite sure whether regulator would be right fit for this.




   From the patche[3/3], this can be achieved by abstracting the IO PAD
as
regulators
then, we may not need to touch the core sdhci.c. But I'm not sure
whether
this
is the good solution or not.




Exactly...


sdhci Maintainers and experts may have better
suggestions.



Thats is the reason I stamped it as a RFC :)



[...]

  From an mmc core perspective it would be preferred if you implement
this as a regulator (vqmmc).

Especially since we will soon have an API for how to set the I/O
voltages - and the intelligence within that API is not something we
would like to implement for each and every host driver.
https://lkml.org/lkml/2015/8/31/367




I would still consider this as a regulator specific and may not address
the IO configuration within the SoC which are module specific.
The API regulator_set_voltage_triplet() will not have intelligence to
differentiate whether the call is coming from MMC or somewhere else.

Note that, the IO pad voltage configuration which I am referring to is
MMC specific and applicable only when pad is configured in MMC mode. So
technically it is not simply common pad voltage configuration.


And I am still not sure regulator framework would be right fit for
this. Pinctrl would have been right fit, but...since I saw f_sdh30
driver is already doing this, which is easy fit; so adopted the same.


Pinctrl would work as well, or perhaps a combination of both pinctrl
and a regulator.



Not sure, how I can propagate "call coming from MMC/SD" to both
regulator and pinctrl.
Probably pinctrl would already know, but then it doesn't know the
voltage settings.

Let me spend some time, but atleast at this point I am not sure.



What I don't like is the solution you have suggested in patch3.



As I said, that was easy fit into existing implementation. :)
f_sdh30 already does something similar.

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


Re: [RFC 2/3] mmc: sdhci: add host_ops->voltage_switch callback for all other voltages

2015-09-14 Thread Vaibhav Hiremath



On Monday 14 September 2015 03:00 PM, Ulf Hansson wrote:

[...]



Could this be implemented by regulator API? From patch set 3/3, the
pxa1928
voltage_switch hook is to operate the IO pad registers, this seems not
belong
to the SDHC IP core.



Not quite sure whether regulator would be right fit for this.



  From the patche[3/3], this can be achieved by abstracting the IO PAD as
regulators
then, we may not need to touch the core sdhci.c. But I'm not sure whether
this
is the good solution or not.



Exactly...


sdhci Maintainers and experts may have better
suggestions.



Thats is the reason I stamped it as a RFC :)



[...]

 From an mmc core perspective it would be preferred if you implement
this as a regulator (vqmmc).

Especially since we will soon have an API for how to set the I/O
voltages - and the intelligence within that API is not something we
would like to implement for each and every host driver.
https://lkml.org/lkml/2015/8/31/367




I would still consider this as a regulator specific and may not address
the IO configuration within the SoC which are module specific.
The API regulator_set_voltage_triplet() will not have intelligence to
differentiate whether the call is coming from MMC or somewhere else.

Note that, the IO pad voltage configuration which I am referring to is
MMC specific and applicable only when pad is configured in MMC mode. So
technically it is not simply common pad voltage configuration.


And I am still not sure regulator framework would be right fit for
this. Pinctrl would have been right fit, but...since I saw f_sdh30
driver is already doing this, which is easy fit; so adopted the same.

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


Re: [PATCH-v5 RESEND 3/5] i2c: pxa: Add support for pxa910/988 & new configuration features

2015-09-13 Thread Vaibhav Hiremath



On Saturday 12 September 2015 12:36 AM, Wolfram Sang wrote:

On Mon, Aug 24, 2015 at 11:29:36AM +0530, Vaibhav Hiremath wrote:

TWSI_ILCR & TWSI_IWCR registers are used to adjust clock rate
of standard & fast mode in pxa910/988; so this patch adds these two new
entries to "struct pxa_reg_layout" and "struct pxa_i2c".

As discussed in the previous patch-series, the idea here is to add standard
DT properties for ilcr and iwcr configuration fields.
In case of Master ilcr is used for low/high time and in case of slave mode
of operation iwcr is used for setup/hold time.


I need to rethink how to describe i2c bus timing parameters in DT in the
next days. But this is planned for 4.4., promised.

One thing I already wonder about this one...


  static const struct platform_device_id i2c_pxa_id_table[] = {
{ "pxa2xx-i2c",   REGS_PXA2XX },
{ "pxa3xx-pwri2c",REGS_PXA3XX },
{ "ce4100-i2c",   REGS_CE4100 },
+   { "pxa910-i2c",   REGS_PXA910 },
{ },


You add a new platform_id...


@@ -1135,7 +1170,7 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = 
{
  static const struct of_device_id i2c_pxa_dt_ids[] = {
{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
-   { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
+   { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
{}


...but change the compatible binding instead of adding a new one?



Yes, because the offset for both REGS_PXA2XX and REGS_PXA910 are same,
and for REGS_PXA2XX we already have compatible entry "mrvl,pxa-i2c".
And the i2c binding documentation, which says,
for platforms using REGS_PXA2XX, they need to provide additional node
"mrvl,pxa-i2c". Which is confusing :)

Also, when I did git-blame on the driver file to see why "mmp-twsi"
entry has been added without anyone really using it. But I did not find
anything meaningful.
So, from the code it was very clear that, "mmp-twsi" and "pxa-i2c" both
are same, its the code which I am adding here brings difference between 
them.


I tried to find datasheet for the platforms using "mmp-twsi", but was
unlucky.


Thanks,
Vaibhav




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


Re: [PATCH-v5 RESEND 2/5] i2c: pxa: enable/disable i2c module across msg xfer

2015-09-13 Thread Vaibhav Hiremath



On Saturday 12 September 2015 12:23 AM, Wolfram Sang wrote:

On Mon, Aug 24, 2015 at 11:29:35AM +0530, Vaibhav Hiremath wrote:

From: Yi Zhang 

Enable i2c module/unit before transmission and disable when it
finishes.

why?
It's because the i2c bus may be disturbed if the slave device,
typically a touch, powers on.


I am not convinced, "may disturb" is too weak for me. It would need a
way more detailed description of the problem which makes clear that
this mechanism is the only way to go forward.



Hmm, Ok.
Not sure what else I can bring up here.


Can't you use Runtime PM for that?



I haven't tried it though, I can give a try and check.

Thanks,
Vaibhav

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


Re: [PATCH-v2 2/7] mmc: sdhci-pxav3: binding: Add pxa1928 compatible support

2015-09-09 Thread Vaibhav Hiremath



On Wednesday 09 September 2015 05:19 AM, Rob Herring wrote:

On 09/07/2015 06:18 AM, Vaibhav Hiremath wrote:

With support for pxa1928 family of devices , this patch
updates the binding document with compatible property
of "marvell,pxav3-1928-sdhci".

Signed-off-by: Vaibhav Hiremath 
---
  Documentation/devicetree/bindings/mmc/sdhci-pxa.txt | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt 
b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
index 3d1b449..29edcf5 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
@@ -5,7 +5,7 @@ and the properties used by the sdhci-pxav2 and sdhci-pxav3 
drivers.

  Required properties:
  - compatible: Should be "mrvl,pxav2-mmc", "mrvl,pxav3-mmc" or
-  "marvell,armada-380-sdhci".
+  "marvell,armada-380-sdhci" or "marvell,pxav3-1928-sdhci".


v3 is implied by pxa1928. So I'd just do "marvell,pxa1928-sdhci" to
better match the chip name.



Ok, No issues.

I followed the existing "armada-380-sdhci" naming style.
Will correct it in next version.


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


Re: [PATCH-v2 4/7] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-08 Thread Vaibhav Hiremath



On Tuesday 08 September 2015 08:12 PM, Linus Walleij wrote:

On Mon, Sep 7, 2015 at 1:18 PM, Vaibhav Hiremath
 wrote:


Different bus clock may need different pin setting.
For example, fast bus clock like 208Mhz need pin drive fast
while slow bus clock prefer pin drive slow to guarantee
signal quality.

So this patch creates two states,
   - Default (slow/normal) pin state
   - And fast pin state for higher freq bus speed.

And selection of pin state is done based on timing mode.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 

(...)

+   pxa->pinctrl = devm_pinctrl_get(dev);
+   if (!IS_ERR(pxa->pinctrl)) {
+   pxa->pins_default = pinctrl_lookup_state(pxa->pinctrl, 
"default");
+   if (IS_ERR(pxa->pins_default))
+   dev_err(dev, "could not get default pinstate\n");
+   pxa->pins_fast = pinctrl_lookup_state(pxa->pinctrl, "fast");
+   if (IS_ERR(pxa->pins_fast))
+   dev_info(dev, "could not get fast pinstate\n");
+   }


This is exactly how I think it should be used from a pin control
point of view.

If you depended on CONFIG_PM you could use
pinctrl_pm_select_default_state() but for this simple scenario
this is fine.

Reviewed-by: Linus Walleij 
 From a pinctrl point of view.




Thanks for your review.

Linus,

I agree this is how it should be used.
But I still have one small doubt on expectation from
devm_pinctrl_get() function.


If pinctrl properties are not populated in Devicetree node,
then, shouldn't devm_pinctrl_get() return error ?
I followed the code flow, and it seems even if pinctrl properties are
not populated in DT node, the devm_pinctrl_get() returns valid
pointer to "struct pinctrl", isn't this against the expectation of the
call?


Code flow -

devm_pinctrl_get()
...
--> creat_pinctrl()
--> pinctrl_dt_to_map()
...



pinctrl_dt_to_map() iterates for pinctrl-x (x = 0,1,...) and if it
founds the entry then it parses the node. If it doesn't find any
pinctrl property then also it returns 0. and subsequently rreturns
handle to "struct pinctrl" for the device. Why is so?


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


Re: [PATCH-v2 4/7] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-08 Thread Vaibhav Hiremath



On Tuesday 08 September 2015 03:34 PM, Jisheng Zhang wrote:

On Tue, 8 Sep 2015 15:32:34 +0530
Vaibhav Hiremath  wrote:




On Tuesday 08 September 2015 03:22 PM, Jisheng Zhang wrote:

On Tue, 8 Sep 2015 15:04:41 +0530
Vaibhav Hiremath  wrote:






static const struct sdhci_ops pxav3_sdhci_ops = {
@@ -586,6 +619,16 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
}
}

+   pxa->pinctrl = devm_pinctrl_get(dev);


could we ignore this for those SDHCI hosts that don't need it?



Again, no need to introduce flags here. This is standard call and
handled properly. So for the platforms not using this, it really should
not matter.
Also, lookup is getting executed only when pinctrl is populated.

So I do not see any need here.


+   if (!IS_ERR(pxa->pinctrl)) {
+   pxa->pins_default = pinctrl_lookup_state(pxa->pinctrl, 
"default");
+   if (IS_ERR(pxa->pins_default))
+   dev_err(dev, "could not get default pinstate\n");


Why those SDHCI hosts that don't need pinctl setting should got this error?



It won't.


It does. On Marvell Berlin SoCs, I got

[1.07] sdhci-pxav3 f7ab0800.sdhci: could not get default pinstate
[1.08] sdhci-pxav3 f7ab0800.sdhci: could not get fast pinstate





If Host does not need pinctrl, the execution would never reach this
point.
The if condition check would handle it, isn't it?

pxa->pinctrl = devm_pinctrl_get(dev);


It seems this function always succeed...



Not always.
I would succeed only if you have pinctrl defined in DT for this device.


Yes, that's what I thought, but I got

[1.07] sdhci-pxav3 f7ab0800.sdhci: could not get default pinstate
[1.08] sdhci-pxav3 f7ab0800.sdhci: could not get fast pinstate

there's no pinctrl for f7ab0800.sdhci. Am I missing somthing?

Thanks,
Jisheng



And if you have pinctrl defined, isn't it is expected to have "default"
pin state to be always present?
And if answer is yes here, then it is fair to be prompting error for it.


  From another side, we may have default pin in dts, for example: pin muxed 
between
emmc and nandflash. But we don't have fast pinstate, so we at least need the
flag to fast pinstate. Otherwise, in such platforms, we could get something like



That is exactly the reason behind keeping it as dev_info.


[1.00] sdhci-pxav3 f7ab.sdhci: get default pinstate
[1.00] sdhci-pxav3 f7ab.sdhci: could not get fast pinstate




I did some invastigation here on the execution flow,
and you know what, you are right here.

It seems, devm_pinctrl_get() always returns valid pinctrl pointer, even
though the DT property is not populated.

The return value from I did some invastigation () should have been 
treated differently, but it is not. Instead it creates the

"struct pinctrl" and return back to the driver.

I am looping Linus Walleji here, probably he can comment/confirm on
this.


Thanks,
Vaibhav



Thanks,
Vaibhav



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


Re: [PATCH-v2 4/7] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-08 Thread Vaibhav Hiremath



On Tuesday 08 September 2015 03:22 PM, Jisheng Zhang wrote:

On Tue, 8 Sep 2015 15:04:41 +0530
Vaibhav Hiremath  wrote:




On Tuesday 08 September 2015 12:22 PM, Jisheng Zhang wrote:

On Mon, 7 Sep 2015 16:48:38 +0530
Vaibhav Hiremath  wrote:


Different bus clock may need different pin setting.
For example, fast bus clock like 208Mhz need pin drive fast
while slow bus clock prefer pin drive slow to guarantee
signal quality.

So this patch creates two states,
- Default (slow/normal) pin state
- And fast pin state for higher freq bus speed.

And selection of pin state is done based on timing mode.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 
---
   drivers/mmc/host/sdhci-pxav3.c | 45 
+-
   1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index c2b2b78..d933f75 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -35,6 +35,7 @@
   #include 
   #include 
   #include 
+#include 

   #include "sdhci.h"
   #include "sdhci-pltfm.h"
@@ -92,6 +93,10 @@ struct sdhci_pxa {
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
struct sdhci_pxa_data *data;
+
+   struct pinctrl *pinctrl;
+   struct pinctrl_state *pins_default;
+   struct pinctrl_state *pins_fast;
   };

   static struct sdhci_pxa_data pxav3_data_v1 = {
@@ -298,6 +303,33 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host 
*host, u8 power_mode)
pxa->power_mode = power_mode;
   }

+static int pxav3_select_pinstate(struct sdhci_host *host, unsigned int uhs)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+   struct pinctrl_state *pinctrl;
+
+   if (IS_ERR(pxa->pinctrl) ||
+   IS_ERR(pxa->pins_default) ||
+   IS_ERR(pxa->pins_fast))
+   return -EINVAL;
+
+   switch (uhs) {
+   case MMC_TIMING_UHS_SDR50:
+   case MMC_TIMING_UHS_SDR104:
+   case MMC_TIMING_MMC_HS200:
+   case MMC_TIMING_MMC_HS400:
+   pinctrl = pxa->pins_fast;
+   break;
+   default:
+   /* back to default state for other legacy timing */
+   pinctrl = pxa->pins_default;
+   break;
+   }
+
+   return pinctrl_select_state(pxa->pinctrl, pinctrl);
+}
+
   static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int 
uhs)
   {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -353,6 +385,8 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
dev_dbg(mmc_dev(host->mmc),
"%s uhs = %d, ctrl_2 = %04X\n",
__func__, uhs, ctrl_2);
+
+   pxav3_select_pinstate(host, uhs);


return pxav3_select_pinstate(host, uhs);?



Its void function, so don't need it.


Can you please have a look at the function?

static int pxav3_select_pinstate(struct sdhci_host *host, unsigned int uhs)



I was referring to pxav3_set_uhs_signaling().
It is void, so what you are suggesting would generate warning.




And could we ignore this call for those SDHCI hosts that don't need it?



I do not want to introduce flags here.
And also, it is already ignored for those who don't need it.

The first thing in the function pxav3_select_pinstate() is


if (IS_ERR(pxa->pinctrl) ||
IS_ERR(pxa->pins_default) ||
IS_ERR(pxa->pins_fast))
return -EINVAL;


So its already handled.


   }

   static void pxav3_voltage_switch(struct sdhci_host *host,
@@ -416,7 +450,6 @@ static void pxav3_set_clock(struct sdhci_host *host, 
unsigned int clock)
/* TX internal clock selection */
pxav3_set_tx_clock(host);
}
-


why not fix this in patch 3?



Oops. it got missed from my eyes :)
Will fix in next version.


   }

   static const struct sdhci_ops pxav3_sdhci_ops = {
@@ -586,6 +619,16 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
}
}

+   pxa->pinctrl = devm_pinctrl_get(dev);


could we ignore this for those SDHCI hosts that don't need it?



Again, no need to introduce flags here. This is standard call and
handled properly. So for the platforms not using this, it really should
not matter.
Also, lookup is getting executed only when pinctrl is populated.

So I do not see any need here.


+   if (!IS_ERR(pxa->pinctrl)) {
+   pxa->pins_default = pinctrl_lookup_state(pxa->pinctrl, 
"default");
+   if (IS_ERR(pxa->pins_default))
+   dev_err(dev, "could not get default pinstate\n");


Why those SDHCI hosts that don't need pinctl setting should got this error?



It won't.


It does. On Marvell Berlin SoCs, I got

[   

Re: [PATCH-v2 4/7] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-08 Thread Vaibhav Hiremath



On Tuesday 08 September 2015 12:24 PM, Jisheng Zhang wrote:

On Mon, 7 Sep 2015 16:48:38 +0530
Vaibhav Hiremath  wrote:


Different bus clock may need different pin setting.
For example, fast bus clock like 208Mhz need pin drive fast
while slow bus clock prefer pin drive slow to guarantee
signal quality.

So this patch creates two states,
   - Default (slow/normal) pin state
   - And fast pin state for higher freq bus speed.

And selection of pin state is done based on timing mode.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 
---
  drivers/mmc/host/sdhci-pxav3.c | 45 +-
  1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index c2b2b78..d933f75 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -35,6 +35,7 @@
  #include 
  #include 
  #include 
+#include 

  #include "sdhci.h"
  #include "sdhci-pltfm.h"
@@ -92,6 +93,10 @@ struct sdhci_pxa {
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
struct sdhci_pxa_data *data;
+
+   struct pinctrl *pinctrl;
+   struct pinctrl_state *pins_default;
+   struct pinctrl_state *pins_fast;
  };

  static struct sdhci_pxa_data pxav3_data_v1 = {
@@ -298,6 +303,33 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host 
*host, u8 power_mode)
pxa->power_mode = power_mode;
  }

+static int pxav3_select_pinstate(struct sdhci_host *host, unsigned int uhs)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+   struct pinctrl_state *pinctrl;
+
+   if (IS_ERR(pxa->pinctrl) ||
+   IS_ERR(pxa->pins_default) ||
+   IS_ERR(pxa->pins_fast))
+   return -EINVAL;
+
+   switch (uhs) {
+   case MMC_TIMING_UHS_SDR50:
+   case MMC_TIMING_UHS_SDR104:
+   case MMC_TIMING_MMC_HS200:
+   case MMC_TIMING_MMC_HS400:


Are you sure this IP can support HS400?


+   pinctrl = pxa->pins_fast;



No it does not.

The reason I put it here is,
code under discussion is related to pinctrl configuration, so for all
higher bus speed mode we want to set pins into fast mode.

And from hs400 perspective, I would expect it must get handled much
before than this stage and should not reach here at all.

So this portion of the code is complete in itself.

I hope I clarified your doubt.

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


Re: [PATCH-v2 5/7] mmc: sdhci-pxav3: Fix HS200 mode support

2015-09-08 Thread Vaibhav Hiremath



On Tuesday 08 September 2015 12:23 PM, Jisheng Zhang wrote:

On Mon, 7 Sep 2015 16:48:39 +0530
Vaibhav Hiremath  wrote:


From: Kevin Liu 

IN case of MMC HS200 mode, current code does not enable
SD_CE_ATA_2.MMC_HS200 & SD_CE_ATA_2.MMC_CARD bit configurations.

So this patch updates the above bit fields correctly.

Signed-off-by: Tim Wang 
Signed-off-by: Kevin Liu 
Signed-off-by: Vaibhav Hiremath 
---
Note: Unfortunately I do not have access to any other datasheets
which uses sdhci-pxav3 driver, so quite not sure whether this would
break any existing platform, probably NOT, as I do not see any
references for this change.
If anyone can confirm that would be really great.

  drivers/mmc/host/sdhci-pxav3.c | 17 +
  1 file changed, 17 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index d933f75..6978810 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -57,6 +57,8 @@
  #define SD_CE_ATA_1   0x10C

  #define SD_CE_ATA_2   0x10E
+#define  SD_CE_ATA2_HS200_EN   BIT(10)
+#define  SD_CE_ATA2_MMC_MODE   BIT(12)
  #define  SDCE_MISC_INTBIT(2)
  #define  SDCE_MISC_INT_EN BIT(1)

@@ -330,6 +332,17 @@ static int pxav3_select_pinstate(struct sdhci_host *host, 
unsigned int uhs)
return pinctrl_select_state(pxa->pinctrl, pinctrl);
  }

+static int pxav3_select_hs200(struct sdhci_host *host)


I didn't see why we need the return value, make it void would be better?



Fair enough.
Will fix it in next version.


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


Re: [PATCH-v2 4/7] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-08 Thread Vaibhav Hiremath



On Tuesday 08 September 2015 12:22 PM, Jisheng Zhang wrote:

On Mon, 7 Sep 2015 16:48:38 +0530
Vaibhav Hiremath  wrote:


Different bus clock may need different pin setting.
For example, fast bus clock like 208Mhz need pin drive fast
while slow bus clock prefer pin drive slow to guarantee
signal quality.

So this patch creates two states,
   - Default (slow/normal) pin state
   - And fast pin state for higher freq bus speed.

And selection of pin state is done based on timing mode.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 
---
  drivers/mmc/host/sdhci-pxav3.c | 45 +-
  1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index c2b2b78..d933f75 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -35,6 +35,7 @@
  #include 
  #include 
  #include 
+#include 

  #include "sdhci.h"
  #include "sdhci-pltfm.h"
@@ -92,6 +93,10 @@ struct sdhci_pxa {
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
struct sdhci_pxa_data *data;
+
+   struct pinctrl *pinctrl;
+   struct pinctrl_state *pins_default;
+   struct pinctrl_state *pins_fast;
  };

  static struct sdhci_pxa_data pxav3_data_v1 = {
@@ -298,6 +303,33 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host 
*host, u8 power_mode)
pxa->power_mode = power_mode;
  }

+static int pxav3_select_pinstate(struct sdhci_host *host, unsigned int uhs)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+   struct pinctrl_state *pinctrl;
+
+   if (IS_ERR(pxa->pinctrl) ||
+   IS_ERR(pxa->pins_default) ||
+   IS_ERR(pxa->pins_fast))
+   return -EINVAL;
+
+   switch (uhs) {
+   case MMC_TIMING_UHS_SDR50:
+   case MMC_TIMING_UHS_SDR104:
+   case MMC_TIMING_MMC_HS200:
+   case MMC_TIMING_MMC_HS400:
+   pinctrl = pxa->pins_fast;
+   break;
+   default:
+   /* back to default state for other legacy timing */
+   pinctrl = pxa->pins_default;
+   break;
+   }
+
+   return pinctrl_select_state(pxa->pinctrl, pinctrl);
+}
+
  static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
  {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -353,6 +385,8 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
dev_dbg(mmc_dev(host->mmc),
"%s uhs = %d, ctrl_2 = %04X\n",
__func__, uhs, ctrl_2);
+
+   pxav3_select_pinstate(host, uhs);


return pxav3_select_pinstate(host, uhs);?



Its void function, so don't need it.


And could we ignore this call for those SDHCI hosts that don't need it?



I do not want to introduce flags here.
And also, it is already ignored for those who don't need it.

The first thing in the function pxav3_select_pinstate() is


if (IS_ERR(pxa->pinctrl) ||
IS_ERR(pxa->pins_default) ||
IS_ERR(pxa->pins_fast))
return -EINVAL;


So its already handled.


  }

  static void pxav3_voltage_switch(struct sdhci_host *host,
@@ -416,7 +450,6 @@ static void pxav3_set_clock(struct sdhci_host *host, 
unsigned int clock)
/* TX internal clock selection */
pxav3_set_tx_clock(host);
}
-


why not fix this in patch 3?



Oops. it got missed from my eyes :)
Will fix in next version.


  }

  static const struct sdhci_ops pxav3_sdhci_ops = {
@@ -586,6 +619,16 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
}
}

+   pxa->pinctrl = devm_pinctrl_get(dev);


could we ignore this for those SDHCI hosts that don't need it?



Again, no need to introduce flags here. This is standard call and
handled properly. So for the platforms not using this, it really should
not matter.
Also, lookup is getting executed only when pinctrl is populated.

So I do not see any need here.


+   if (!IS_ERR(pxa->pinctrl)) {
+   pxa->pins_default = pinctrl_lookup_state(pxa->pinctrl, 
"default");
+   if (IS_ERR(pxa->pins_default))
+   dev_err(dev, "could not get default pinstate\n");


Why those SDHCI hosts that don't need pinctl setting should got this error?



It won't.

If Host does not need pinctrl, the execution would never reach this
point.
The if condition check would handle it, isn't it?

pxa->pinctrl = devm_pinctrl_get(dev);
if (!IS_ERR(pxa->pinctrl)) {

...

}

So I do not see why is it issue here?


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


Re: [PATCH-v2 1/3] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-07 Thread Vaibhav Hiremath



On Monday 07 September 2015 05:26 PM, Jisheng Zhang wrote:

On Mon, 7 Sep 2015 17:01:09 +0530
Vaibhav Hiremath  wrote:


There were some coding style issues where spaces have been used instead
of tabs, for example, in macro definitions, alignment of function
declarations/definitions, etc...

This patch fixes all such occurrences in the code.

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mmc/host/sdhci-pxav3.c | 46 +-
  1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 946d37f..7a07177 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -39,24 +39,24 @@
  #include "sdhci.h"
  #include "sdhci-pltfm.h"

-#define PXAV3_RPM_DELAY_MS 50
+#define PXAV3_RPM_DELAY_MS 50

-#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
-#define SDCLK_SEL  0x100
-#define SDCLK_DELAY_SHIFT  9
-#define SDCLK_DELAY_MASK   0x1f
+#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
+#define SDCLK_SEL  0x100
+#define  SDCLK_DELAY_SHIFT 9
+#define  SDCLK_DELAY_MASK  0x1f

-#define SD_CFG_FIFO_PARAM   0x100
-#define SDCFG_GEN_PAD_CLK_ON   (1<<6)
-#define SDCFG_GEN_PAD_CLK_CNT_MASK 0xFF
-#define SDCFG_GEN_PAD_CLK_CNT_SHIFT24
+#define SD_CFG_FIFO_PARAM  0x100
+#define  SDCFG_GEN_PAD_CLK_ON  (1<<6)
+#define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
+#define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24

-#define SD_SPI_MODE  0x108
-#define SD_CE_ATA_1  0x10C
+#define SD_SPI_MODE0x108
+#define SD_CE_ATA_10x10C

-#define SD_CE_ATA_2  0x10E
-#define SDCE_MISC_INT  (1<<2)
-#define SDCE_MISC_INT_EN   (1<<1)
+#define SD_CE_ATA_20x10E
+#define  SDCE_MISC_INT (1<<2)
+#define  SDCE_MISC_INT_EN  (1<<1)

  struct sdhci_pxa {
struct clk *clk_core;
@@ -284,7 +284,7 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 * FE-2946959
 */
if (pxa->sdio3_conf_reg) {
-   u8 reg_val  = readb(pxa->sdio3_conf_reg);
+   u8 reg_val = readb(pxa->sdio3_conf_reg);

if (uhs == MMC_TIMING_UHS_SDR50 ||
uhs == MMC_TIMING_UHS_DDR50) {
@@ -304,20 +304,20 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
  }

  static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock = sdhci_set_clock,
-   .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
-   .get_max_clock = sdhci_pltfm_clk_get_max_clock,
-   .set_bus_width = sdhci_set_bus_width,
-   .reset = pxav3_reset,
-   .set_uhs_signaling = pxav3_set_uhs_signaling,
+   .set_clock  = sdhci_set_clock,
+   .platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
+   .get_max_clock  = sdhci_pltfm_clk_get_max_clock,
+   .set_bus_width  = sdhci_set_bus_width,
+   .reset  = pxav3_reset,
+   .set_uhs_signaling  = pxav3_set_uhs_signaling,


IMHO, this is not an improvement, previous style is fine and I saw
such style in kernel here and there



I had received feedback to use above style on different patch-series.
And I also think this looks more clean and readable.

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


[PATCH-v2 3/3] mmc: sdhci: print notice on -EPROBE_DEFER in sdhci_add_host() fn

2015-09-07 Thread Vaibhav Hiremath
This patch adds kernel notice/message to sdhci_host_add() fn on
-EPROBE_DEFER.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1dbe932..37a5cd5 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3130,8 +3130,11 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->caps |= MMC_CAP_NEEDS_POLL;
 
/* If there are external regulators, get them */
-   if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER)
+   if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER) {
+   pr_notice("%s: regulator supply unavailable, deferring 
probe.\n",
+   mmc_hostname(mmc));
return -EPROBE_DEFER;
+   }
 
/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
if (!IS_ERR(mmc->supply.vqmmc)) {
-- 
1.9.1

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


[PATCH-v2 1/3] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-07 Thread Vaibhav Hiremath
There were some coding style issues where spaces have been used instead
of tabs, for example, in macro definitions, alignment of function
declarations/definitions, etc...

This patch fixes all such occurrences in the code.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 46 +-
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 946d37f..7a07177 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -39,24 +39,24 @@
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
 
-#define PXAV3_RPM_DELAY_MS 50
+#define PXAV3_RPM_DELAY_MS 50
 
-#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
-#define SDCLK_SEL  0x100
-#define SDCLK_DELAY_SHIFT  9
-#define SDCLK_DELAY_MASK   0x1f
+#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
+#define SDCLK_SEL  0x100
+#define  SDCLK_DELAY_SHIFT 9
+#define  SDCLK_DELAY_MASK  0x1f
 
-#define SD_CFG_FIFO_PARAM   0x100
-#define SDCFG_GEN_PAD_CLK_ON   (1<<6)
-#define SDCFG_GEN_PAD_CLK_CNT_MASK 0xFF
-#define SDCFG_GEN_PAD_CLK_CNT_SHIFT24
+#define SD_CFG_FIFO_PARAM  0x100
+#define  SDCFG_GEN_PAD_CLK_ON  (1<<6)
+#define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
+#define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24
 
-#define SD_SPI_MODE  0x108
-#define SD_CE_ATA_1  0x10C
+#define SD_SPI_MODE0x108
+#define SD_CE_ATA_10x10C
 
-#define SD_CE_ATA_2  0x10E
-#define SDCE_MISC_INT  (1<<2)
-#define SDCE_MISC_INT_EN   (1<<1)
+#define SD_CE_ATA_20x10E
+#define  SDCE_MISC_INT (1<<2)
+#define  SDCE_MISC_INT_EN  (1<<1)
 
 struct sdhci_pxa {
struct clk *clk_core;
@@ -284,7 +284,7 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 * FE-2946959
 */
if (pxa->sdio3_conf_reg) {
-   u8 reg_val  = readb(pxa->sdio3_conf_reg);
+   u8 reg_val = readb(pxa->sdio3_conf_reg);
 
if (uhs == MMC_TIMING_UHS_SDR50 ||
uhs == MMC_TIMING_UHS_DDR50) {
@@ -304,20 +304,20 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock = sdhci_set_clock,
-   .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
-   .get_max_clock = sdhci_pltfm_clk_get_max_clock,
-   .set_bus_width = sdhci_set_bus_width,
-   .reset = pxav3_reset,
-   .set_uhs_signaling = pxav3_set_uhs_signaling,
+   .set_clock  = sdhci_set_clock,
+   .platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
+   .get_max_clock  = sdhci_pltfm_clk_get_max_clock,
+   .set_bus_width  = sdhci_set_bus_width,
+   .reset  = pxav3_reset,
+   .set_uhs_signaling  = pxav3_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
-   .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
+   .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
| SDHCI_QUIRK_32BIT_ADMA_SIZE
| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
-   .ops = &pxav3_sdhci_ops,
+   .ops= &pxav3_sdhci_ops,
 };
 
 #ifdef CONFIG_OF
-- 
1.9.1

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


[PATCH-v2 0/3] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-07 Thread Vaibhav Hiremath
Trivial patch-series, which fixes the tabbing issue in the driver,
uses the BIT macro for bit fields and prints notice on -EPROBE_DEFER
in sdhci_add_host() function on regulator unavailability.

V1 => V2

 - Fixed all comments from Joe, mostly alignment changes
 - Separated BIT macro usage patch into new one.
 - changed error to kernel notice for EPROBE_DEFER in sdhci_add_host()

Note: This patch-series should get merged before another series -

[PATCH-v2 0/7] mmc: sdhci-pxav3: Enable support for PXA1928 SDCHI controller

Vaibhav Hiremath (3):
  mmc: sdhci-pxav3: Fix tabbing issue
  mmc: sdhci-pxav3: Use BIT macro for bit field definitions
  mmc: sdhci: print notice on -EPROBE_DEFER in sdhci_add_host() fn

 drivers/mmc/host/sdhci-pxav3.c | 46 +-
 drivers/mmc/host/sdhci.c   |  5 -
 2 files changed, 27 insertions(+), 24 deletions(-)

-- 
1.9.1

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


[PATCH-v2 2/3] mmc: sdhci-pxav3: Use BIT macro for bit field definitions

2015-09-07 Thread Vaibhav Hiremath
Instead of using shift operation use BIT macro for bit field
definitions.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 7a07177..a8a8c94 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -47,7 +47,7 @@
 #define  SDCLK_DELAY_MASK  0x1f
 
 #define SD_CFG_FIFO_PARAM  0x100
-#define  SDCFG_GEN_PAD_CLK_ON  (1<<6)
+#define  SDCFG_GEN_PAD_CLK_ON  BIT(6)
 #define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
 #define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24
 
@@ -55,8 +55,8 @@
 #define SD_CE_ATA_10x10C
 
 #define SD_CE_ATA_20x10E
-#define  SDCE_MISC_INT (1<<2)
-#define  SDCE_MISC_INT_EN  (1<<1)
+#define  SDCE_MISC_INT BIT(2)
+#define  SDCE_MISC_INT_EN  BIT(1)
 
 struct sdhci_pxa {
struct clk *clk_core;
-- 
1.9.1

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


[PATCH-v2 1/7] mmc: sdhci-pxav3: Enable pxa1928 device support

2015-09-07 Thread Vaibhav Hiremath
SDHCI controller present in PXA1928 has few differences as far as
register map is concerned.
For example,

 PXAxxxPXA1928
 =====
 SDCLK_DELAY field   0x10A 0x114
 SDCLK_DELAY mask0x1F  0x3FF
 SDCLK_DELAY shift9  8
 SDCLK_SEL shift  8  2 (SEL1)

So in order to support multi-platform, use sdhci_pxa_regdata structure
as a variant data according to platform.

Note that, there are some more differences, which would be added
as and when respective feature gets added to the driver.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 62 ++
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 6d4bad4..aecae04 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -42,9 +42,6 @@
 #define PXAV3_RPM_DELAY_MS 50
 
 #define SD_CLOCK_BURST_SIZE_SETUP  0x10A
-#define SDCLK_SEL  0x100
-#define  SDCLK_DELAY_SHIFT 9
-#define  SDCLK_DELAY_MASK  0x1f
 
 #define SD_CFG_FIFO_PARAM  0x100
 #define  SDCFG_GEN_PAD_CLK_ON  BIT(6)
@@ -58,11 +55,25 @@
 #define  SDCE_MISC_INT BIT(2)
 #define  SDCE_MISC_INT_EN  BIT(1)
 
+#define SD_RX_CFG_REG  0x114
+
 /* IO Power control */
 #define IO_PWR_AKEY_ASFAR  0xbaba
 #define IO_PWR_AKEY_ASSAR  0xeb10
 #define IO_PWR_MMC1_PAD_1V8BIT(2)
 
+struct sdhci_pxa_data {
+   u32 sdclk_delay_reg;
+   u32 sdclk_delay_mask;
+   u8 sdclk_delay_shift;
+   u8 sdclk_sel_mask;
+   u8 sdclk_sel_shift;
+   /*
+* We have few more differences, add them along with their
+* respective feature support
+*/
+};
+
 struct sdhci_pxa {
struct clk *clk_core;
struct clk *clk_io;
@@ -70,6 +81,24 @@ struct sdhci_pxa {
void __iomem *sdio3_conf_reg;
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
+   struct sdhci_pxa_data *data;
+};
+
+static struct sdhci_pxa_data pxav3_data_v1 = {
+   .sdclk_delay_reg= SD_CLOCK_BURST_SIZE_SETUP,
+   .sdclk_delay_mask   = 0x1F,
+   .sdclk_delay_shift  = 9,
+   .sdclk_sel_mask = 0x1,
+   .sdclk_sel_shift= 8,
+};
+
+static struct sdhci_pxa_data pxav3_data_v2 = {
+   .sdclk_delay_reg= SD_RX_CFG_REG,
+   .sdclk_delay_mask   = 0x3FF,
+   .sdclk_delay_shift  = 8,
+   /* Only set SDCLK_SEL1, as driver uses default value of SDCLK_SEL0 */
+   .sdclk_sel_mask = 0x3,
+   .sdclk_sel_shift= 2,/* SDCLK_SEL1 */
 };
 
 /*
@@ -183,6 +212,8 @@ static void pxav3_reset(struct sdhci_host *host, u8 mask)
 {
struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
 
sdhci_reset(host, mask);
 
@@ -193,12 +224,14 @@ static void pxav3_reset(struct sdhci_host *host, u8 mask)
 */
if (pdata && 0 != pdata->clk_delay_cycles) {
u16 tmp;
-
-   tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
-   tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
-   << SDCLK_DELAY_SHIFT;
-   tmp |= SDCLK_SEL;
-   writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
+   struct sdhci_pxa_data *data = pxa->data;
+
+   tmp = readw(host->ioaddr + data->sdclk_delay_reg);
+   tmp |= (pdata->clk_delay_cycles & 
data->sdclk_delay_mask)
+   << data->sdclk_delay_shift;
+   tmp &= ~(data->sdclk_sel_mask << data->sdclk_sel_shift);
+   tmp |= 1 << data->sdclk_sel_shift;
+   writew(tmp, host->ioaddr + data->sdclk_delay_reg);
}
}
 }
@@ -363,10 +396,16 @@ static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
 #ifdef CONFIG_OF
 static const struct of_device_id sdhci_pxav3_of_match[] = {
{
-   .compatible = "mrvl,pxav3-mmc",
+   .compatible = "mrvl,pxav3-mmc",
+   .data   = (void *)&pxav3_data_v1,
+   },
+   {
+   .compatible = "marvell,armada-380-sdhci",
+   .data   = (void *)&pxav3_data_v1,
},
{
-   .compat

[PATCH-v2 4/7] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-07 Thread Vaibhav Hiremath
Different bus clock may need different pin setting.
For example, fast bus clock like 208Mhz need pin drive fast
while slow bus clock prefer pin drive slow to guarantee
signal quality.

So this patch creates two states,
  - Default (slow/normal) pin state
  - And fast pin state for higher freq bus speed.

And selection of pin state is done based on timing mode.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 
---
 drivers/mmc/host/sdhci-pxav3.c | 45 +-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index c2b2b78..d933f75 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
@@ -92,6 +93,10 @@ struct sdhci_pxa {
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
struct sdhci_pxa_data *data;
+
+   struct pinctrl *pinctrl;
+   struct pinctrl_state *pins_default;
+   struct pinctrl_state *pins_fast;
 };
 
 static struct sdhci_pxa_data pxav3_data_v1 = {
@@ -298,6 +303,33 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host 
*host, u8 power_mode)
pxa->power_mode = power_mode;
 }
 
+static int pxav3_select_pinstate(struct sdhci_host *host, unsigned int uhs)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+   struct pinctrl_state *pinctrl;
+
+   if (IS_ERR(pxa->pinctrl) ||
+   IS_ERR(pxa->pins_default) ||
+   IS_ERR(pxa->pins_fast))
+   return -EINVAL;
+
+   switch (uhs) {
+   case MMC_TIMING_UHS_SDR50:
+   case MMC_TIMING_UHS_SDR104:
+   case MMC_TIMING_MMC_HS200:
+   case MMC_TIMING_MMC_HS400:
+   pinctrl = pxa->pins_fast;
+   break;
+   default:
+   /* back to default state for other legacy timing */
+   pinctrl = pxa->pins_default;
+   break;
+   }
+
+   return pinctrl_select_state(pxa->pinctrl, pinctrl);
+}
+
 static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -353,6 +385,8 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
dev_dbg(mmc_dev(host->mmc),
"%s uhs = %d, ctrl_2 = %04X\n",
__func__, uhs, ctrl_2);
+
+   pxav3_select_pinstate(host, uhs);
 }
 
 static void pxav3_voltage_switch(struct sdhci_host *host,
@@ -416,7 +450,6 @@ static void pxav3_set_clock(struct sdhci_host *host, 
unsigned int clock)
/* TX internal clock selection */
pxav3_set_tx_clock(host);
}
-
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
@@ -586,6 +619,16 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
}
}
 
+   pxa->pinctrl = devm_pinctrl_get(dev);
+   if (!IS_ERR(pxa->pinctrl)) {
+   pxa->pins_default = pinctrl_lookup_state(pxa->pinctrl, 
"default");
+   if (IS_ERR(pxa->pins_default))
+   dev_err(dev, "could not get default pinstate\n");
+   pxa->pins_fast = pinctrl_lookup_state(pxa->pinctrl, "fast");
+   if (IS_ERR(pxa->pins_fast))
+   dev_info(dev, "could not get fast pinstate\n");
+   }
+
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS);
-- 
1.9.1

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


[PATCH-v2 2/7] mmc: sdhci-pxav3: binding: Add pxa1928 compatible support

2015-09-07 Thread Vaibhav Hiremath
With support for pxa1928 family of devices , this patch
updates the binding document with compatible property
of "marvell,pxav3-1928-sdhci".

Signed-off-by: Vaibhav Hiremath 
---
 Documentation/devicetree/bindings/mmc/sdhci-pxa.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt 
b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
index 3d1b449..29edcf5 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-pxa.txt
@@ -5,7 +5,7 @@ and the properties used by the sdhci-pxav2 and sdhci-pxav3 
drivers.
 
 Required properties:
 - compatible: Should be "mrvl,pxav2-mmc", "mrvl,pxav3-mmc" or
-  "marvell,armada-380-sdhci".
+  "marvell,armada-380-sdhci" or "marvell,pxav3-1928-sdhci".
 - reg:
   * for "mrvl,pxav2-mmc" and "mrvl,pxav3-mmc", one register area for
 the SDHCI registers.
-- 
1.9.1

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


[PATCH-v2 6/7] mmc: sdhci: add new quirk for setting BUS_POWER & BUS_VLT fields

2015-09-07 Thread Vaibhav Hiremath
IN case of Marvell 1928 family of devices, the SD_BUS_POWER and
SD_BUS_VLT bits are used internally to gate the clocks, so
we have to set these fields.

Pasting Spec words here,

The  and  fields should be configured
to correct values. These actually do not do the voltage selection
or switch power to the SD card. However these fields are used
internally to gate the clock. So if these fields are set
incorrectly, SD module will not function.

And during my development, I have seen that SD card wouldn't function
without right configuration into these fields.

So this patch adds new quirk (SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER),
which make sure that ->set_power() sets these fields.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pltfm.c | 3 +++
 drivers/mmc/host/sdhci.c   | 3 ++-
 drivers/mmc/host/sdhci.h   | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index a207f5a..5788a8c 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -101,6 +101,9 @@ void sdhci_get_of_property(struct platform_device *pdev)
of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
+   if (of_device_is_compatible(np, "marvell,pxav3-1928-sdhci"))
+   host->quirks2 |= SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER;
+
clk = of_get_property(np, "clock-frequency", &size);
if (clk && size == sizeof(*clk) && *clk)
pltfm_host->clock = be32_to_cpup(clk);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2d58b31..418f381 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1265,7 +1265,8 @@ static void sdhci_set_power(struct sdhci_host *host, 
unsigned char mode,
else
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 
-   return;
+   if (!(host->quirks2 | SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER))
+   return;
}
 
if (mode != MMC_POWER_OFF) {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 9b0e2a8..8802a0c 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -409,6 +409,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_SUPPORT_SINGLE(1<<13)
 /* Controller broken with using ACMD23 */
 #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14)
+/* Voltage capabilities of Controller must be set  */
+#define SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER  (1<<15)
 
int irq;/* Device IRQ */
void __iomem *ioaddr;   /* Mapped address */
-- 
1.9.1

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


[PATCH-v2 5/7] mmc: sdhci-pxav3: Fix HS200 mode support

2015-09-07 Thread Vaibhav Hiremath
From: Kevin Liu 

IN case of MMC HS200 mode, current code does not enable
SD_CE_ATA_2.MMC_HS200 & SD_CE_ATA_2.MMC_CARD bit configurations.

So this patch updates the above bit fields correctly.

Signed-off-by: Tim Wang 
Signed-off-by: Kevin Liu 
Signed-off-by: Vaibhav Hiremath 
---
Note: Unfortunately I do not have access to any other datasheets
which uses sdhci-pxav3 driver, so quite not sure whether this would
break any existing platform, probably NOT, as I do not see any
references for this change.
If anyone can confirm that would be really great.

 drivers/mmc/host/sdhci-pxav3.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index d933f75..6978810 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -57,6 +57,8 @@
 #define SD_CE_ATA_10x10C
 
 #define SD_CE_ATA_20x10E
+#define  SD_CE_ATA2_HS200_EN   BIT(10)
+#define  SD_CE_ATA2_MMC_MODE   BIT(12)
 #define  SDCE_MISC_INT BIT(2)
 #define  SDCE_MISC_INT_EN  BIT(1)
 
@@ -330,6 +332,17 @@ static int pxav3_select_pinstate(struct sdhci_host *host, 
unsigned int uhs)
return pinctrl_select_state(pxa->pinctrl, pinctrl);
 }
 
+static int pxav3_select_hs200(struct sdhci_host *host)
+{
+   u16 reg = 0;
+
+   reg = sdhci_readw(host, SD_CE_ATA_2);
+   reg |= SD_CE_ATA2_HS200_EN | SD_CE_ATA2_MMC_MODE;
+   sdhci_writew(host, reg, SD_CE_ATA_2);
+
+   return 0;
+}
+
 static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -361,6 +374,10 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
case MMC_TIMING_UHS_DDR50:
ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
break;
+   case MMC_TIMING_MMC_HS200:
+   ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
+   pxav3_select_hs200(host);
+   break;
}
 
/*
-- 
1.9.1

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


[PATCH-v2 7/7] mmc: sdhci: enable SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON for pxa1928

2015-09-07 Thread Vaibhav Hiremath
Card power is dependent on bus power, without that card
wouldn't respond (No CARD_INT). So this patch enables the
quirk SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pltfm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index 5788a8c..057190c 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -102,7 +102,8 @@ void sdhci_get_of_property(struct platform_device *pdev)
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
if (of_device_is_compatible(np, "marvell,pxav3-1928-sdhci"))
-   host->quirks2 |= SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER;
+   host->quirks2 |= SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER |
+   SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON;
 
clk = of_get_property(np, "clock-frequency", &size);
if (clk && size == sizeof(*clk) && *clk)
-- 
1.9.1

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


[PATCH-v2 3/7] mmc: sdhci-pxav3: Add platform specific set_clock ops

2015-09-07 Thread Vaibhav Hiremath
In case of PXA1928 & family of devices, the TX BUS and internal clock
need to be set as part of ->set_clock() ops, so this patch adds
platform specific ->set_clock() operation.

Note that, in order to not break other platforms, this patch
introduced the flag, which controls whether controller/platform
specific clock configuration needs to be executed.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 46 +-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index aecae04..c2b2b78 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -48,6 +48,10 @@
 #define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
 #define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24
 
+#define SD_FIFO_PARAM  0x104
+#define  INTERNAL_CLK_GATE_CTRLBIT(8)
+#define  INTERNAL_CLK_GATE_ON  BIT(9)
+
 #define SD_SPI_MODE0x108
 #define SD_CE_ATA_10x10C
 
@@ -57,6 +61,9 @@
 
 #define SD_RX_CFG_REG  0x114
 
+#define TX_CFG_REG 0x118
+#define  TX_INTERNAL_SEL_BUS_CLK   BIT(30)
+
 /* IO Power control */
 #define IO_PWR_AKEY_ASFAR  0xbaba
 #define IO_PWR_AKEY_ASSAR  0xeb10
@@ -68,6 +75,9 @@ struct sdhci_pxa_data {
u8 sdclk_delay_shift;
u8 sdclk_sel_mask;
u8 sdclk_sel_shift;
+
+   /* set this if platform needs separate clock configuration */
+   bool set_pltfrm_clk;
/*
 * We have few more differences, add them along with their
 * respective feature support
@@ -90,6 +100,7 @@ static struct sdhci_pxa_data pxav3_data_v1 = {
.sdclk_delay_shift  = 9,
.sdclk_sel_mask = 0x1,
.sdclk_sel_shift= 8,
+   .set_pltfrm_clk = false,
 };
 
 static struct sdhci_pxa_data pxav3_data_v2 = {
@@ -99,6 +110,7 @@ static struct sdhci_pxa_data pxav3_data_v2 = {
/* Only set SDCLK_SEL1, as driver uses default value of SDCLK_SEL0 */
.sdclk_sel_mask = 0x3,
.sdclk_sel_shift= 2,/* SDCLK_SEL1 */
+   .set_pltfrm_clk = true,
 };
 
 /*
@@ -375,8 +387,40 @@ static void pxav3_voltage_switch(struct sdhci_host *host,
writel(val, pxa->io_pwr_reg);
 }
 
+static void pxav3_set_tx_clock(struct sdhci_host *host)
+{
+   u32 val;
+
+   val = sdhci_readl(host, TX_CFG_REG);
+   val |= TX_INTERNAL_SEL_BUS_CLK;
+   sdhci_writel(host, val, TX_CFG_REG);
+}
+
+static void pxav3_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+
+   /* We still use common sdhci_set_clock() */
+   sdhci_set_clock(host, clock);
+
+   /* platform/controller specific clock configuration */
+   if (pxa->data->set_pltfrm_clk && clock != 0) {
+   u32 val;
+
+   val = sdhci_readw(host, SD_FIFO_PARAM);
+   /* Internal clock gate ON and CTRL = 0b11 */
+   val |= INTERNAL_CLK_GATE_CTRL | INTERNAL_CLK_GATE_ON;
+   sdhci_writew(host, val, SD_FIFO_PARAM);
+
+   /* TX internal clock selection */
+   pxav3_set_tx_clock(host);
+   }
+
+}
+
 static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock  = sdhci_set_clock,
+   .set_clock  = pxav3_set_clock,
.platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
.get_max_clock  = sdhci_pltfm_clk_get_max_clock,
.set_bus_width  = sdhci_set_bus_width,
-- 
1.9.1

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


[PATCH-v2 0/7] mmc: sdhci-pxav3: Enable support for PXA1928 SDCHI controller

2015-09-07 Thread Vaibhav Hiremath
PXA1928 SDHCI controller has few differences, for example,

 PXAxxxPXA1928
 =====
 SDCLK_DELAY field   0x10A 0x114
 SDCLK_DELAY mask0x1F  0x3FF
 SDCLK_DELAY shift9  8
 SDCLK_SEL shift  8  2 (SEL1)

So this patch series introduces new compatible device_id
(marvell,pxav3-1928-sdhci), and makes use of .data for handling
such differences.

The series also adds support like,

 - independent ->set_clock() api, as we need to enable internal clock gate
   and TX clock
 - pinctrl configuration based on bus speed.
 - introduce new quirk SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER
   SD_BUS_POWER & SD_BUS_VLT bit-fields are used internally to gate the
   clocks, so it is important to configure them as part of ->set_power()
   More detailed description is written into commit log.
 - Enable SDHCI_QUIRK_BROKEN_TIMEOUT_VAL for PXA1928 device_id
 - Enable SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON quirk for pxa1928 device


V1 => V2:
=
 - Fixed typo issue (residual change remained by mistake)
 - Added new patch updating DT binding document for pxa1928 support
 - Added new patch enabling CARD_ON_NEEDS_BUS_ON for pxa1928 device

Testing:
I have done basic testing on both eMMC and SD card on PXA1928 based
platform.

Note: I tried to made sure that I do not break any other platform, which
used sdhci, except HS200 configuration.·
Unfortunately I do not have access to any other datasheets, where I can
cross check the details on HS200 bit-fields. Probably someone who has
access can confirm [PATCH 4/5], whether it impacts other platforms.

Kevin Liu (1):
  mmc: sdhci-pxav3: Fix HS200 mode support

Vaibhav Hiremath (6):
  mmc: sdhci-pxav3: Enable pxa1928 device support
  mmc: sdhci-pxav3: binding: Add pxa1928 compatible support
  mmc: sdhci-pxav3: Add platform specific set_clock ops
  mmc: sdhci-pxav3: Add pinctl setting according to bus clock
  mmc: sdhci: add new quirk for setting BUS_POWER & BUS_VLT fields
  mmc: sdhci: enable SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON for pxa1928

 .../devicetree/bindings/mmc/sdhci-pxa.txt  |   2 +-
 drivers/mmc/host/sdhci-pltfm.c |   4 +
 drivers/mmc/host/sdhci-pxav3.c | 168 +++--
 drivers/mmc/host/sdhci.c   |   3 +-
 drivers/mmc/host/sdhci.h   |   2 +
 5 files changed, 165 insertions(+), 14 deletions(-)

-- 
1.9.1

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


Re: [PATCH 0/5] mmc: sdhci-pxav3: Enable support for PXA1928 SDCHI controller

2015-09-07 Thread Vaibhav Hiremath



On Friday 04 September 2015 09:02 PM, Vaibhav Hiremath wrote:

PXA1928 SDHCI controller has few differences, for example,

PXAxxxPXA1928
=====
SDCLK_DELAY field   0x10A 0x114
SDCLK_DELAY mask0x1F  0x3FF
SDCLK_DELAY shift9  8
SDCLK_SEL shift  8  2 (SEL1)

So this patch series introduces new compatible device_id
(marvell,pxav3-1928-sdhci), and makes use of .data for handling
such differences.

The series also adds support like,

  - independent ->set_clock() api, as we need to enable internal clock gate
 and TX clock
  - pinctrl configuration based on bus speed.
  - introduce new quirk SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER
SD_BUS_POWER & SD_BUS_VLT bit-fields are used internally to gate the
clocks, so it is important to configure them as part of ->set_power()
More detailed description is written into commit log.
  - Enable SDHCI_QUIRK_BROKEN_TIMEOUT_VAL for PXA1928 device_id



Please ignore this series, as one residual change (rather typo error).
Mistakenly while checking in the code, instead of 1928 compatible
property it was 988.

I will submit the new series shortly.

Thanks,
Vaibhav




Testing:
I have done basic testing on both eMMC and SD card on PXA1928 based
platform.

Note: I tried to made sure that I do not break any other platform, which
used sdhci, except HS200 configuration.
Unfortunately I do not have access to any other datasheets, where I can
cross check the details on HS200 bit-fields. Probably someone who has
access can confirm [PATCH 4/5], whether it impacts other platforms.

Kevin Liu (1):
   mmc: sdhci-pxav3: Fix HS200 mode support

Vaibhav Hiremath (4):
   mmc: sdhci-pxav3: Enable pxa1928 device support
   mmc: sdhci-pxav3: Add platform specific set_clock ops
   mmc: sdhci-pxav3: Add pinctl setting according to bus clock
   mmc: sdhci: add new quirk for setting BUS_POWER & BUS_VLT fields

  drivers/mmc/host/sdhci-pltfm.c |   3 +
  drivers/mmc/host/sdhci-pxav3.c | 168 ++---
  drivers/mmc/host/sdhci.c   |   3 +-
  drivers/mmc/host/sdhci.h   |   2 +
  4 files changed, 163 insertions(+), 13 deletions(-)


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


[PATCH 5/5] mmc: sdhci: add new quirk for setting BUS_POWER & BUS_VLT fields

2015-09-04 Thread Vaibhav Hiremath
IN case of Marvell 1928 family of devices, the SD_BUS_POWER and
SD_BUS_VLT bits are used internally to gate the clocks, so
we have to set these fields.

Pasting Spec words here,

The  and  fields should be configured
to correct values. These actually do not do the voltage selection
or switch power to the SD card. However these fields are used
internally to gate the clock. So if these fields are set
incorrectly, SD module will not function.

And during my development, I have seen that SD card wouldn't function
without right configuration into these fields.

So this patch adds new quirk (SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER),
which make sure that ->set_power() sets these fields.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pltfm.c | 3 +++
 drivers/mmc/host/sdhci.c   | 3 ++-
 drivers/mmc/host/sdhci.h   | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index a207f5a..0872da0 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -101,6 +101,9 @@ void sdhci_get_of_property(struct platform_device *pdev)
of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
+   if (of_device_is_compatible(np, "marvell,pxav3-988-sdhci"))
+   host->quirks2 |= SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER;
+
clk = of_get_property(np, "clock-frequency", &size);
if (clk && size == sizeof(*clk) && *clk)
pltfm_host->clock = be32_to_cpup(clk);
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2d58b31..418f381 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1265,7 +1265,8 @@ static void sdhci_set_power(struct sdhci_host *host, 
unsigned char mode,
else
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 
-   return;
+   if (!(host->quirks2 | SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER))
+   return;
}
 
if (mode != MMC_POWER_OFF) {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 9b0e2a8..8802a0c 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -409,6 +409,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_SUPPORT_SINGLE(1<<13)
 /* Controller broken with using ACMD23 */
 #define SDHCI_QUIRK2_ACMD23_BROKEN (1<<14)
+/* Voltage capabilities of Controller must be set  */
+#define SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER  (1<<15)
 
int irq;/* Device IRQ */
void __iomem *ioaddr;   /* Mapped address */
-- 
1.9.1

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


[PATCH 3/5] mmc: sdhci-pxav3: Add pinctl setting according to bus clock

2015-09-04 Thread Vaibhav Hiremath
Different bus clock may need different pin setting.
For example, fast bus clock like 208Mhz need pin drive fast
while slow bus clock prefer pin drive slow to guarantee
signal quality.

So this patch creates two states,
  - Default (slow/normal) pin state
  - And fast pin state for higher freq bus speed.

And selection of pin state is done based on timing mode.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 
---
 drivers/mmc/host/sdhci-pxav3.c | 45 +-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index c2b2b78..d933f75 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
@@ -92,6 +93,10 @@ struct sdhci_pxa {
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
struct sdhci_pxa_data *data;
+
+   struct pinctrl *pinctrl;
+   struct pinctrl_state *pins_default;
+   struct pinctrl_state *pins_fast;
 };
 
 static struct sdhci_pxa_data pxav3_data_v1 = {
@@ -298,6 +303,33 @@ static void pxav3_gen_init_74_clocks(struct sdhci_host 
*host, u8 power_mode)
pxa->power_mode = power_mode;
 }
 
+static int pxav3_select_pinstate(struct sdhci_host *host, unsigned int uhs)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+   struct pinctrl_state *pinctrl;
+
+   if (IS_ERR(pxa->pinctrl) ||
+   IS_ERR(pxa->pins_default) ||
+   IS_ERR(pxa->pins_fast))
+   return -EINVAL;
+
+   switch (uhs) {
+   case MMC_TIMING_UHS_SDR50:
+   case MMC_TIMING_UHS_SDR104:
+   case MMC_TIMING_MMC_HS200:
+   case MMC_TIMING_MMC_HS400:
+   pinctrl = pxa->pins_fast;
+   break;
+   default:
+   /* back to default state for other legacy timing */
+   pinctrl = pxa->pins_default;
+   break;
+   }
+
+   return pinctrl_select_state(pxa->pinctrl, pinctrl);
+}
+
 static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -353,6 +385,8 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
dev_dbg(mmc_dev(host->mmc),
"%s uhs = %d, ctrl_2 = %04X\n",
__func__, uhs, ctrl_2);
+
+   pxav3_select_pinstate(host, uhs);
 }
 
 static void pxav3_voltage_switch(struct sdhci_host *host,
@@ -416,7 +450,6 @@ static void pxav3_set_clock(struct sdhci_host *host, 
unsigned int clock)
/* TX internal clock selection */
pxav3_set_tx_clock(host);
}
-
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
@@ -586,6 +619,16 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
}
}
 
+   pxa->pinctrl = devm_pinctrl_get(dev);
+   if (!IS_ERR(pxa->pinctrl)) {
+   pxa->pins_default = pinctrl_lookup_state(pxa->pinctrl, 
"default");
+   if (IS_ERR(pxa->pins_default))
+   dev_err(dev, "could not get default pinstate\n");
+   pxa->pins_fast = pinctrl_lookup_state(pxa->pinctrl, "fast");
+   if (IS_ERR(pxa->pins_fast))
+   dev_info(dev, "could not get fast pinstate\n");
+   }
+
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, PXAV3_RPM_DELAY_MS);
-- 
1.9.1

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


[PATCH 4/5] mmc: sdhci-pxav3: Fix HS200 mode support

2015-09-04 Thread Vaibhav Hiremath
From: Kevin Liu 

IN case of MMC HS200 mode, current code does not enable
SD_CE_ATA_2.MMC_HS200 & SD_CE_ATA_2.MMC_CARD bit configurations.

So this patch updates the above bit fields correctly.

Signed-off-by: Tim Wang 
Signed-off-by: Kevin Liu 
Signed-off-by: Vaibhav Hiremath 
---
Note: Unfortunately I do not have access to any other datasheets
which uses sdhci-pxav3 driver, so quite not sure whether this would
break any existing platform, probably NOT, as I do not see any
references for this change.
If anyone can confirm that would be really great.

 drivers/mmc/host/sdhci-pxav3.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index d933f75..6978810 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -57,6 +57,8 @@
 #define SD_CE_ATA_10x10C
 
 #define SD_CE_ATA_20x10E
+#define  SD_CE_ATA2_HS200_EN   BIT(10)
+#define  SD_CE_ATA2_MMC_MODE   BIT(12)
 #define  SDCE_MISC_INT BIT(2)
 #define  SDCE_MISC_INT_EN  BIT(1)
 
@@ -330,6 +332,17 @@ static int pxav3_select_pinstate(struct sdhci_host *host, 
unsigned int uhs)
return pinctrl_select_state(pxa->pinctrl, pinctrl);
 }
 
+static int pxav3_select_hs200(struct sdhci_host *host)
+{
+   u16 reg = 0;
+
+   reg = sdhci_readw(host, SD_CE_ATA_2);
+   reg |= SD_CE_ATA2_HS200_EN | SD_CE_ATA2_MMC_MODE;
+   sdhci_writew(host, reg, SD_CE_ATA_2);
+
+   return 0;
+}
+
 static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
 {
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -361,6 +374,10 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
case MMC_TIMING_UHS_DDR50:
ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
break;
+   case MMC_TIMING_MMC_HS200:
+   ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
+   pxav3_select_hs200(host);
+   break;
}
 
/*
-- 
1.9.1

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


[PATCH 1/5] mmc: sdhci-pxav3: Enable pxa1928 device support

2015-09-04 Thread Vaibhav Hiremath
SDHCI controller present in PXA1928 has few differences as far as
register map is concerned.
For example,

 PXAxxxPXA1928
 =====
 SDCLK_DELAY field   0x10A 0x114
 SDCLK_DELAY mask0x1F  0x3FF
 SDCLK_DELAY shift9  8
 SDCLK_SEL shift  8  2 (SEL1)

So in order to support multi-platform, use sdhci_pxa_regdata structure
as a variant data according to platform.

Note that, there are some more differences, which would be added
as and when respective feature gets added to the driver.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 62 ++
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 6d4bad4..aecae04 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -42,9 +42,6 @@
 #define PXAV3_RPM_DELAY_MS 50
 
 #define SD_CLOCK_BURST_SIZE_SETUP  0x10A
-#define SDCLK_SEL  0x100
-#define  SDCLK_DELAY_SHIFT 9
-#define  SDCLK_DELAY_MASK  0x1f
 
 #define SD_CFG_FIFO_PARAM  0x100
 #define  SDCFG_GEN_PAD_CLK_ON  BIT(6)
@@ -58,11 +55,25 @@
 #define  SDCE_MISC_INT BIT(2)
 #define  SDCE_MISC_INT_EN  BIT(1)
 
+#define SD_RX_CFG_REG  0x114
+
 /* IO Power control */
 #define IO_PWR_AKEY_ASFAR  0xbaba
 #define IO_PWR_AKEY_ASSAR  0xeb10
 #define IO_PWR_MMC1_PAD_1V8BIT(2)
 
+struct sdhci_pxa_data {
+   u32 sdclk_delay_reg;
+   u32 sdclk_delay_mask;
+   u8 sdclk_delay_shift;
+   u8 sdclk_sel_mask;
+   u8 sdclk_sel_shift;
+   /*
+* We have few more differences, add them along with their
+* respective feature support
+*/
+};
+
 struct sdhci_pxa {
struct clk *clk_core;
struct clk *clk_io;
@@ -70,6 +81,24 @@ struct sdhci_pxa {
void __iomem *sdio3_conf_reg;
void __iomem *io_pwr_reg;
void __iomem *io_pwr_lock_reg;
+   struct sdhci_pxa_data *data;
+};
+
+static struct sdhci_pxa_data pxav3_data_v1 = {
+   .sdclk_delay_reg= SD_CLOCK_BURST_SIZE_SETUP,
+   .sdclk_delay_mask   = 0x1F,
+   .sdclk_delay_shift  = 9,
+   .sdclk_sel_mask = 0x1,
+   .sdclk_sel_shift= 8,
+};
+
+static struct sdhci_pxa_data pxav3_data_v2 = {
+   .sdclk_delay_reg= SD_RX_CFG_REG,
+   .sdclk_delay_mask   = 0x3FF,
+   .sdclk_delay_shift  = 8,
+   /* Only set SDCLK_SEL1, as driver uses default value of SDCLK_SEL0 */
+   .sdclk_sel_mask = 0x3,
+   .sdclk_sel_shift= 2,/* SDCLK_SEL1 */
 };
 
 /*
@@ -183,6 +212,8 @@ static void pxav3_reset(struct sdhci_host *host, u8 mask)
 {
struct platform_device *pdev = to_platform_device(mmc_dev(host->mmc));
struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
 
sdhci_reset(host, mask);
 
@@ -193,12 +224,14 @@ static void pxav3_reset(struct sdhci_host *host, u8 mask)
 */
if (pdata && 0 != pdata->clk_delay_cycles) {
u16 tmp;
-
-   tmp = readw(host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
-   tmp |= (pdata->clk_delay_cycles & SDCLK_DELAY_MASK)
-   << SDCLK_DELAY_SHIFT;
-   tmp |= SDCLK_SEL;
-   writew(tmp, host->ioaddr + SD_CLOCK_BURST_SIZE_SETUP);
+   struct sdhci_pxa_data *data = pxa->data;
+
+   tmp = readw(host->ioaddr + data->sdclk_delay_reg);
+   tmp |= (pdata->clk_delay_cycles & 
data->sdclk_delay_mask)
+   << data->sdclk_delay_shift;
+   tmp &= ~(data->sdclk_sel_mask << data->sdclk_sel_shift);
+   tmp |= 1 << data->sdclk_sel_shift;
+   writew(tmp, host->ioaddr + data->sdclk_delay_reg);
}
}
 }
@@ -363,10 +396,16 @@ static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
 #ifdef CONFIG_OF
 static const struct of_device_id sdhci_pxav3_of_match[] = {
{
-   .compatible = "mrvl,pxav3-mmc",
+   .compatible = "mrvl,pxav3-mmc",
+   .data   = (void *)&pxav3_data_v1,
+   },
+   {
+   .compatible = "marvell,armada-380-sdhci",
+   .data   = (void *)&pxav3_data_v1,
},
{
-   .compat

[PATCH 2/5] mmc: sdhci-pxav3: Add platform specific set_clock ops

2015-09-04 Thread Vaibhav Hiremath
In case of PXA1928 & family of devices, the TX BUS and internal clock
need to be set as part of ->set_clock() ops, so this patch adds
platform specific ->set_clock() operation.

Note that, in order to not break other platforms, this patch
introduced the flag, which controls whether controller/platform
specific clock configuration needs to be executed.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 46 +-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index aecae04..c2b2b78 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -48,6 +48,10 @@
 #define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
 #define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24
 
+#define SD_FIFO_PARAM  0x104
+#define  INTERNAL_CLK_GATE_CTRLBIT(8)
+#define  INTERNAL_CLK_GATE_ON  BIT(9)
+
 #define SD_SPI_MODE0x108
 #define SD_CE_ATA_10x10C
 
@@ -57,6 +61,9 @@
 
 #define SD_RX_CFG_REG  0x114
 
+#define TX_CFG_REG 0x118
+#define  TX_INTERNAL_SEL_BUS_CLK   BIT(30)
+
 /* IO Power control */
 #define IO_PWR_AKEY_ASFAR  0xbaba
 #define IO_PWR_AKEY_ASSAR  0xeb10
@@ -68,6 +75,9 @@ struct sdhci_pxa_data {
u8 sdclk_delay_shift;
u8 sdclk_sel_mask;
u8 sdclk_sel_shift;
+
+   /* set this if platform needs separate clock configuration */
+   bool set_pltfrm_clk;
/*
 * We have few more differences, add them along with their
 * respective feature support
@@ -90,6 +100,7 @@ static struct sdhci_pxa_data pxav3_data_v1 = {
.sdclk_delay_shift  = 9,
.sdclk_sel_mask = 0x1,
.sdclk_sel_shift= 8,
+   .set_pltfrm_clk = false,
 };
 
 static struct sdhci_pxa_data pxav3_data_v2 = {
@@ -99,6 +110,7 @@ static struct sdhci_pxa_data pxav3_data_v2 = {
/* Only set SDCLK_SEL1, as driver uses default value of SDCLK_SEL0 */
.sdclk_sel_mask = 0x3,
.sdclk_sel_shift= 2,/* SDCLK_SEL1 */
+   .set_pltfrm_clk = true,
 };
 
 /*
@@ -375,8 +387,40 @@ static void pxav3_voltage_switch(struct sdhci_host *host,
writel(val, pxa->io_pwr_reg);
 }
 
+static void pxav3_set_tx_clock(struct sdhci_host *host)
+{
+   u32 val;
+
+   val = sdhci_readl(host, TX_CFG_REG);
+   val |= TX_INTERNAL_SEL_BUS_CLK;
+   sdhci_writel(host, val, TX_CFG_REG);
+}
+
+static void pxav3_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+
+   /* We still use common sdhci_set_clock() */
+   sdhci_set_clock(host, clock);
+
+   /* platform/controller specific clock configuration */
+   if (pxa->data->set_pltfrm_clk && clock != 0) {
+   u32 val;
+
+   val = sdhci_readw(host, SD_FIFO_PARAM);
+   /* Internal clock gate ON and CTRL = 0b11 */
+   val |= INTERNAL_CLK_GATE_CTRL | INTERNAL_CLK_GATE_ON;
+   sdhci_writew(host, val, SD_FIFO_PARAM);
+
+   /* TX internal clock selection */
+   pxav3_set_tx_clock(host);
+   }
+
+}
+
 static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock  = sdhci_set_clock,
+   .set_clock  = pxav3_set_clock,
.platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
.get_max_clock  = sdhci_pltfm_clk_get_max_clock,
.set_bus_width  = sdhci_set_bus_width,
-- 
1.9.1

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


[PATCH 0/5] mmc: sdhci-pxav3: Enable support for PXA1928 SDCHI controller

2015-09-04 Thread Vaibhav Hiremath
PXA1928 SDHCI controller has few differences, for example,

   PXAxxxPXA1928
   =====
   SDCLK_DELAY field   0x10A 0x114
   SDCLK_DELAY mask0x1F  0x3FF
   SDCLK_DELAY shift9  8
   SDCLK_SEL shift  8  2 (SEL1)

So this patch series introduces new compatible device_id
(marvell,pxav3-1928-sdhci), and makes use of .data for handling
such differences.

The series also adds support like,

 - independent ->set_clock() api, as we need to enable internal clock gate
and TX clock
 - pinctrl configuration based on bus speed.
 - introduce new quirk SDHCI_QUIRK2_MUST_SET_SDHCI_BUS_POWER
   SD_BUS_POWER & SD_BUS_VLT bit-fields are used internally to gate the
   clocks, so it is important to configure them as part of ->set_power()
   More detailed description is written into commit log.
 - Enable SDHCI_QUIRK_BROKEN_TIMEOUT_VAL for PXA1928 device_id


Testing:
I have done basic testing on both eMMC and SD card on PXA1928 based
platform.

Note: I tried to made sure that I do not break any other platform, which
used sdhci, except HS200 configuration. 
Unfortunately I do not have access to any other datasheets, where I can
cross check the details on HS200 bit-fields. Probably someone who has
access can confirm [PATCH 4/5], whether it impacts other platforms.

Kevin Liu (1):
  mmc: sdhci-pxav3: Fix HS200 mode support

Vaibhav Hiremath (4):
  mmc: sdhci-pxav3: Enable pxa1928 device support
  mmc: sdhci-pxav3: Add platform specific set_clock ops
  mmc: sdhci-pxav3: Add pinctl setting according to bus clock
  mmc: sdhci: add new quirk for setting BUS_POWER & BUS_VLT fields

 drivers/mmc/host/sdhci-pltfm.c |   3 +
 drivers/mmc/host/sdhci-pxav3.c | 168 ++---
 drivers/mmc/host/sdhci.c   |   3 +-
 drivers/mmc/host/sdhci.h   |   2 +
 4 files changed, 163 insertions(+), 13 deletions(-)

-- 
1.9.1

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


Re: [RFC 3/3] mmc: sdhci-pxav3: Add ->voltage_switch callback support

2015-09-03 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 07:21 PM, Shawn Lin wrote:

On 2015/9/2 3:32, Vaibhav Hiremath wrote:

In case PXA1928 family of devices, there is device/controller specific
configuration to control voltage/power on the IO pins.

This patch implements and enables the sdhci_ops->voltage_switch()
callback api.
Note that IO pad register addresses are fetched as a memory resource.

For example, in case of PXA1928 and family of devices, the DT property
would look something like,

sdh1: sdh@d428 {
compatible = "mrvl,pxav3-mmc";
reg-names = "sdhci", "io-pwr", "io-pwr-lock-unlock";
reg = <0xd428 0x120>,
<0xd401e81c 4>,
    <0xd4015068 8>;
...
};

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mmc/host/sdhci-pxav3.c | 59
++
  1 file changed, 59 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav3.c
b/drivers/mmc/host/sdhci-pxav3.c
index 5d26fe0..cebb2f9 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -63,11 +63,18 @@
  #define IO_PWR_AKEY_ASSAR0xeb10
  #define IO_PWR_MMC1_PAD_1V8BIT(2)

+/* IO Power control */
+#define IO_PWR_AKEY_ASFAR0xbaba
+#define IO_PWR_AKEY_ASSAR0xeb10
+#define IO_PWR_MMC1_PAD_1V8BIT(2)
+
  struct sdhci_pxa {
  struct clk *clk_core;
  struct clk *clk_io;
  u8power_mode;
  void __iomem *sdio3_conf_reg;
+void __iomem *io_pwr_reg;
+void __iomem *io_pwr_lock_reg;
  };

  /*
@@ -307,6 +314,38 @@ static void pxav3_set_uhs_signaling(struct
sdhci_host *host, unsigned int uhs)
  __func__, uhs, ctrl_2);
  }

+static void pxav3_voltage_switch(struct sdhci_host *host,
+u8 signal_voltage)
+{
+struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+struct sdhci_pxa *pxa = pltfm_host->priv;
+unsigned int val;
+
+if (!pxa->io_pwr_reg || !pxa->io_pwr_lock_reg)
+return;
+
+/* Lock register is 64 bit: First & Second access register */
+writel(IO_PWR_AKEY_ASFAR, pxa->io_pwr_lock_reg);
+writel(IO_PWR_AKEY_ASSAR, pxa->io_pwr_lock_reg + 4);
+val = readl(pxa->io_pwr_reg);
+
+switch (signal_voltage) {
+case MMC_SIGNAL_VOLTAGE_180:
+case MMC_SIGNAL_VOLTAGE_120:
+val |= IO_PWR_MMC1_PAD_1V8;
+break;
+case MMC_SIGNAL_VOLTAGE_330:
+default:
+val &= ~IO_PWR_MMC1_PAD_1V8;
+break;
+}
+
+writel(IO_PWR_AKEY_ASFAR, pxa->io_pwr_lock_reg);
+writel(IO_PWR_AKEY_ASSAR, pxa->io_pwr_lock_reg + 4);
+
+writel(val, pxa->io_pwr_reg);
+}
+
  static const struct sdhci_ops pxav3_sdhci_ops = {
  .set_clock= sdhci_set_clock,
  .platform_send_init_74_clocks= pxav3_gen_init_74_clocks,
@@ -314,6 +353,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
  .set_bus_width= sdhci_set_bus_width,
  .reset= pxav3_reset,
  .set_uhs_signaling= pxav3_set_uhs_signaling,
+.voltage_switch= pxav3_voltage_switch,
  };

  static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
@@ -368,6 +408,7 @@ static int sdhci_pxav3_probe(struct
platform_device *pdev)
  struct sdhci_host *host = NULL;
  struct sdhci_pxa *pxa = NULL;
  const struct of_device_id *match;
+struct resource *res;
  int ret;

  pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa),
GFP_KERNEL);
@@ -408,6 +449,24 @@ static int sdhci_pxav3_probe(struct
platform_device *pdev)
  goto err_mbus_win;
  }

+res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"io-pwr-conf");
+if (res) {
+pxa->io_pwr_reg = devm_ioremap_resource(&pdev->dev, res);
+if (IS_ERR(pxa->io_pwr_reg)) {
+ret = PTR_ERR(pxa->io_pwr_reg);
+goto err_mbus_win;
+}
+}


Hi Vaibhav,

Why not get it from syscon and use regmap API to deal with it.
IMO, that's okay, you can find examples from
drivers/mmc/host/dw_mmc-k3.c: dw_mci_hi6220_switch_voltage




After looking more into this, things are not looking good to me -

PXA1928 (thats what I have details for) has different needs here,

The lock/unlock register located in apbc_clocks register space, and sysconf
will not be right place for it.

I think the approach which I took in this series looks better to me :)

Thanks,
Vaibhav

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


Re: [PATCH 2/2] mmc: sdhci-pxav3: Print ret value on error from sdhci_add_host() fn

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 08:37 PM, Joe Perches wrote:

On Wed, 2015-09-02 at 18:37 +0530, Vaibhav Hiremath wrote:

On Wednesday 02 September 2015 02:07 AM, Joe Perches wrote:

On Wed, 2015-09-02 at 00:54 +0530, Vaibhav Hiremath wrote:

Return value would give clear information about the actual root-cause
of the failure.
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
@@ -455,7 +455,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)

ret = sdhci_add_host(host);
if (ret) {
-   dev_err(&pdev->dev, "failed to add host\n");
+   dev_err(&pdev->dev, "failed to add host ret - %d\n", ret);
goto err_add_host;
}


If this is really desirable, there are many other callers of
sdhci_add_host with error messages just like this one.


How about this? If you are ok, I can change it and submit the patch
again.
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c

[]

@@ -3176,8 +3176,11 @@ int sdhci_add_host(struct sdhci_host *host)
  mmc->caps |= MMC_CAP_NEEDS_POLL;

  /* If there are external regulators, get them */
-   if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER)
+   if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER) {
+   pr_err("%s: regulator supply unavailable, deferring
probe. \n",
+   mmc_hostname(mmc));
  return -EPROBE_DEFER;
+   }


(your email client has inappropriate line wrapping)

The KERN_ here probably isn't right.

Deferring isn't an error, at best it's a notification


I would consider it as an ERROR if it gets deferred
continuously/multiple times due to same reason.


and perhaps should be at pr_notice/KERN_NOTICE



Yeah, KERN_NOTICE looks right here.


I don't know how often or how many times this deferral
can occur.  Do you?



-EDEFER_PROBE usually means that driver has some dependency,
for which it has to wait.
In my case, during every boot, I pxav3_sdhci_probe gets deferred once
due to regulator unavailability.

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


Re: [RFC 3/3] mmc: sdhci-pxav3: Add ->voltage_switch callback support

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 07:21 PM, Shawn Lin wrote:

On 2015/9/2 3:32, Vaibhav Hiremath wrote:

In case PXA1928 family of devices, there is device/controller specific
configuration to control voltage/power on the IO pins.

This patch implements and enables the sdhci_ops->voltage_switch()
callback api.
Note that IO pad register addresses are fetched as a memory resource.

For example, in case of PXA1928 and family of devices, the DT property
would look something like,

sdh1: sdh@d428 {
compatible = "mrvl,pxav3-mmc";
reg-names = "sdhci", "io-pwr", "io-pwr-lock-unlock";
reg = <0xd428 0x120>,
<0xd401e81c 4>,
    <0xd4015068 8>;
...
};

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mmc/host/sdhci-pxav3.c | 59
++
  1 file changed, 59 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav3.c
b/drivers/mmc/host/sdhci-pxav3.c
index 5d26fe0..cebb2f9 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -63,11 +63,18 @@
  #define IO_PWR_AKEY_ASSAR0xeb10
  #define IO_PWR_MMC1_PAD_1V8BIT(2)

+/* IO Power control */
+#define IO_PWR_AKEY_ASFAR0xbaba
+#define IO_PWR_AKEY_ASSAR0xeb10
+#define IO_PWR_MMC1_PAD_1V8BIT(2)
+
  struct sdhci_pxa {
  struct clk *clk_core;
  struct clk *clk_io;
  u8power_mode;
  void __iomem *sdio3_conf_reg;
+void __iomem *io_pwr_reg;
+void __iomem *io_pwr_lock_reg;
  };

  /*
@@ -307,6 +314,38 @@ static void pxav3_set_uhs_signaling(struct
sdhci_host *host, unsigned int uhs)
  __func__, uhs, ctrl_2);
  }

+static void pxav3_voltage_switch(struct sdhci_host *host,
+u8 signal_voltage)
+{
+struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+struct sdhci_pxa *pxa = pltfm_host->priv;
+unsigned int val;
+
+if (!pxa->io_pwr_reg || !pxa->io_pwr_lock_reg)
+return;
+
+/* Lock register is 64 bit: First & Second access register */
+writel(IO_PWR_AKEY_ASFAR, pxa->io_pwr_lock_reg);
+writel(IO_PWR_AKEY_ASSAR, pxa->io_pwr_lock_reg + 4);
+val = readl(pxa->io_pwr_reg);
+
+switch (signal_voltage) {
+case MMC_SIGNAL_VOLTAGE_180:
+case MMC_SIGNAL_VOLTAGE_120:
+val |= IO_PWR_MMC1_PAD_1V8;
+break;
+case MMC_SIGNAL_VOLTAGE_330:
+default:
+val &= ~IO_PWR_MMC1_PAD_1V8;
+break;
+}
+
+writel(IO_PWR_AKEY_ASFAR, pxa->io_pwr_lock_reg);
+writel(IO_PWR_AKEY_ASSAR, pxa->io_pwr_lock_reg + 4);
+
+writel(val, pxa->io_pwr_reg);
+}
+
  static const struct sdhci_ops pxav3_sdhci_ops = {
  .set_clock= sdhci_set_clock,
  .platform_send_init_74_clocks= pxav3_gen_init_74_clocks,
@@ -314,6 +353,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
  .set_bus_width= sdhci_set_bus_width,
  .reset= pxav3_reset,
  .set_uhs_signaling= pxav3_set_uhs_signaling,
+.voltage_switch= pxav3_voltage_switch,
  };

  static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
@@ -368,6 +408,7 @@ static int sdhci_pxav3_probe(struct
platform_device *pdev)
  struct sdhci_host *host = NULL;
  struct sdhci_pxa *pxa = NULL;
  const struct of_device_id *match;
+struct resource *res;
  int ret;

  pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa),
GFP_KERNEL);
@@ -408,6 +449,24 @@ static int sdhci_pxav3_probe(struct
platform_device *pdev)
  goto err_mbus_win;
  }

+res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"io-pwr-conf");
+if (res) {
+pxa->io_pwr_reg = devm_ioremap_resource(&pdev->dev, res);
+if (IS_ERR(pxa->io_pwr_reg)) {
+ret = PTR_ERR(pxa->io_pwr_reg);
+goto err_mbus_win;
+}
+}


Hi Vaibhav,

Why not get it from syscon and use regmap API to deal with it.
IMO, that's okay, you can find examples from
drivers/mmc/host/dw_mmc-k3.c: dw_mci_hi6220_switch_voltage




Thanks Shawn,
Good to know that, something similar is already in the mainline.

Quickly looked into the driver, and I think it looks ok and doable.
I will for couple of days, to see whether I get further comments and then
spin next version.

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


Re: [PATCH 2/2] mmc: sdhci-pxav3: Print ret value on error from sdhci_add_host() fn

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 02:07 AM, Joe Perches wrote:

On Wed, 2015-09-02 at 00:54 +0530, Vaibhav Hiremath wrote:

Return value would give clear information about the actual root-cause
of the failure.
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
@@ -455,7 +455,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)

ret = sdhci_add_host(host);
if (ret) {
-   dev_err(&pdev->dev, "failed to add host\n");
+   dev_err(&pdev->dev, "failed to add host ret - %d\n", ret);
goto err_add_host;
}



If this is really desirable, there are many other callers of
sdhci_add_host with error messages just like this one.



How about this? If you are ok, I can change it and submit the patch
again.


diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index d2caa60..3a4902c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -3176,8 +3176,11 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->caps |= MMC_CAP_NEEDS_POLL;

/* If there are external regulators, get them */
-   if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER)
+   if (mmc_regulator_get_supply(mmc) == -EPROBE_DEFER) {
+   pr_err("%s: regulator supply unavailable, deferring 
probe. \n",

+   mmc_hostname(mmc));
return -EPROBE_DEFER;
+   }

/* If vqmmc regulator and no 1.8V signalling, then there's no 
UHS */

if (!IS_ERR(mmc->supply.vqmmc)) {


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


Re: [PATCH 1/2] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 02:01 AM, Joe Perches wrote:

On Wed, 2015-09-02 at 00:54 +0530, Vaibhav Hiremath wrote:

There were some coding style issues where spaces have been used instead
of tabs, for example, in macro definitions, alignment of function
declarations/definitions, etc...

This patch fixes all such occurrences in the code.
And also use BIT for bit definitions.


Please send 2 patches instead.


diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c

[]

@@ -128,7 +133,7 @@ static int mv_conf_mbus_windows(struct platform_device 
*pdev,
  }

  static int armada_38x_quirks(struct platform_device *pdev,
-struct sdhci_host *host)
+   struct sdhci_host *host)


This is not an improvement.



Missed to highlight one more point here,

The kernel CodingStyle talks about indentation, pasting it below -

---
Outside of comments, documentation and except in Kconfig, spaces are
never used for indentation.
---

But I see spaces are being used at lot of places :)

Till now all the patches or drivers which I submitted, I never used
spaces. :)
Anyway, just wanted to highlight CodingStyle document here.

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


Re: [RFC 2/3] mmc: sdhci: add host_ops->voltage_switch callback for all other voltages

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 01:56 PM, Jisheng Zhang wrote:

On Wed, 2 Sep 2015 13:49:53 +0530
Vaibhav Hiremath  wrote:




On Wednesday 02 September 2015 12:34 PM, Jisheng Zhang wrote:

On Wed, 2 Sep 2015 01:02:17 +0530
Vaibhav Hiremath  wrote:


Currently, the sdhci_do_start_signal_voltage_switch() function invokes
controller specific voltage switch configuration only for 1.8v usecase;
but it is required for others as well.

For example, in case of PXA1928 SDH controller, we need to set different
configuration for 3.3, 1.8 and 1.2 volt support (I/O domain power
control register).

Signed-off-by: Vaibhav Hiremath 
---
Note:
Currently ->voltage_switch() callback is only supported
in f_sdh30 driver. And I am not sure on the dependency of execution
sequence for that device. I could have moved ->voltage_switch() call
at one common place (above/below), but was not quite sure about it.
So, replicated/duplicated the call for other voltages.

   drivers/mmc/host/sdhci.c | 8 
   1 file changed, 8 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3dd295f..b59b76d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1753,6 +1753,10 @@ static int sdhci_do_start_signal_voltage_switch(struct 
sdhci_host *host,
/* Wait for 5ms */
usleep_range(5000, 5500);

+   /* Some controller need to do more when switching */
+   if (host->ops->voltage_switch)
+   host->ops->voltage_switch(host, MMC_SIGNAL_VOLTAGE_330);


Could this be implemented by regulator API? From patch set 3/3, the pxa1928
voltage_switch hook is to operate the IO pad registers, this seems not belong
to the SDHC IP core.



Not quite sure whether regulator would be right fit for this.


 From the patche[3/3], this can be achieved by abstracting the IO PAD as 
regulators
then, we may not need to touch the core sdhci.c. But I'm not sure whether this
is the good solution or not.


Exactly...


sdhci Maintainers and experts may have better
suggestions.



Thats is the reason I stamped it as a RFC :)

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


Re: [RFC 2/3] mmc: sdhci: add host_ops->voltage_switch callback for all other voltages

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 12:34 PM, Jisheng Zhang wrote:

On Wed, 2 Sep 2015 01:02:17 +0530
Vaibhav Hiremath  wrote:


Currently, the sdhci_do_start_signal_voltage_switch() function invokes
controller specific voltage switch configuration only for 1.8v usecase;
but it is required for others as well.

For example, in case of PXA1928 SDH controller, we need to set different
configuration for 3.3, 1.8 and 1.2 volt support (I/O domain power
control register).

Signed-off-by: Vaibhav Hiremath 
---
Note:
Currently ->voltage_switch() callback is only supported
in f_sdh30 driver. And I am not sure on the dependency of execution
sequence for that device. I could have moved ->voltage_switch() call
at one common place (above/below), but was not quite sure about it.
So, replicated/duplicated the call for other voltages.

  drivers/mmc/host/sdhci.c | 8 
  1 file changed, 8 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3dd295f..b59b76d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1753,6 +1753,10 @@ static int sdhci_do_start_signal_voltage_switch(struct 
sdhci_host *host,
/* Wait for 5ms */
usleep_range(5000, 5500);

+   /* Some controller need to do more when switching */
+   if (host->ops->voltage_switch)
+   host->ops->voltage_switch(host, MMC_SIGNAL_VOLTAGE_330);


Could this be implemented by regulator API? From patch set 3/3, the pxa1928
voltage_switch hook is to operate the IO pad registers, this seems not belong
to the SDHC IP core.



Not quite sure whether regulator would be right fit for this.

Initially I was thinking of making use of pinconf framework, using
PIN_CONFIG_POWER_SOURCE, but that too I am not sure is the right way of
doing it.

Probably, question for pinctrl maintainer. Looping Linus Walleji.

Also note that, this configuration is not applicable to all pins/pads,
only handpicked pads have this configuration (voltage selection on
pads).
And this configuration is not part of the same register map.

It is part of separate register map (AIB_EXT_REG_BASE), called IO
domain power control register.
And that

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


Re: [PATCH 1/2] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-02 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 12:24 PM, Jisheng Zhang wrote:

On Wed, 2 Sep 2015 00:54:13 +0530
Vaibhav Hiremath  wrote:


There were some coding style issues where spaces have been used instead
of tabs, for example, in macro definitions, alignment of function
declarations/definitions, etc...

This patch fixes all such occurrences in the code.
And also use BIT for bit definitions.

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mmc/host/sdhci-pxav3.c | 63 ++
  1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 946d37f..d02bc37 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -39,24 +39,29 @@
  #include "sdhci.h"
  #include "sdhci-pltfm.h"

-#define PXAV3_RPM_DELAY_MS 50
+#define PXAV3_RPM_DELAY_MS 50

-#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
-#define SDCLK_SEL  0x100
-#define SDCLK_DELAY_SHIFT  9
-#define SDCLK_DELAY_MASK   0x1f
+#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
+#define SDCLK_SEL  0x100
+#define  SDCLK_DELAY_SHIFT 9
+#define  SDCLK_DELAY_MASK  0x1f

-#define SD_CFG_FIFO_PARAM   0x100
-#define SDCFG_GEN_PAD_CLK_ON   (1<<6)
-#define SDCFG_GEN_PAD_CLK_CNT_MASK 0xFF
-#define SDCFG_GEN_PAD_CLK_CNT_SHIFT24
+#define SD_CFG_FIFO_PARAM  0x100
+#define  SDCFG_GEN_PAD_CLK_ON  BIT(6)
+#define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
+#define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24

-#define SD_SPI_MODE  0x108
-#define SD_CE_ATA_1  0x10C
+#define SD_SPI_MODE0x108
+#define SD_CE_ATA_10x10C

-#define SD_CE_ATA_2  0x10E
-#define SDCE_MISC_INT  (1<<2)
-#define SDCE_MISC_INT_EN   (1<<1)
+#define SD_CE_ATA_20x10E
+#define  SDCE_MISC_INT BIT(2)
+#define  SDCE_MISC_INT_EN  BIT(1)


BIT or (1 << y) are both fine, is there any reason to change to BIT?
If so, there will be lots of source code need such changes.



I have received comments for my other patches (PMIC/Regulator/mfd),
so applying same here as well before doing any real
functionality/coding changes to the driver.



+
+/* IO Power control */
+#define IO_PWR_AKEY_ASFAR  0xbaba
+#define IO_PWR_AKEY_ASSAR  0xeb10
+#define IO_PWR_MMC1_PAD_1V8BIT(2)

  struct sdhci_pxa {
struct clk *clk_core;
@@ -128,7 +133,7 @@ static int mv_conf_mbus_windows(struct platform_device 
*pdev,
  }

  static int armada_38x_quirks(struct platform_device *pdev,
-struct sdhci_host *host)
+   struct sdhci_host *host)
  {
struct device_node *np = pdev->dev.of_node;
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -136,8 +141,7 @@ static int armada_38x_quirks(struct platform_device *pdev,
struct resource *res;

host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
-   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-  "conf-sdio3");
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "conf-sdio3");
if (res) {
pxa->sdio3_conf_reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pxa->sdio3_conf_reg))
@@ -284,10 +288,10 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 * FE-2946959
 */
if (pxa->sdio3_conf_reg) {
-   u8 reg_val  = readb(pxa->sdio3_conf_reg);
+   u8 reg_val = readb(pxa->sdio3_conf_reg);

if (uhs == MMC_TIMING_UHS_SDR50 ||
-   uhs == MMC_TIMING_UHS_DDR50) {
+   uhs == MMC_TIMING_UHS_DDR50) {
reg_val &= ~SDIO3_CONF_CLK_INV;
reg_val |= SDIO3_CONF_SD_FB_CLK;
} else {
@@ -304,20 +308,20 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
  }

  static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock = sdhci_set_clock,
-   .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
-   .get_max_clock = sdhci_pltfm_clk_get_max_clock,
-   .set_bus_width = sdhci_set_bus_width,
-   .reset = pxav3_reset,
-   .set_uhs_signaling = pxav3_set_uhs_signaling,
+   .set_clock  = sdhci_set_clock,
+   .platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
+   .get_max_clock  = sdhci_pltfm_clk_get_max_clock,
+   .set_bus_width  = sdhci_set_bus_width,
+   .reset  = pxav3_reset,
+   .set_uhs_signaling  = pxav3_set_uhs_signaling,
  };


IMHO these two styles are both fine. For example, the mmc_sd_ops structure i

Re: [PATCH-v5 RESEND 0/5] i2c: pxa: Add support for PXA910 family of device

2015-09-01 Thread Vaibhav Hiremath


On Monday 24 August 2015 11:29 AM, Vaibhav Hiremath wrote:

Sorry for not following up on this aggressively, was quit busy with some
other stuff. Resending this patch with Robert's Tested-By.


This patch-series is subset of the original patch-series, submitted
on 14 Jul 2015.
Link to Original Patch-series - https://lkml.org/lkml/2015/7/14/80

The first six patches have been already queued up for upstream. So this
patch-series is respin of remaining 5 patches.

Testing:
   - Basic testing on PMIC device on I2C-0 interface
   - Boot tested on platform based on PXA1928
   - Read few registers of PMIC (RTC, ID, etc...) during boot

V4 => V5
===
Link to V3: https://lkml.org/lkml/2015/7/14/80
   - Dropped First 6 patches as they are already accepted, queued for upstream
   - Fixed a bug in PATCH [5/5], where for non PXA910 devices it as resulting 
into
 NULL pointer dereference.





Any update on this? This series is waiting since long time now.

Wolfram,
I know you wanted to have more discussion on DT properties & changes.
And I would be more happy to discuss.

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


Re: [PATCH 2/2] mmc: sdhci-pxav3: Print ret value on error from sdhci_add_host() fn

2015-09-01 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 02:07 AM, Joe Perches wrote:

On Wed, 2015-09-02 at 00:54 +0530, Vaibhav Hiremath wrote:

Return value would give clear information about the actual root-cause
of the failure.


I'm not sure why that is as nearly every error path in
sdhci_add_host emits a message.



Not for everything.
No error message for -EPROBE_DEFER.


diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c

[]

@@ -455,7 +455,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)

ret = sdhci_add_host(host);
if (ret) {
-   dev_err(&pdev->dev, "failed to add host\n");
+   dev_err(&pdev->dev, "failed to add host ret - %d\n", ret);
goto err_add_host;
}



If this is really desirable, there are many other callers of
sdhci_add_host with error messages just like this one.



Yes, true.
Ho about, adding pr_err into sdhci_add_host for -EPROBE_DEFER.

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


Re: [PATCH 1/2] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-01 Thread Vaibhav Hiremath



On Wednesday 02 September 2015 02:01 AM, Joe Perches wrote:

On Wed, 2015-09-02 at 00:54 +0530, Vaibhav Hiremath wrote:

There were some coding style issues where spaces have been used instead
of tabs, for example, in macro definitions, alignment of function
declarations/definitions, etc...

This patch fixes all such occurrences in the code.
And also use BIT for bit definitions.


Please send 2 patches instead.



Really?

I had two separate patches earlier, but after looking at the changes
squahsed them. Anyway, I do not have any strong opinion on this, so
will separate it in next version.



diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c

[]

@@ -128,7 +133,7 @@ static int mv_conf_mbus_windows(struct platform_device 
*pdev,
  }

  static int armada_38x_quirks(struct platform_device *pdev,
-struct sdhci_host *host)
+   struct sdhci_host *host)


This is not an improvement.

The old code is aligned to the open parenthesis
and is fine.



Ok,
Same here, I always use tabs. No strong opinion, so will remove it.


@@ -284,10 +288,10 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 * FE-2946959
 */
if (pxa->sdio3_conf_reg) {
-   u8 reg_val  = readb(pxa->sdio3_conf_reg);
+   u8 reg_val = readb(pxa->sdio3_conf_reg);

if (uhs == MMC_TIMING_UHS_SDR50 ||
-   uhs == MMC_TIMING_UHS_DDR50) {
+   uhs == MMC_TIMING_UHS_DDR50) {


Also not an improvement.


@@ -304,20 +308,20 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
  }

  static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock = sdhci_set_clock,
-   .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
-   .get_max_clock = sdhci_pltfm_clk_get_max_clock,
-   .set_bus_width = sdhci_set_bus_width,
-   .reset = pxav3_reset,
-   .set_uhs_signaling = pxav3_set_uhs_signaling,
+   .set_clock  = sdhci_set_clock,
+   .platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
+   .get_max_clock  = sdhci_pltfm_clk_get_max_clock,
+   .set_bus_width  = sdhci_set_bus_width,
+   .reset  = pxav3_reset,
+   .set_uhs_signaling  = pxav3_set_uhs_signaling,


  If you want.


Please clarify.

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


[RFC 2/3] mmc: sdhci: add host_ops->voltage_switch callback for all other voltages

2015-09-01 Thread Vaibhav Hiremath
Currently, the sdhci_do_start_signal_voltage_switch() function invokes
controller specific voltage switch configuration only for 1.8v usecase;
but it is required for others as well.

For example, in case of PXA1928 SDH controller, we need to set different
configuration for 3.3, 1.8 and 1.2 volt support (I/O domain power
control register).

Signed-off-by: Vaibhav Hiremath 
---
Note:
Currently ->voltage_switch() callback is only supported
in f_sdh30 driver. And I am not sure on the dependency of execution
sequence for that device. I could have moved ->voltage_switch() call
at one common place (above/below), but was not quite sure about it.
So, replicated/duplicated the call for other voltages.

 drivers/mmc/host/sdhci.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 3dd295f..b59b76d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1753,6 +1753,10 @@ static int sdhci_do_start_signal_voltage_switch(struct 
sdhci_host *host,
/* Wait for 5ms */
usleep_range(5000, 5500);
 
+   /* Some controller need to do more when switching */
+   if (host->ops->voltage_switch)
+   host->ops->voltage_switch(host, MMC_SIGNAL_VOLTAGE_330);
+
/* 3.3V regulator output should be stable within 5 ms */
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
if (!(ctrl & SDHCI_CTRL_VDD_180))
@@ -1803,6 +1807,10 @@ static int sdhci_do_start_signal_voltage_switch(struct 
sdhci_host *host,
return -EIO;
}
}
+   /* Some controller need to do more when switching */
+   if (host->ops->voltage_switch)
+   host->ops->voltage_switch(host, MMC_SIGNAL_VOLTAGE_120);
+
return 0;
default:
/* No signal voltage switch required */
-- 
1.9.1

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


[RFC 1/3] mmc: sdhci: pass signal_voltage as an argument to voltage_switch callback

2015-09-01 Thread Vaibhav Hiremath
In order to do particular voltage specific configuration in
sdhci_ops->voltage_switch() callback function, we need to
pass respective voltage value as well.
So this patch adds an extra argument for signal voltage to the
callback function.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Kevin Liu 
---
 drivers/mmc/host/sdhci.c | 2 +-
 drivers/mmc/host/sdhci.h | 2 +-
 drivers/mmc/host/sdhci_f_sdh30.c | 3 ++-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1dbe932..3dd295f 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1782,7 +1782,7 @@ static int sdhci_do_start_signal_voltage_switch(struct 
sdhci_host *host,
 
/* Some controller need to do more when switching */
if (host->ops->voltage_switch)
-   host->ops->voltage_switch(host);
+   host->ops->voltage_switch(host, MMC_SIGNAL_VOLTAGE_180);
 
/* 1.8V regulator output should be stable within 5 ms */
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 5521d29..9b0e2a8 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -537,7 +537,7 @@ struct sdhci_ops {
void(*adma_workaround)(struct sdhci_host *host, u32 intmask);
void(*platform_init)(struct sdhci_host *host);
void(*card_event)(struct sdhci_host *host);
-   void(*voltage_switch)(struct sdhci_host *host);
+   void(*voltage_switch)(struct sdhci_host *host, u8 signal_voltage);
int (*select_drive_strength)(struct sdhci_host *host,
 struct mmc_card *card,
 unsigned int max_dtr, int host_drv,
diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
index 983b8b3..7ab1c20 100644
--- a/drivers/mmc/host/sdhci_f_sdh30.c
+++ b/drivers/mmc/host/sdhci_f_sdh30.c
@@ -49,7 +49,8 @@ struct f_sdhost_priv {
struct device *dev;
 };
 
-static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host)
+static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host,
+   u8 signal_voltage)
 {
struct f_sdhost_priv *priv = sdhci_priv(host);
u32 ctrl = 0;
-- 
1.9.1

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


[RFC 3/3] mmc: sdhci-pxav3: Add ->voltage_switch callback support

2015-09-01 Thread Vaibhav Hiremath
In case PXA1928 family of devices, there is device/controller specific
configuration to control voltage/power on the IO pins.

This patch implements and enables the sdhci_ops->voltage_switch()
callback api.
Note that IO pad register addresses are fetched as a memory resource.

For example, in case of PXA1928 and family of devices, the DT property
would look something like,

sdh1: sdh@d428 {
compatible = "mrvl,pxav3-mmc";
reg-names = "sdhci", "io-pwr", "io-pwr-lock-unlock";
reg = <0xd428 0x120>,
<0xd401e81c 4>,
    <0xd4015068 8>;
...
};

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 59 ++
 1 file changed, 59 insertions(+)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 5d26fe0..cebb2f9 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -63,11 +63,18 @@
 #define IO_PWR_AKEY_ASSAR  0xeb10
 #define IO_PWR_MMC1_PAD_1V8BIT(2)
 
+/* IO Power control */
+#define IO_PWR_AKEY_ASFAR  0xbaba
+#define IO_PWR_AKEY_ASSAR  0xeb10
+#define IO_PWR_MMC1_PAD_1V8BIT(2)
+
 struct sdhci_pxa {
struct clk *clk_core;
struct clk *clk_io;
u8  power_mode;
void __iomem *sdio3_conf_reg;
+   void __iomem *io_pwr_reg;
+   void __iomem *io_pwr_lock_reg;
 };
 
 /*
@@ -307,6 +314,38 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
__func__, uhs, ctrl_2);
 }
 
+static void pxav3_voltage_switch(struct sdhci_host *host,
+   u8 signal_voltage)
+{
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct sdhci_pxa *pxa = pltfm_host->priv;
+   unsigned int val;
+
+   if (!pxa->io_pwr_reg || !pxa->io_pwr_lock_reg)
+   return;
+
+   /* Lock register is 64 bit: First & Second access register */
+   writel(IO_PWR_AKEY_ASFAR, pxa->io_pwr_lock_reg);
+   writel(IO_PWR_AKEY_ASSAR, pxa->io_pwr_lock_reg + 4);
+   val = readl(pxa->io_pwr_reg);
+
+   switch (signal_voltage) {
+   case MMC_SIGNAL_VOLTAGE_180:
+   case MMC_SIGNAL_VOLTAGE_120:
+   val |= IO_PWR_MMC1_PAD_1V8;
+   break;
+   case MMC_SIGNAL_VOLTAGE_330:
+   default:
+   val &= ~IO_PWR_MMC1_PAD_1V8;
+   break;
+   }
+
+   writel(IO_PWR_AKEY_ASFAR, pxa->io_pwr_lock_reg);
+   writel(IO_PWR_AKEY_ASSAR, pxa->io_pwr_lock_reg + 4);
+
+   writel(val, pxa->io_pwr_reg);
+}
+
 static const struct sdhci_ops pxav3_sdhci_ops = {
.set_clock  = sdhci_set_clock,
.platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
@@ -314,6 +353,7 @@ static const struct sdhci_ops pxav3_sdhci_ops = {
.set_bus_width  = sdhci_set_bus_width,
.reset  = pxav3_reset,
.set_uhs_signaling  = pxav3_set_uhs_signaling,
+   .voltage_switch = pxav3_voltage_switch,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
@@ -368,6 +408,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
struct sdhci_host *host = NULL;
struct sdhci_pxa *pxa = NULL;
const struct of_device_id *match;
+   struct resource *res;
int ret;
 
pxa = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_pxa), GFP_KERNEL);
@@ -408,6 +449,24 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
goto err_mbus_win;
}
 
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "io-pwr-conf");
+   if (res) {
+   pxa->io_pwr_reg = devm_ioremap_resource(&pdev->dev, res);
+   if (IS_ERR(pxa->io_pwr_reg)) {
+   ret = PTR_ERR(pxa->io_pwr_reg);
+   goto err_mbus_win;
+   }
+   }
+
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 
"io-pwr-lock-unlock");
+   if (res) {
+   pxa->io_pwr_lock_reg = devm_ioremap_resource(&pdev->dev, res);
+   if (IS_ERR(pxa->io_pwr_lock_reg)) {
+   ret = PTR_ERR(pxa->io_pwr_lock_reg);
+   goto err_mbus_win;
+   }
+   }
+
match = of_match_device(of_match_ptr(sdhci_pxav3_of_match), &pdev->dev);
if (match) {
ret = mmc_of_parse(host->mmc);
-- 
1.9.1

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


[RFC 0/3] mmc: sdhci: pass signal voltage as an argument to ->voltage_switch()

2015-09-01 Thread Vaibhav Hiremath
In order to do particular voltage specific configuration in
sdhci_ops->voltage_switch() callback function, we need to
pass respective voltage value as well.

So this patch series pass signal voltage to the controller
specific ->voltage_switch() callback.
Adds controller specific configuration for other voltages as well,
and add implementation for ->voltage_switch to pxav3 driver.


Note:
Currently ->voltage_switch() callback is only supported
in f_sdh30 driver. And I am not sure on the dependency of execution
sequence for that device. I could have moved ->voltage_switch() call
at one common place (above/below), but was not quite sure about it.
So, replicated/duplicated the call for other voltages.


Vaibhav Hiremath (3):
  mmc: sdhci: pass signal_voltage as an argument to voltage_switch
callback
  mmc: sdhci: add host_ops->voltage_switch callback for all other
voltages
  mmc: sdhci-pxav3: Add ->voltage_switch callback support

 drivers/mmc/host/sdhci-pxav3.c   | 59 
 drivers/mmc/host/sdhci.c | 10 ++-
 drivers/mmc/host/sdhci.h |  2 +-
 drivers/mmc/host/sdhci_f_sdh30.c |  3 +-
 4 files changed, 71 insertions(+), 3 deletions(-)

-- 
1.9.1

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


[PATCH 0/2] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-01 Thread Vaibhav Hiremath
Trivial patch-series, which fixes the tabbing issue in the driver
and second patch prints the return value from sdhci_add_host() function


Vaibhav Hiremath (2):
  mmc: sdhci-pxav3: Fix tabbing issue
  mmc: sdhci-pxav3: Print ret value on error from sdhci_add_host() fn

 drivers/mmc/host/sdhci-pxav3.c | 65 ++
 1 file changed, 34 insertions(+), 31 deletions(-)

-- 
1.9.1

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


[PATCH 1/2] mmc: sdhci-pxav3: Fix tabbing issue

2015-09-01 Thread Vaibhav Hiremath
There were some coding style issues where spaces have been used instead
of tabs, for example, in macro definitions, alignment of function
declarations/definitions, etc...

This patch fixes all such occurrences in the code.
And also use BIT for bit definitions.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 63 ++
 1 file changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 946d37f..d02bc37 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -39,24 +39,29 @@
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
 
-#define PXAV3_RPM_DELAY_MS 50
+#define PXAV3_RPM_DELAY_MS 50
 
-#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
-#define SDCLK_SEL  0x100
-#define SDCLK_DELAY_SHIFT  9
-#define SDCLK_DELAY_MASK   0x1f
+#define SD_CLOCK_BURST_SIZE_SETUP  0x10A
+#define SDCLK_SEL  0x100
+#define  SDCLK_DELAY_SHIFT 9
+#define  SDCLK_DELAY_MASK  0x1f
 
-#define SD_CFG_FIFO_PARAM   0x100
-#define SDCFG_GEN_PAD_CLK_ON   (1<<6)
-#define SDCFG_GEN_PAD_CLK_CNT_MASK 0xFF
-#define SDCFG_GEN_PAD_CLK_CNT_SHIFT24
+#define SD_CFG_FIFO_PARAM  0x100
+#define  SDCFG_GEN_PAD_CLK_ON  BIT(6)
+#define  SDCFG_GEN_PAD_CLK_CNT_MASK0xFF
+#define  SDCFG_GEN_PAD_CLK_CNT_SHIFT   24
 
-#define SD_SPI_MODE  0x108
-#define SD_CE_ATA_1  0x10C
+#define SD_SPI_MODE0x108
+#define SD_CE_ATA_10x10C
 
-#define SD_CE_ATA_2  0x10E
-#define SDCE_MISC_INT  (1<<2)
-#define SDCE_MISC_INT_EN   (1<<1)
+#define SD_CE_ATA_20x10E
+#define  SDCE_MISC_INT BIT(2)
+#define  SDCE_MISC_INT_EN  BIT(1)
+
+/* IO Power control */
+#define IO_PWR_AKEY_ASFAR  0xbaba
+#define IO_PWR_AKEY_ASSAR  0xeb10
+#define IO_PWR_MMC1_PAD_1V8BIT(2)
 
 struct sdhci_pxa {
struct clk *clk_core;
@@ -128,7 +133,7 @@ static int mv_conf_mbus_windows(struct platform_device 
*pdev,
 }
 
 static int armada_38x_quirks(struct platform_device *pdev,
-struct sdhci_host *host)
+   struct sdhci_host *host)
 {
struct device_node *np = pdev->dev.of_node;
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -136,8 +141,7 @@ static int armada_38x_quirks(struct platform_device *pdev,
struct resource *res;
 
host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
-   res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
-  "conf-sdio3");
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "conf-sdio3");
if (res) {
pxa->sdio3_conf_reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pxa->sdio3_conf_reg))
@@ -284,10 +288,10 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 * FE-2946959
 */
if (pxa->sdio3_conf_reg) {
-   u8 reg_val  = readb(pxa->sdio3_conf_reg);
+   u8 reg_val = readb(pxa->sdio3_conf_reg);
 
if (uhs == MMC_TIMING_UHS_SDR50 ||
-   uhs == MMC_TIMING_UHS_DDR50) {
+   uhs == MMC_TIMING_UHS_DDR50) {
reg_val &= ~SDIO3_CONF_CLK_INV;
reg_val |= SDIO3_CONF_SD_FB_CLK;
} else {
@@ -304,20 +308,20 @@ static void pxav3_set_uhs_signaling(struct sdhci_host 
*host, unsigned int uhs)
 }
 
 static const struct sdhci_ops pxav3_sdhci_ops = {
-   .set_clock = sdhci_set_clock,
-   .platform_send_init_74_clocks = pxav3_gen_init_74_clocks,
-   .get_max_clock = sdhci_pltfm_clk_get_max_clock,
-   .set_bus_width = sdhci_set_bus_width,
-   .reset = pxav3_reset,
-   .set_uhs_signaling = pxav3_set_uhs_signaling,
+   .set_clock  = sdhci_set_clock,
+   .platform_send_init_74_clocks   = pxav3_gen_init_74_clocks,
+   .get_max_clock  = sdhci_pltfm_clk_get_max_clock,
+   .set_bus_width  = sdhci_set_bus_width,
+   .reset  = pxav3_reset,
+   .set_uhs_signaling  = pxav3_set_uhs_signaling,
 };
 
 static struct sdhci_pltfm_data sdhci_pxav3_pdata = {
-   .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
+   .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
| SDHCI_QUIRK_32BIT_ADMA_SIZE
| SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
-   .ops = &pxav3_sdhci_ops,
+   .ops= &pxav3_sdhci_ops,
 };
 
 #ifdef CONFIG_OF
@@ -343,7 +347,7 @@ static struct sdhci_pxa_platdata 
*pxav3_get_mmc_pdata(struct device

[PATCH 2/2] mmc: sdhci-pxav3: Print ret value on error from sdhci_add_host() fn

2015-09-01 Thread Vaibhav Hiremath
Return value would give clear information about the actual root-cause
of the failure.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mmc/host/sdhci-pxav3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index d02bc37..5d26fe0 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -455,7 +455,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
 
ret = sdhci_add_host(host);
if (ret) {
-   dev_err(&pdev->dev, "failed to add host\n");
+   dev_err(&pdev->dev, "failed to add host ret - %d\n", ret);
goto err_add_host;
}
 
-- 
1.9.1

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


Re: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 04:05 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:




On Tuesday 25 August 2015 01:22 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:


Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mfd/88pm800.c | 125 --
  1 file changed, 61 insertions(+), 64 deletions(-)


Same comment as before.

How similar is this file to the other one?


I believe you are referring to include/linux/mfd/88pm80x.h



Can you reduce the size by having shared register defines?



Not sure whether I understand your comment here,
They are common defines.


I guess the question was a little convoluted.

How about; why are the extra defines in the driver?  Why aren't all of
them in the header file?  What is the difference between the defines
in the C file compared with the ones defined in the header?




I do not see any difference and need of having defines separately in C
file.
That's the cleanup I was referring to in another email.

I will walk through the whole driver code and try to cleanup all such
coding related issues. Probably expect separate series here.

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


Re: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 04:00 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

On Tuesday 25 August 2015 01:21 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:


Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.


That's not all it's doing though is it?



Yes, its just tabbing related fixes.


No, it's really not.


Please describe all of your changes.


... we're also taking the opportunity to remove the unnecessary
protection surrounding some of the defined values.



Ohhh ok. Forgot about brackets :)

Anyway,
Based on the comments you provided, I think both header file and
source file needs some more cleanup.
I will try to incorporate all changes in next version.

I may also submit separate series for cleanup version (depends on
patches I produce).

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


[PATCH-v3 RESEND] mfd: 88pm80x: Add 88pm860 chip type support

2015-08-25 Thread Vaibhav Hiremath
Add chip identification support for 88PM860 device
to the pm80x_chip_mapping table.

Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
Acked-by: Lee Jones 
---
 drivers/mfd/88pm80x.c   | 2 ++
 include/linux/mfd/88pm80x.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index 5e72f65..63445ea 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -33,6 +33,8 @@ static struct pm80x_chip_mapping chip_mapping[] = {
{0x3,   CHIP_PM800},
/* 88PM805 chip id number */
{0x0,   CHIP_PM805},
+   /* 88PM860 chip id number */
+   {0x4,   CHIP_PM860},
 };
 
 /*
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 8fcad63..d409ceb 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -21,6 +21,7 @@ enum {
CHIP_INVALID = 0,
CHIP_PM800,
CHIP_PM805,
+   CHIP_PM860,
CHIP_MAX,
 };
 
-- 
1.9.1

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


Re: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 02:00 PM, Lee Jones wrote:

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:




On Monday 24 August 2015 09:21 PM, Lee Jones wrote:

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:




On Monday 24 August 2015 07:24 PM, Lee Jones wrote:

On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:


As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
(page 0) controls the method of clearing interrupt
status of 88pm800 family of devices;

   0: clear on read
   1: clear on write

If pdata is not coming from board file, then set the
default irq clear method to "irq clear on write"

Also, as suggested by "Lee Jones" renaming variable field
to appropriate name and removed unnecessary field
pm80x_chip.irq_mode, using platform_data.irq_clr_method.

Signed-off-by: Zhao Ye 
Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
---
  drivers/mfd/88pm800.c   | 15 ++-
  include/linux/mfd/88pm80x.h |  9 +++--
  2 files changed, 17 insertions(+), 7 deletions(-)


[...]


+#define PM800_WAKEUP2_INT_READ_CLEAR   (0 << 1)
+#define PM800_WAKEUP2_INT_WRITE_CLEAR  (1 << 1)


Use BIT().


+/* Used by irq_clr_method */
+#define PM800_IRQ_CLR_ON_READ  0
+#define PM800_IRQ_CLR_ON_WRITE 1



-   int irq_mode;   /* Clear interrupt by read/write(0/1) */
+   bool irq_clr_method;/* Clear interrupt by read/write(0/1) */



+   irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
+   PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
+   ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);


This is pretty convoluted.

For starters you're abusing the 'bool' type here.  Bool is either
'true' or 'false', so at the very least you should rename
'irq_clr_method' to 'irq_clr_on_write'.

Then you can do:

irq_clr_mode = pdata->irq_clr_on_write ?
PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;



We have discussed on this, and went back-n-forth.
I think if I remember correctly, one of the version was using
true/false then we decided to rename it to relevant macro.

If I am not wrong V4 version of this series is exactly same as what you
are referring to.


Right.  I made a few suggestions which vary in usefulness depending on
how you plan to implement all of this.  Unfortunately this is a bit of
a bastardised version where some of it make sense and other parts
could do with some improvement.



This so called "basterdised version could have been avoided :)

V2 version itself was clean and ready. It just got dragged into
multiple iterations.


Don't kid yourself.  There were still improvements to be made.



Yes indeed,
Moving to pdata was required. I was referring to logic part of it.


However, what I suggest you really do is share
PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
the value through directly.



I think we discussed about this also, and the reason I recall here is,

we may need to control this from DT in the future so we decided to keep
it boolean in platform_data and have simple check before writing to
register.

And I think that was also another reason we introduced

/* Used by irq_clr_method */
#define PM800_IRQ_CLR_ON_READ   0
#define PM800_IRQ_CLR_ON_WRITE  1


I think these are still required.  So it would look like this:



NO. I think you are confused here,
We have two different macros playing around here,


+/* Used by irq_clr_method */
+#define PM800_IRQ_CLR_ON_READ  0
+#define PM800_IRQ_CLR_ON_WRITE 1

/* Used to write to register */
+#define PM800_WAKEUP2_INT_READ_CLEAR   (0 << 1)
+#define PM800_WAKEUP2_INT_WRITE_CLEAR  (1 << 1)


I know.  I used both of them *correctly* in my example below.  No
confusion here.


== Platform data ==

struct pdata {
   bool clear_irq_on_write;
};

pdata->clear_irq_on_write = PM800_IRQ_CLR_ON_{READ,WRITE};

== Driver ==

irq_clr_mode = pdata->clear_irq_on_write ?
  PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);






The V2 version had


irq_clr_mode = (chip->irq_clr_on_wr) ?
PM800_WAKEUP2_INT_WRITE_CLEAR :
PM800_WAKEUP2_INT_READ_CLEAR;
ret = regmap_update_bits(map, PM800_WAKEUP2, mask,
irq_clr_mode);

Which is exactly same as your example above, except pdata moment.

Lets not discuss too much on this, I think its time for conclusion :)


Your below example looks even better to me. So I will adopt below
example and resubmit the series.


Please check V2, which is exactly same as above.

https://patchwork.kernel.org/patch/6627781/


If you are OK with it, I will spin another version and submit it.


If you can't use the value directly, which if you want to pull the
value

Re: [PATCH-v2 3/5] mfd: devicetree: bindings: Add clock subdevice node information

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 01:28 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:


This patch updates the binding documentation for optional
clocks node and related information for buffered 32KHz clock.

Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
Acked-by: Rob Herring 
---
  Documentation/devicetree/bindings/mfd/88pm800.txt | 27 +++
  1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt 
b/Documentation/devicetree/bindings/mfd/88pm800.txt
index 2c82fcb..bc6cb02 100644
--- a/Documentation/devicetree/bindings/mfd/88pm800.txt
+++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
@@ -15,6 +15,26 @@ Optional properties :
Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
(This property is only applicable to 88PM860)

+Optional nodes:
+- clocks: 88pm800 family of devices provide multiple buffered 32.768
+  KHz outputs, so to register these as clocks with common clock framework
+  instantiate a sub-node named "clocks". It uses the common clock binding
+  documented in :
+  [Documentation/devicetree/bindings/clock/clock-bindings.txt]


I tend to prefer relative paths.  Firstly because they're shorter and
more succinct and secondly because if we do eventually move DT out of
the kernel, it will be less hassle to rename each of them.


+  - #clock-cells: should be 1.
+
+  - The following is the list of clocks generated by the controller. Each clock
+is assigned an identifier and client nodes use this identifier to specify
+the clock which they consume.
+Clock  ID  Devices
+--
+pm800_clk32k_1 0   88PM800 and 88PM860
+pm800_clk32k_2 1   88PM800 and 88PM860
+pm800_clk32k_3 2   88PM800
+
+  - compatible: Should be : "marvell,88pm800-clk"
+
  88pm80x family of devices consists of varied group of sub-devices:

  DeviceSupply Names Description
@@ -22,6 +42,7 @@ DeviceSupply Names Description
  88pm80x-onkey :   : On key
  88pm80x-rtc   :   : RTC
  88pm80x-regulator :   : Regulators
+88pm80x-clk:   : 32KHz Clk provider


Nit: Alphabetical?



Will correct both comments.

Thanks,
Vaibhav


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


Re: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 01:22 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:


Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mfd/88pm800.c | 125 --
  1 file changed, 61 insertions(+), 64 deletions(-)


Same comment as before.

How similar is this file to the other one?


I believe you are referring to include/linux/mfd/88pm80x.h



Can you reduce the size by having shared register defines?



Not sure whether I understand your comment here,
They are common defines.

PM860 only defines are named as

PM860_

Similarly,
PM805 only defines are named as

PM805_


and PM800_xxx should be common.

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


Re: [PATCH-v2 2/5] mfd: 88pm800: Update the header file with 32K clk related macros

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 01:25 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:


Update header file with required macros for 32KHz buffered clock
output of 88PM800 family of device.
These macros will be used in clk provider driver.

Signed-off-by: Vaibhav Hiremath 
---
  include/linux/mfd/88pm80x.h | 12 
  1 file changed, 12 insertions(+)

diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 122cfd2..0215d5f 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -91,6 +91,7 @@ enum {
  /* Referance and low power registers */
  #define PM800_LOW_POWER1  (0x20)
  #define PM800_LOW_POWER2  (0x21)
+#define PM800_LOW_POWER2_XO_LJ_EN  BIT(5)


Some people add an extra space for register bits, which I quite like.

So:

#define SOME_REGISTER_ADDRESS   0x123
#define  SOME_BIT_VALUE BIT(4)

Feel free to use it, or not.


  #define PM800_LOW_POWER_CONFIG3   (0x22)
  #define PM800_LDOBK_FREEZEBIT(7)
@@ -138,6 +139,13 @@ enum {
  #define PM800_ALARM   BIT(5)
  #define PM800_RTC1_USE_XO BIT(7)

+#define PM800_32K_OUTX_SEL_MASK0x3
+/* 32KHz clk output sel mode */
+#define PM800_32K_OUTX_SEL_ZERO0x0
+#define PM800_32K_OUTX_SEL_INT_32KHZ   0x1
+#define PM800_32K_OUTX_SEL_XO_32KHZ0x2
+#define PM800_32K_OUTX_SEL_HIZ 0x3
+
  /* Regulator Control Registers: BUCK1,BUCK5,LDO1 have DVC */

  /* buck registers */
@@ -208,6 +216,10 @@ enum {
  #define PM800_PMOD_MEAS1  0x52
  #define PM800_PMOD_MEAS2  0x53

+/* Oscillator control */
+#define PM800_OSC_CNTRL1   0x50
+#define PM800_OSC_CNTRL1_OSC_FREERUN_ENBIT(1)


0x50 goes before 0x52 (and 0x51 if it's there).


Will reorder in next version.

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


Re: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 01:21 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:


Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.


That's not all it's doing though is it?



Yes, its just tabbing related fixes.



Please describe all of your changes.


Signed-off-by: Vaibhav Hiremath 
---
  drivers/mfd/88pm800.c | 125 --
  1 file changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index f104a32..c4e097d 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -30,55 +30,55 @@
  #include 

  /* Interrupt Registers */
-#define PM800_INT_STATUS1  (0x05)
+#define PM800_INT_STATUS1  0x05
  #define PM800_ONKEY_INT_STS1  (1 << 0)
  #define PM800_EXTON_INT_STS1  (1 << 1)
-#define PM800_CHG_INT_STS1 (1 << 2)
-#define PM800_BAT_INT_STS1 (1 << 3)
-#define PM800_RTC_INT_STS1 (1 << 4)
+#define PM800_CHG_INT_STS1 (1 << 2)
+#define PM800_BAT_INT_STS1 (1 << 3)
+#define PM800_RTC_INT_STS1 (1 << 4)
  #define PM800_CLASSD_OC_INT_STS1  (1 << 5)


These should all be replaced by BIT().

Please fix the whole file.


Will do.

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


Re: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 01:19 PM, Lee Jones wrote:

On Tue, 25 Aug 2015, Krzysztof Kozlowski wrote:


On 25.08.2015 03:56, Vaibhav Hiremath wrote:

This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
(and family of devices).

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mfd/88pm800.c | 25 +
  1 file changed, 25 insertions(+)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index c4e097d..a928eed 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
},
  };

+static struct mfd_cell clk_devs[] = {
+   {
+   .name = "88pm80x-clk",
+   .of_compatible = "marvell,88pm800-clk",
+   .id = -1,


The "-1" here stands for PLATFORM_DEVID_NONE?


Right.  Please use the define, but use it in the mfd_add_devices()
call, rather than individual cells.



Ok,

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


Re: [PATCH-v3] mfd: 88pm80x: Add 88pm860 chip type support

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 12:08 PM, Mark Brown wrote:

On Mon, Aug 24, 2015 at 12:32:17PM +0530, Vaibhav Hiremath wrote:

On Monday 20 July 2015 05:22 PM, Vaibhav Hiremath wrote:

Add chip identification support for 88PM860 device
to the pm80x_chip_mapping table.



Last update/understanding which I have on this patch is,

Lee is OK with taking this patch from regulator tree.
Lee please let me know if you think otherwise.

With this patch in, the build dependency will go away.

Request to pick this patch into your topic/88pm800 branch and run build
test.


Please don't send content free pings, they just waste time.  I can't
review or apply content free pings.  Please submit patches following the
process in SubmittingPatches.

The chances are I deleted this mail unread since it is a MFD patch...



Hmmm Ok,

Resending now...

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


Re: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice

2015-08-25 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 10:55 AM, Krzysztof Kozlowski wrote:

On 25.08.2015 03:56, Vaibhav Hiremath wrote:

This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
(and family of devices).

Signed-off-by: Vaibhav Hiremath 
---
  drivers/mfd/88pm800.c | 25 +
  1 file changed, 25 insertions(+)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index c4e097d..a928eed 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
},
  };

+static struct mfd_cell clk_devs[] = {
+   {
+   .name = "88pm80x-clk",
+   .of_compatible = "marvell,88pm800-clk",
+   .id = -1,


The "-1" here stands for PLATFORM_DEVID_NONE?



Yes,

But it is rarely used in the kernel. so was reluctant to use and
decided to follow existing implementation.

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


Re: [PATCH-v3 2/2] regulator: 88pm800: Add support for configuration of dual phase on BUCK1

2015-08-24 Thread Vaibhav Hiremath



On Tuesday 25 August 2015 10:18 AM, Krzysztof Kozlowski wrote:

On 24.08.2015 21:40, Vaibhav Hiremath wrote:

88PM860 device supports dual phase mode on BUCK1 output.
In normal usecase, BUCK1A and BUCK1B operates independently with 3A
capacity. And they both can work as a dual phase providing 6A capacity.

This patch updates the regulator driver to read the respective
DT property and enable dual-phase mode on BUCK1.
Note that if dual phase mode is enabled, then BUCK1B will not be
registered to the regulator framework and the current capacity of
BUCK1(A) would be set to 6A [3A of BUCK1A + 3A of BUCK1B].

Signed-off-by: Vaibhav Hiremath 
---
  drivers/regulator/88pm800.c | 40 
  include/linux/mfd/88pm80x.h |  3 +++
  2 files changed, 43 insertions(+)

diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 365a154..7aca6d17 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -267,6 +267,37 @@ static struct pm800_regulator_info pm860_regulator_info[] 
= {
PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 1, ldo_volt_table2),
  };

+static int pm800_regulator_init(struct platform_device *pdev,
+   struct pm800_regulator_info *info)
+{
+   struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
+   struct pm80x_chip *chip = pm800_data->chip;
+   int ret = 0;
+
+   /* Currently only supported on 88pm860 device */
+   if (chip->type != CHIP_PM860)
+   return 0;
+
+   if (of_property_read_bool(pdev->dev.of_node,
+   "marvell,88pm860-buck1-dualphase-en")) {
+   /* Update the constraint  to [3A (BUCK1A) + 3A (BUCK1B)] */
+   info[PM800_ID_BUCK1].max_ua = 600;
+   /* Remove BUCK1B from the list, as we are in dual phase mode */
+   memset(&info[PM800_ID_BUCK1B], 0, sizeof(*info));
+   /* Enable dual phase mode */
+   ret = regmap_update_bits(chip->subchip->regmap_power,
+   PM860_BUCK1_MISC,
+   BUCK1_DUAL_PHASE_SEL,
+   BUCK1_DUAL_PHASE_SEL);
+   if (ret) {
+   dev_err(chip->dev, "failed to set dual-pase mode %d\n", 
ret);
+   return ret;
+   }
+   }
+
+   return ret;
+}
+
  static int pm800_regulator_probe(struct platform_device *pdev)
  {
struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -311,11 +342,20 @@ static int pm800_regulator_probe(struct platform_device 
*pdev)
return -ENODEV;
}

+   ret = pm800_regulator_init(pdev, info);
+   if (ret) {
+   dev_err(&pdev->dev, "failed to init 88pm800 regulator 
device\n");
+   return ret;
+   }
+
config.dev = chip->dev;
config.regmap = pm800_data->map;
for (i = 0; i < PM800_ID_RG_MAX; i++) {
struct regulator_dev *regulator;

+   if (!info[i].desc.name)
+   continue;


How the driver was working without this on 88PM800? There is a gap in
pm800_regulator_info - three regulators are not set.



I have 88PM860 based board, where the whole array will be filled up.
So it was missed I guess :)

But when I introduced logic for skipping BUCK1B, I hit this.
And here is the fix.



The patch itself looks good
Reviewed-by: Krzysztof Kozlowski 



Thanks for your review.

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


[PATCH-v2 4/5] clk: 88pm800: Add clk provider driver for 88pm800 family of devices

2015-08-24 Thread Vaibhav Hiremath
88PM800 family of devices supports buffered 32KHz clock output,
for example,

88PM800: CLK32k_1, CLK32k_2 and CLK32k_3
88PM860: CLK32K_1 and CLK32K_2

This patch adds new clk provider driver to support enable/disable
of the 32KHz clock output from 88PM800 family of devices.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/clk/Kconfig   |   8 ++
 drivers/clk/Makefile  |   1 +
 drivers/clk/clk-88pm800.c | 341 ++
 3 files changed, 350 insertions(+)
 create mode 100644 drivers/clk/clk-88pm800.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 42f7120..c34c14d 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -167,6 +167,14 @@ config COMMON_CLK_CDCE706
---help---
  This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
 
+config COMMON_CLK_88PM800
+   tristate "Clock driver for 88PM800 MFD"
+   depends on MFD_88PM800
+   ---help---
+ This driver supports 88PM800 & 88PM860 crystal oscillator
+ clock. These multi-function devices have two (88PM860) or three
+ (88PM800) fixed-rate output, clocked at 32KHz each.
+
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/qcom/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c4cf075..5248cd3 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_X86) += x86/
 obj-$(CONFIG_ARCH_ZX)  += zte/
 obj-$(CONFIG_ARCH_ZYNQ)+= zynq/
 obj-$(CONFIG_H8300)+= h8300/
+obj-$(CONFIG_COMMON_CLK_88PM800)   += clk-88pm800.o
diff --git a/drivers/clk/clk-88pm800.c b/drivers/clk/clk-88pm800.c
new file mode 100644
index 000..4c045e1
--- /dev/null
+++ b/drivers/clk/clk-88pm800.c
@@ -0,0 +1,341 @@
+/*
+ * clk-88pm800.c - Clock driver for 88PM800 family of devices
+ *
+ * This driver is created based on clk-s2mps11.c
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Number of clocks output from 88pm800 family of device */
+enum {
+   PM800_CLK32K_1 = 0,
+   PM800_CLK32K_2,
+   PM800_CLK32K_3,
+   PM800_CLKS_NUM,
+};
+
+struct pm800_clk {
+   struct pm80x_chip *chip;
+   struct device_node *clk_np;
+   struct clk_hw hw;
+   struct clk *clk;
+   struct clk_lookup *lookup;
+   u32 mask;
+   u32 shift;
+   unsigned int reg;
+};
+
+static struct pm800_clk *to_pm800_clk(struct clk_hw *hw)
+{
+   return container_of(hw, struct pm800_clk, hw);
+}
+
+static int pm800_clk_prepare(struct clk_hw *hw)
+{
+   struct pm800_clk *pm800 = to_pm800_clk(hw);
+
+   /* We always want to use XO clock */
+   return regmap_update_bits(pm800->chip->regmap,
+pm800->reg,
+pm800->mask,
+PM800_32K_OUTX_SEL_XO_32KHZ << pm800->shift);
+}
+
+static void pm800_clk_unprepare(struct clk_hw *hw)
+{
+   struct pm800_clk *pm800 = to_pm800_clk(hw);
+
+   regmap_update_bits(pm800->chip->regmap, pm800->reg,
+   pm800->mask, ~pm800->mask);
+}
+
+static int pm800_clk_is_prepared(struct clk_hw *hw)
+{
+   int ret;
+   u32 val;
+   struct pm800_clk *pm800 = to_pm800_clk(hw);
+
+   ret = regmap_read(pm800->chip->regmap,
+   pm800->reg, &val);
+   if (ret < 0)
+   return -EINVAL;
+
+   return (val & pm800->mask) >> pm800->shift;
+}
+
+static unsigned long pm800_clk_recalc_rate(struct clk_hw *hw,
+unsigned long parent_rate)
+{
+   return 32768;
+}
+
+static const struct clk_ops pm800_clk_ops = {
+   .prepare= pm800_clk_prepare,
+   .unprepare  = pm800_clk_unprepare,
+   .is_prepared= pm800_clk_is_prepared,
+   .recalc_rate= pm800_clk_recalc_rate,
+};
+
+static struct clk_init_data pm800_clks_init[PM800_CLKS_NUM] = {
+   [PM800_CLK32K_1] = {
+   .name   = "pm800_clk32k_1",
+   .ops= &pm800_clk_ops,
+   .flags  = CLK_IS_ROOT,
+   },
+   [PM800_CLK32K_2] = {
+   .name   = "p

[PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice

2015-08-24 Thread Vaibhav Hiremath
This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
(and family of devices).

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mfd/88pm800.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index c4e097d..a928eed 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
},
 };
 
+static struct mfd_cell clk_devs[] = {
+   {
+   .name = "88pm80x-clk",
+   .of_compatible = "marvell,88pm800-clk",
+   .id = -1,
+   },
+};
+
 static const struct regmap_irq pm800_irqs[] = {
/* INT0 */
[PM800_IRQ_ONKEY] = {
@@ -344,6 +352,17 @@ static int device_regulator_init(struct pm80x_chip *chip)
ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
 }
 
+static int device_clk_init(struct pm80x_chip *chip)
+{
+   if (chip->type == CHIP_PM800)
+   clk_devs[0].name = "88pm800-clk";
+   else if (chip->type == CHIP_PM860)
+   clk_devs[0].name = "88pm860-clk";
+
+   return mfd_add_devices(chip->dev, 0, &clk_devs[0],
+   ARRAY_SIZE(clk_devs), NULL, 0, NULL);
+}
+
 static int device_irq_init_800(struct pm80x_chip *chip)
 {
struct regmap *map = chip->regmap;
@@ -511,6 +530,12 @@ static int device_800_init(struct pm80x_chip *chip)
goto out;
}
 
+   ret = device_clk_init(chip);
+   if (ret) {
+   dev_err(chip->dev, "Failed to add clk subdev\n");
+   goto out;
+   }
+
return 0;
 out_dev:
mfd_remove_devices(chip->dev);
-- 
1.9.1

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


[PATCH-v2 2/5] mfd: 88pm800: Update the header file with 32K clk related macros

2015-08-24 Thread Vaibhav Hiremath
Update header file with required macros for 32KHz buffered clock
output of 88PM800 family of device.
These macros will be used in clk provider driver.

Signed-off-by: Vaibhav Hiremath 
---
 include/linux/mfd/88pm80x.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 122cfd2..0215d5f 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -91,6 +91,7 @@ enum {
 /* Referance and low power registers */
 #define PM800_LOW_POWER1   (0x20)
 #define PM800_LOW_POWER2   (0x21)
+#define PM800_LOW_POWER2_XO_LJ_EN  BIT(5)
 
 #define PM800_LOW_POWER_CONFIG3(0x22)
 #define PM800_LDOBK_FREEZE BIT(7)
@@ -138,6 +139,13 @@ enum {
 #define PM800_ALARMBIT(5)
 #define PM800_RTC1_USE_XO  BIT(7)
 
+#define PM800_32K_OUTX_SEL_MASK0x3
+/* 32KHz clk output sel mode */
+#define PM800_32K_OUTX_SEL_ZERO0x0
+#define PM800_32K_OUTX_SEL_INT_32KHZ   0x1
+#define PM800_32K_OUTX_SEL_XO_32KHZ0x2
+#define PM800_32K_OUTX_SEL_HIZ 0x3
+
 /* Regulator Control Registers: BUCK1,BUCK5,LDO1 have DVC */
 
 /* buck registers */
@@ -208,6 +216,10 @@ enum {
 #define PM800_PMOD_MEAS1   0x52
 #define PM800_PMOD_MEAS2   0x53
 
+/* Oscillator control */
+#define PM800_OSC_CNTRL1   0x50
+#define PM800_OSC_CNTRL1_OSC_FREERUN_ENBIT(1)
+
 #define PM800_GPADC0_MEAS1 0x54
 #define PM800_GPADC0_MEAS2 0x55
 #define PM800_GPADC1_MEAS1 0x56
-- 
1.9.1

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


[PATCH-v2 3/5] mfd: devicetree: bindings: Add clock subdevice node information

2015-08-24 Thread Vaibhav Hiremath
This patch updates the binding documentation for optional
clocks node and related information for buffered 32KHz clock.

Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/mfd/88pm800.txt | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt 
b/Documentation/devicetree/bindings/mfd/88pm800.txt
index 2c82fcb..bc6cb02 100644
--- a/Documentation/devicetree/bindings/mfd/88pm800.txt
+++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
@@ -15,6 +15,26 @@ Optional properties :
   Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
   (This property is only applicable to 88PM860)
 
+Optional nodes:
+- clocks: 88pm800 family of devices provide multiple buffered 32.768
+  KHz outputs, so to register these as clocks with common clock framework
+  instantiate a sub-node named "clocks". It uses the common clock binding
+  documented in :
+  [Documentation/devicetree/bindings/clock/clock-bindings.txt]
+
+  - #clock-cells: should be 1.
+
+  - The following is the list of clocks generated by the controller. Each clock
+is assigned an identifier and client nodes use this identifier to specify
+the clock which they consume.
+Clock  ID  Devices
+--
+pm800_clk32k_1 0   88PM800 and 88PM860
+pm800_clk32k_2 1   88PM800 and 88PM860
+pm800_clk32k_3 2   88PM800
+
+  - compatible: Should be : "marvell,88pm800-clk"
+
 88pm80x family of devices consists of varied group of sub-devices:
 
 Device Supply Names Description
@@ -22,6 +42,7 @@ DeviceSupply Names Description
 88pm80x-onkey  :   : On key
 88pm80x-rtc:   : RTC
 88pm80x-regulator  :   : Regulators
+88pm80x-clk:   : 32KHz Clk provider
 
 Example:
 
@@ -33,6 +54,12 @@ Example:
interrupt-controller;
#interrupt-cells = <1>;
 
+   pm800clk: clocks {
+   compatible = "marvell,88pm800-clk";
+   #clock-cells = <1>;
+   clock-output-names = "xx", "yy", "zz";
+   };
+
regulators {
compatible = "marvell,88pm80x-regulator";
 
-- 
1.9.1

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


[PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue

2015-08-24 Thread Vaibhav Hiremath
Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mfd/88pm800.c | 125 --
 1 file changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index f104a32..c4e097d 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -30,55 +30,55 @@
 #include 
 
 /* Interrupt Registers */
-#define PM800_INT_STATUS1  (0x05)
+#define PM800_INT_STATUS1  0x05
 #define PM800_ONKEY_INT_STS1   (1 << 0)
 #define PM800_EXTON_INT_STS1   (1 << 1)
-#define PM800_CHG_INT_STS1 (1 << 2)
-#define PM800_BAT_INT_STS1 (1 << 3)
-#define PM800_RTC_INT_STS1 (1 << 4)
+#define PM800_CHG_INT_STS1 (1 << 2)
+#define PM800_BAT_INT_STS1 (1 << 3)
+#define PM800_RTC_INT_STS1 (1 << 4)
 #define PM800_CLASSD_OC_INT_STS1   (1 << 5)
 
-#define PM800_INT_STATUS2  (0x06)
+#define PM800_INT_STATUS2  0x06
 #define PM800_VBAT_INT_STS2(1 << 0)
 #define PM800_VSYS_INT_STS2(1 << 1)
 #define PM800_VCHG_INT_STS2(1 << 2)
 #define PM800_TINT_INT_STS2(1 << 3)
-#define PM800_GPADC0_INT_STS2  (1 << 4)
+#define PM800_GPADC0_INT_STS2  (1 << 4)
 #define PM800_TBAT_INT_STS2(1 << 5)
-#define PM800_GPADC2_INT_STS2  (1 << 6)
-#define PM800_GPADC3_INT_STS2  (1 << 7)
+#define PM800_GPADC2_INT_STS2  (1 << 6)
+#define PM800_GPADC3_INT_STS2  (1 << 7)
 
-#define PM800_INT_STATUS3  (0x07)
+#define PM800_INT_STATUS3  0x07
 
-#define PM800_INT_STATUS4  (0x08)
+#define PM800_INT_STATUS4  0x08
 #define PM800_GPIO0_INT_STS4   (1 << 0)
 #define PM800_GPIO1_INT_STS4   (1 << 1)
 #define PM800_GPIO2_INT_STS4   (1 << 2)
 #define PM800_GPIO3_INT_STS4   (1 << 3)
 #define PM800_GPIO4_INT_STS4   (1 << 4)
 
-#define PM800_INT_ENA_1(0x09)
+#define PM800_INT_ENA_10x09
 #define PM800_ONKEY_INT_ENA1   (1 << 0)
 #define PM800_EXTON_INT_ENA1   (1 << 1)
-#define PM800_CHG_INT_ENA1 (1 << 2)
-#define PM800_BAT_INT_ENA1 (1 << 3)
-#define PM800_RTC_INT_ENA1 (1 << 4)
+#define PM800_CHG_INT_ENA1 (1 << 2)
+#define PM800_BAT_INT_ENA1 (1 << 3)
+#define PM800_RTC_INT_ENA1 (1 << 4)
 #define PM800_CLASSD_OC_INT_ENA1   (1 << 5)
 
-#define PM800_INT_ENA_2(0x0A)
+#define PM800_INT_ENA_20x0A
 #define PM800_VBAT_INT_ENA2(1 << 0)
 #define PM800_VSYS_INT_ENA2(1 << 1)
 #define PM800_VCHG_INT_ENA2(1 << 2)
 #define PM800_TINT_INT_ENA2(1 << 3)
 
-#define PM800_INT_ENA_3(0x0B)
+#define PM800_INT_ENA_30x0B
 #define PM800_GPADC0_INT_ENA3  (1 << 0)
 #define PM800_GPADC1_INT_ENA3  (1 << 1)
 #define PM800_GPADC2_INT_ENA3  (1 << 2)
 #define PM800_GPADC3_INT_ENA3  (1 << 3)
 #define PM800_GPADC4_INT_ENA3  (1 << 4)
 
-#define PM800_INT_ENA_4(0x0C)
+#define PM800_INT_ENA_40x0C
 #define PM800_GPIO0_INT_ENA4   (1 << 0)
 #define PM800_GPIO1_INT_ENA4   (1 << 1)
 #define PM800_GPIO2_INT_ENA4   (1 << 2)
@@ -86,7 +86,7 @@
 #define PM800_GPIO4_INT_ENA4   (1 << 4)
 
 /* number of INT_ENA & INT_STATUS regs */
-#define PM800_INT_REG_NUM  (4)
+#define PM800_INT_REG_NUM  4
 
 /* Interrupt Number in 88PM800 */
 enum {
@@ -114,7 +114,7 @@ enum {
 };
 
 /* PM800: generation identification number */
-#define PM800_CHIP_GEN_ID_NUM  0x3
+#define PM800_CHIP_GEN_ID_NUM  0x3
 
 static const struct i2c_device_id pm80x_id_table[] = {
{"88PM800", 0},
@@ -129,47 +129,47 @@ static const struct of_device_id pm80x_of_match_table[] = 
{
 
 static struct resource rtc_resources[] = {
{
-.name = "88pm80x-rtc",
-.start = PM800_IRQ_RTC,
-.end = PM800_IRQ_RTC,
-.flags = IORESOURCE_IRQ,
-},
+   .name = "88pm80x-rtc",
+   .start = PM800_IRQ_RTC,
+   .end = PM800_IRQ_RTC,
+   .flags = IORESOURCE_IRQ,
+   },
 };
 
 static struct mfd_cell rtc_devs[] = {
{
-.name = "88pm80x-rtc",
-.of_compatible = "marvell,88pm80x-rtc",
-.num_resources = ARRAY_SIZE(rtc_resource

[PATCH-v2 0/5] clk: 88pm800: Add new clk provider driver for 88PM800 MFD

2015-08-24 Thread Vaibhav Hiremath
88PM800 family of devices provides multiple buffered 32.768 KHz clock
output.
88PM800 : CLK32k_1, CLK32k_2 and CLK32k_3
88PM860 : CLK32k_1 and CLK32k_2

This patch-series adds new clock provider driver for enabling/disabling
buffered 32Khz clock output from 88PM800 family of device. Adds clock device to
MFD and updates the binding documentation.

The PATCH [1/4], created separately, as it would be easy between maintainers to
queue it.


Note that, I have access to only 88PM800 and 88PM860 datasheet,
so enabling support for only above two devices.

Testing:
  - Boot tested on 88PM860 based platform
  - Clock enable/disable
  - Non PM860, to make sure that it won't lead to any issues

V1 => V2:

Link to  V1: https://lkml.org/lkml/2015/7/21/298

  - Added new patch to the series [1/5], fixing tabbing issue in the file
  - Removed unnecessary brackets around macro value
  - Used devm_kcalloc variants for array allocation instead of kzalloc.
  - Fixed all other trivial issues.

Vaibhav Hiremath (5):
  mfd: 88pm800: Fix tabbing issue
  mfd: 88pm800: Update the header file with 32K clk related macros
  mfd: devicetree: bindings: Add clock subdevice node information
  clk: 88pm800: Add clk provider driver for 88pm800 family of devices
  mfd: 88pm800: Add support for clk subdevice

 Documentation/devicetree/bindings/mfd/88pm800.txt |  27 ++
 drivers/clk/Kconfig   |   8 +
 drivers/clk/Makefile  |   1 +
 drivers/clk/clk-88pm800.c | 341 ++
 drivers/mfd/88pm800.c | 150 ++
 include/linux/mfd/88pm80x.h   |  12 +
 6 files changed, 475 insertions(+), 64 deletions(-)
 create mode 100644 drivers/clk/clk-88pm800.c

-- 
1.9.1

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


[PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue

2015-08-24 Thread Vaibhav Hiremath
Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.

Signed-off-by: Vaibhav Hiremath 
---
 drivers/mfd/88pm800.c | 125 --
 1 file changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index f104a32..c4e097d 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -30,55 +30,55 @@
 #include 
 
 /* Interrupt Registers */
-#define PM800_INT_STATUS1  (0x05)
+#define PM800_INT_STATUS1  0x05
 #define PM800_ONKEY_INT_STS1   (1 << 0)
 #define PM800_EXTON_INT_STS1   (1 << 1)
-#define PM800_CHG_INT_STS1 (1 << 2)
-#define PM800_BAT_INT_STS1 (1 << 3)
-#define PM800_RTC_INT_STS1 (1 << 4)
+#define PM800_CHG_INT_STS1 (1 << 2)
+#define PM800_BAT_INT_STS1 (1 << 3)
+#define PM800_RTC_INT_STS1 (1 << 4)
 #define PM800_CLASSD_OC_INT_STS1   (1 << 5)
 
-#define PM800_INT_STATUS2  (0x06)
+#define PM800_INT_STATUS2  0x06
 #define PM800_VBAT_INT_STS2(1 << 0)
 #define PM800_VSYS_INT_STS2(1 << 1)
 #define PM800_VCHG_INT_STS2(1 << 2)
 #define PM800_TINT_INT_STS2(1 << 3)
-#define PM800_GPADC0_INT_STS2  (1 << 4)
+#define PM800_GPADC0_INT_STS2  (1 << 4)
 #define PM800_TBAT_INT_STS2(1 << 5)
-#define PM800_GPADC2_INT_STS2  (1 << 6)
-#define PM800_GPADC3_INT_STS2  (1 << 7)
+#define PM800_GPADC2_INT_STS2  (1 << 6)
+#define PM800_GPADC3_INT_STS2  (1 << 7)
 
-#define PM800_INT_STATUS3  (0x07)
+#define PM800_INT_STATUS3  0x07
 
-#define PM800_INT_STATUS4  (0x08)
+#define PM800_INT_STATUS4  0x08
 #define PM800_GPIO0_INT_STS4   (1 << 0)
 #define PM800_GPIO1_INT_STS4   (1 << 1)
 #define PM800_GPIO2_INT_STS4   (1 << 2)
 #define PM800_GPIO3_INT_STS4   (1 << 3)
 #define PM800_GPIO4_INT_STS4   (1 << 4)
 
-#define PM800_INT_ENA_1(0x09)
+#define PM800_INT_ENA_10x09
 #define PM800_ONKEY_INT_ENA1   (1 << 0)
 #define PM800_EXTON_INT_ENA1   (1 << 1)
-#define PM800_CHG_INT_ENA1 (1 << 2)
-#define PM800_BAT_INT_ENA1 (1 << 3)
-#define PM800_RTC_INT_ENA1 (1 << 4)
+#define PM800_CHG_INT_ENA1 (1 << 2)
+#define PM800_BAT_INT_ENA1 (1 << 3)
+#define PM800_RTC_INT_ENA1 (1 << 4)
 #define PM800_CLASSD_OC_INT_ENA1   (1 << 5)
 
-#define PM800_INT_ENA_2(0x0A)
+#define PM800_INT_ENA_20x0A
 #define PM800_VBAT_INT_ENA2(1 << 0)
 #define PM800_VSYS_INT_ENA2(1 << 1)
 #define PM800_VCHG_INT_ENA2(1 << 2)
 #define PM800_TINT_INT_ENA2(1 << 3)
 
-#define PM800_INT_ENA_3(0x0B)
+#define PM800_INT_ENA_30x0B
 #define PM800_GPADC0_INT_ENA3  (1 << 0)
 #define PM800_GPADC1_INT_ENA3  (1 << 1)
 #define PM800_GPADC2_INT_ENA3  (1 << 2)
 #define PM800_GPADC3_INT_ENA3  (1 << 3)
 #define PM800_GPADC4_INT_ENA3  (1 << 4)
 
-#define PM800_INT_ENA_4(0x0C)
+#define PM800_INT_ENA_40x0C
 #define PM800_GPIO0_INT_ENA4   (1 << 0)
 #define PM800_GPIO1_INT_ENA4   (1 << 1)
 #define PM800_GPIO2_INT_ENA4   (1 << 2)
@@ -86,7 +86,7 @@
 #define PM800_GPIO4_INT_ENA4   (1 << 4)
 
 /* number of INT_ENA & INT_STATUS regs */
-#define PM800_INT_REG_NUM  (4)
+#define PM800_INT_REG_NUM  4
 
 /* Interrupt Number in 88PM800 */
 enum {
@@ -114,7 +114,7 @@ enum {
 };
 
 /* PM800: generation identification number */
-#define PM800_CHIP_GEN_ID_NUM  0x3
+#define PM800_CHIP_GEN_ID_NUM  0x3
 
 static const struct i2c_device_id pm80x_id_table[] = {
{"88PM800", 0},
@@ -129,47 +129,47 @@ static const struct of_device_id pm80x_of_match_table[] = 
{
 
 static struct resource rtc_resources[] = {
{
-.name = "88pm80x-rtc",
-.start = PM800_IRQ_RTC,
-.end = PM800_IRQ_RTC,
-.flags = IORESOURCE_IRQ,
-},
+   .name = "88pm80x-rtc",
+   .start = PM800_IRQ_RTC,
+   .end = PM800_IRQ_RTC,
+   .flags = IORESOURCE_IRQ,
+   },
 };
 
 static struct mfd_cell rtc_devs[] = {
{
-.name = "88pm80x-rtc",
-.of_compatible = "marvell,88pm80x-rtc",
-.num_resources = ARRAY_SIZE(rtc_resource

Re: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method

2015-08-24 Thread Vaibhav Hiremath



On Monday 24 August 2015 09:21 PM, Lee Jones wrote:

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:




On Monday 24 August 2015 07:24 PM, Lee Jones wrote:

On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:


As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
(page 0) controls the method of clearing interrupt
status of 88pm800 family of devices;

   0: clear on read
   1: clear on write

If pdata is not coming from board file, then set the
default irq clear method to "irq clear on write"

Also, as suggested by "Lee Jones" renaming variable field
to appropriate name and removed unnecessary field
pm80x_chip.irq_mode, using platform_data.irq_clr_method.

Signed-off-by: Zhao Ye 
Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
---
  drivers/mfd/88pm800.c   | 15 ++-
  include/linux/mfd/88pm80x.h |  9 +++--
  2 files changed, 17 insertions(+), 7 deletions(-)


[...]


+#define PM800_WAKEUP2_INT_READ_CLEAR   (0 << 1)
+#define PM800_WAKEUP2_INT_WRITE_CLEAR  (1 << 1)


Use BIT().


+/* Used by irq_clr_method */
+#define PM800_IRQ_CLR_ON_READ  0
+#define PM800_IRQ_CLR_ON_WRITE 1



-   int irq_mode;   /* Clear interrupt by read/write(0/1) */
+   bool irq_clr_method;/* Clear interrupt by read/write(0/1) */



+   irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
+   PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
+   ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);


This is pretty convoluted.

For starters you're abusing the 'bool' type here.  Bool is either
'true' or 'false', so at the very least you should rename
'irq_clr_method' to 'irq_clr_on_write'.

Then you can do:

irq_clr_mode = pdata->irq_clr_on_write ?
PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;



We have discussed on this, and went back-n-forth.
I think if I remember correctly, one of the version was using
true/false then we decided to rename it to relevant macro.

If I am not wrong V4 version of this series is exactly same as what you
are referring to.


Right.  I made a few suggestions which vary in usefulness depending on
how you plan to implement all of this.  Unfortunately this is a bit of
a bastardised version where some of it make sense and other parts
could do with some improvement.



This so called "basterdised version could have been avoided :)

V2 version itself was clean and ready. It just got dragged into
multiple iterations.


However, what I suggest you really do is share
PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
the value through directly.



I think we discussed about this also, and the reason I recall here is,

we may need to control this from DT in the future so we decided to keep
it boolean in platform_data and have simple check before writing to
register.

And I think that was also another reason we introduced

/* Used by irq_clr_method */
#define PM800_IRQ_CLR_ON_READ   0
#define PM800_IRQ_CLR_ON_WRITE  1


I think these are still required.  So it would look like this:



NO. I think you are confused here,
We have two different macros playing around here,


+/* Used by irq_clr_method */
+#define PM800_IRQ_CLR_ON_READ  0
+#define PM800_IRQ_CLR_ON_WRITE 1

/* Used to write to register */
+#define PM800_WAKEUP2_INT_READ_CLEAR   (0 << 1)
+#define PM800_WAKEUP2_INT_WRITE_CLEAR  (1 << 1)




== Platform data ==

struct pdata {
   bool clear_irq_on_write;
};

pdata->clear_irq_on_write = PM800_IRQ_CLR_ON_{READ,WRITE};

== Driver ==

irq_clr_mode = pdata->clear_irq_on_write ?
  PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);



Please check V2, which is exactly same as above.

https://patchwork.kernel.org/patch/6627781/


If you are OK with it, I will spin another version and submit it.

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


Re: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method

2015-08-24 Thread Vaibhav Hiremath



On Monday 24 August 2015 07:24 PM, Lee Jones wrote:

On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:


As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
(page 0) controls the method of clearing interrupt
status of 88pm800 family of devices;

   0: clear on read
   1: clear on write

If pdata is not coming from board file, then set the
default irq clear method to "irq clear on write"

Also, as suggested by "Lee Jones" renaming variable field
to appropriate name and removed unnecessary field
pm80x_chip.irq_mode, using platform_data.irq_clr_method.

Signed-off-by: Zhao Ye 
Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
---
  drivers/mfd/88pm800.c   | 15 ++-
  include/linux/mfd/88pm80x.h |  9 +++--
  2 files changed, 17 insertions(+), 7 deletions(-)


[...]


+#define PM800_WAKEUP2_INT_READ_CLEAR   (0 << 1)
+#define PM800_WAKEUP2_INT_WRITE_CLEAR  (1 << 1)


Use BIT().


+/* Used by irq_clr_method */
+#define PM800_IRQ_CLR_ON_READ  0
+#define PM800_IRQ_CLR_ON_WRITE 1



-   int irq_mode;   /* Clear interrupt by read/write(0/1) */
+   bool irq_clr_method;/* Clear interrupt by read/write(0/1) */



+   irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
+   PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
+   ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);


This is pretty convoluted.

For starters you're abusing the 'bool' type here.  Bool is either
'true' or 'false', so at the very least you should rename
'irq_clr_method' to 'irq_clr_on_write'.

Then you can do:

irq_clr_mode = pdata->irq_clr_on_write ?
PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;



We have discussed on this, and went back-n-forth.
I think if I remember correctly, one of the version was using
true/false then we decided to rename it to relevant macro.

If I am not wrong V4 version of this series is exactly same as what you
are referring to.



However, what I suggest you really do is share
PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
the value through directly.



I think we discussed about this also, and the reason I recall here is,

we may need to control this from DT in the future so we decided to keep
it boolean in platform_data and have simple check before writing to
register.

And I think that was also another reason we introduced

/* Used by irq_clr_method */
#define PM800_IRQ_CLR_ON_READ   0
#define PM800_IRQ_CLR_ON_WRITE  1

(Earlier it was true/false in V4)

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


Re: [PATCH-v3 1/2] mfd: devicetree: bindings: 88pm800: Add DT property for dual phase enable

2015-08-24 Thread Vaibhav Hiremath



On Monday 24 August 2015 06:32 PM, Lee Jones wrote:

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:


88PM860 family of device supports dual phase mode on BUCK1 supply
providing total 6A capacity.
Note that by default they operate independently with 3A capacity.

This patch updates the devicetree binding with DT property
to enable dual-phase mode on BUCK1.

Signed-off-by: Vaibhav Hiremath 
---
  Documentation/devicetree/bindings/mfd/88pm800.txt | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt 
b/Documentation/devicetree/bindings/mfd/88pm800.txt
index dec842f..2c82fcb 100644
--- a/Documentation/devicetree/bindings/mfd/88pm800.txt
+++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
@@ -9,6 +9,12 @@ Required parent device properties:
  - #interrupt-cells: should be 1.
  The cell is the 88pm80x local IRQ number

+Optional properties :
+- marvell,88pm860-buck1-dualphase-en  : If set, enable dual phase on BUCK1,
+  providing 6A capacity.
+  Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
+  (This property is only applicable to 88PM860)


This will require a Regulator Ack.

My suggestion would be to remove the 'buck' number, as the same
property could be used on any Buck, and remove the '-en' part, as
this is implied.



Ok, Will do it in next version.

Mark,

Any comments here before I spin V4.

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


[PATCH-v3 2/2] regulator: 88pm800: Add support for configuration of dual phase on BUCK1

2015-08-24 Thread Vaibhav Hiremath
88PM860 device supports dual phase mode on BUCK1 output.
In normal usecase, BUCK1A and BUCK1B operates independently with 3A
capacity. And they both can work as a dual phase providing 6A capacity.

This patch updates the regulator driver to read the respective
DT property and enable dual-phase mode on BUCK1.
Note that if dual phase mode is enabled, then BUCK1B will not be
registered to the regulator framework and the current capacity of
BUCK1(A) would be set to 6A [3A of BUCK1A + 3A of BUCK1B].

Signed-off-by: Vaibhav Hiremath 
---
 drivers/regulator/88pm800.c | 40 
 include/linux/mfd/88pm80x.h |  3 +++
 2 files changed, 43 insertions(+)

diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 365a154..7aca6d17 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -267,6 +267,37 @@ static struct pm800_regulator_info pm860_regulator_info[] 
= {
PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 1, ldo_volt_table2),
 };
 
+static int pm800_regulator_init(struct platform_device *pdev,
+   struct pm800_regulator_info *info)
+{
+   struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
+   struct pm80x_chip *chip = pm800_data->chip;
+   int ret = 0;
+
+   /* Currently only supported on 88pm860 device */
+   if (chip->type != CHIP_PM860)
+   return 0;
+
+   if (of_property_read_bool(pdev->dev.of_node,
+   "marvell,88pm860-buck1-dualphase-en")) {
+   /* Update the constraint  to [3A (BUCK1A) + 3A (BUCK1B)] */
+   info[PM800_ID_BUCK1].max_ua = 600;
+   /* Remove BUCK1B from the list, as we are in dual phase mode */
+   memset(&info[PM800_ID_BUCK1B], 0, sizeof(*info));
+   /* Enable dual phase mode */
+   ret = regmap_update_bits(chip->subchip->regmap_power,
+   PM860_BUCK1_MISC,
+   BUCK1_DUAL_PHASE_SEL,
+   BUCK1_DUAL_PHASE_SEL);
+   if (ret) {
+   dev_err(chip->dev, "failed to set dual-pase mode %d\n", 
ret);
+   return ret;
+   }
+   }
+
+   return ret;
+}
+
 static int pm800_regulator_probe(struct platform_device *pdev)
 {
struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -311,11 +342,20 @@ static int pm800_regulator_probe(struct platform_device 
*pdev)
return -ENODEV;
}
 
+   ret = pm800_regulator_init(pdev, info);
+   if (ret) {
+   dev_err(&pdev->dev, "failed to init 88pm800 regulator 
device\n");
+   return ret;
+   }
+
config.dev = chip->dev;
config.regmap = pm800_data->map;
for (i = 0; i < PM800_ID_RG_MAX; i++) {
struct regulator_dev *regulator;
 
+   if (!info[i].desc.name)
+   continue;
+
if (pdata && pdata->num_regulators) {
init_data = pdata->regulators[i];
if (!init_data)
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index a92d173..122cfd2 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -295,6 +295,9 @@ enum {
 #define PM860_BUCK4_MISC2  (0x82)
 #define PM860_BUCK4_FULL_DRV   BIT(2)
 
+#define PM860_BUCK1_MISC   0x8E
+#define BUCK1_DUAL_PHASE_SEL   BIT(2)
+
 struct pm80x_rtc_pdata {
int vrtc;
int rtc_wakeup;
-- 
1.9.1

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


[PATCH-v3 1/2] mfd: devicetree: bindings: 88pm800: Add DT property for dual phase enable

2015-08-24 Thread Vaibhav Hiremath
88PM860 family of device supports dual phase mode on BUCK1 supply
providing total 6A capacity.
Note that by default they operate independently with 3A capacity.

This patch updates the devicetree binding with DT property
to enable dual-phase mode on BUCK1.

Signed-off-by: Vaibhav Hiremath 
---
 Documentation/devicetree/bindings/mfd/88pm800.txt | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt 
b/Documentation/devicetree/bindings/mfd/88pm800.txt
index dec842f..2c82fcb 100644
--- a/Documentation/devicetree/bindings/mfd/88pm800.txt
+++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
@@ -9,6 +9,12 @@ Required parent device properties:
 - #interrupt-cells : should be 1.
  The cell is the 88pm80x local IRQ number
 
+Optional properties :
+- marvell,88pm860-buck1-dualphase-en  : If set, enable dual phase on BUCK1,
+  providing 6A capacity.
+  Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
+  (This property is only applicable to 88PM860)
+
 88pm80x family of devices consists of varied group of sub-devices:
 
 Device Supply Names Description
-- 
1.9.1

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


[PATCH-v3 0/2] regulator: 88pm800: Add dual phase mode support on BUCK1

2015-08-24 Thread Vaibhav Hiremath
88PM860 device supports dual phase mode on BUCK1 output.
In normal usecase, BUCK1A and BUCK1B operates independently with 3A
capacity. And they both can work as a dual phase providing 6A capacity.

This patch series is subset of earlier patch-series
Link to earlier series - https://lkml.org/lkml/2015/7/16/722

Except PATCH[5/5], all other patches in the series are accepted and
queued up for next merge window.
And based on discussion on the list, creating DT property to enable
dual-phase mode on BUCK1.

Testing:
 - Tested on 88PM860 based platform
 - Boot tested 
 - Tested with & without DT property being set
 - Read register value before and after probe to make sure that
   value has been set.

V2 => V3:

 - Based on discussion on earlier patch-series,
   (comments from Krzysztof Kozlowski)
   Dynamically controlled current capacity and registration of BUCK1B,
   in case of BUCK1 dual phase mode enabled.
   Now, if BUCK1 dual phase is enabled, current capacity is set to 6A,
   and, BUCK1B will not be registered to regulator framework.

V1 => V2:

 - This is new patch-series, where, all accepted patches dropped.
   Upgraded Patch version, to ease review.
 - Based on Mark Brown's comment, we should use DT property of its own.
   using set_current_limit() is not right way here.
   So, created DT property for Dual phase mode enable.
 - Updated binding for new DT property


Vaibhav Hiremath (2):
  mfd: devicetree: bindings: 88pm800: Add DT property for dual phase
enable
  regulator: 88pm800: Add support for configuration of dual phase on
BUCK1

 Documentation/devicetree/bindings/mfd/88pm800.txt |  6 
 drivers/regulator/88pm800.c   | 40 +++
 include/linux/mfd/88pm80x.h   |  3 ++
 3 files changed, 49 insertions(+)

-- 
1.9.1

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


Re: [PATCH-v3] mfd: 88pm80x: Add 88pm860 chip type support

2015-08-24 Thread Vaibhav Hiremath



On Monday 20 July 2015 05:22 PM, Vaibhav Hiremath wrote:

Add chip identification support for 88PM860 device
to the pm80x_chip_mapping table.

Signed-off-by: Vaibhav Hiremath 
Reviewed-by: Krzysztof Kozlowski 
---
  drivers/mfd/88pm80x.c   | 2 ++
  include/linux/mfd/88pm80x.h | 1 +
  2 files changed, 3 insertions(+)



Mark,

Last update/understanding which I have on this patch is,

Lee is OK with taking this patch from regulator tree.
Lee please let me know if you think otherwise.

With this patch in, the build dependency will go away.

Request to pick this patch into your topic/88pm800 branch and run build
test.

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


Re: [PATCH-v6 0/6] mfd: 88pm800: Add Device tree support

2015-08-23 Thread Vaibhav Hiremath



On Tuesday 14 July 2015 12:27 AM, Vaibhav Hiremath wrote:



On Wednesday 08 July 2015 05:56 PM, Vaibhav Hiremath wrote:

This patch-series adds support for Device tree to 88PM800 mfd driver.
It also sets default configuration of irq clear method if board file
doesn't exist.

Testing::
  - Boot tested on PXA1928 based platform.
  - probe of mfd, rtc and regulator function passing successfully.
  - Basic read operations on registers
  - irq clear configuration

V5 => V6
===


I hope this will be queued for 4.2




Lee,

This patch-series is pending since long time, reviewed and acked.
Request to queue it up for next merge window.

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


[PATCH-v5 RESEND 3/5] i2c: pxa: Add support for pxa910/988 & new configuration features

2015-08-23 Thread Vaibhav Hiremath
TWSI_ILCR & TWSI_IWCR registers are used to adjust clock rate
of standard & fast mode in pxa910/988; so this patch adds these two new
entries to "struct pxa_reg_layout" and "struct pxa_i2c".

As discussed in the previous patch-series, the idea here is to add standard
DT properties for ilcr and iwcr configuration fields.
In case of Master ilcr is used for low/high time and in case of slave mode
of operation iwcr is used for setup/hold time.

Signed-off-by: Jett.Zhou 
Signed-off-by: Yi Zhang 
Signed-off-by: Vaibhav Hiremath 
Tested-by: Robert Jarzmik 
---
 drivers/i2c/busses/i2c-pxa.c | 42 +-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index abf04f2..8d76197 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -46,12 +46,15 @@ struct pxa_reg_layout {
u32 icr;
u32 isr;
u32 isar;
+   u32 ilcr;
+   u32 iwcr;
 };
 
 enum pxa_i2c_types {
REGS_PXA2XX,
REGS_PXA3XX,
REGS_CE4100,
+   REGS_PXA910,
 };
 
 /*
@@ -79,12 +82,22 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
.isr =  0x04,
/* no isar register */
},
+   [REGS_PXA910] = {
+   .ibmr = 0x00,
+   .idbr = 0x08,
+   .icr =  0x10,
+   .isr =  0x18,
+   .isar = 0x20,
+   .ilcr = 0x28,
+   .iwcr = 0x30,
+   },
 };
 
 static const struct platform_device_id i2c_pxa_id_table[] = {
{ "pxa2xx-i2c", REGS_PXA2XX },
{ "pxa3xx-pwri2c",  REGS_PXA3XX },
{ "ce4100-i2c", REGS_CE4100 },
+   { "pxa910-i2c", REGS_PXA910 },
{ },
 };
 MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -124,6 +137,24 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 #define ISR_SAD(1 << 9)   /* slave address detected */
 #define ISR_BED(1 << 10)  /* bus error no ACK/NAK */
 
+/* bit field shift & mask */
+#define ILCR_SLV_SHIFT 0
+#define ILCR_SLV_MASK  (0x1FF << ILCR_SLV_SHIFT)
+#define ILCR_FLV_SHIFT 9
+#define ILCR_FLV_MASK  (0x1FF << ILCR_FLV_SHIFT)
+#define ILCR_HLVL_SHIFT18
+#define ILCR_HLVL_MASK (0x1FF << ILCR_HLVL_SHIFT)
+#define ILCR_HLVH_SHIFT27
+#define ILCR_HLVH_MASK (0x1F << ILCR_HLVH_SHIFT)
+
+#define IWCR_CNT_SHIFT 0
+#define IWCR_CNT_MASK  (0x1F << IWCR_CNT_SHIFT)
+#define IWCR_HS_CNT1_SHIFT 5
+#define IWCR_HS_CNT1_MASK  (0x1F << IWCR_HS_CNT1_SHIFT)
+#define IWCR_HS_CNT2_SHIFT 10
+#define IWCR_HS_CNT2_MASK  (0x1F << IWCR_HS_CNT2_SHIFT)
+
+
 struct pxa_i2c {
spinlock_t  lock;
wait_queue_head_t   wait;
@@ -150,6 +181,8 @@ struct pxa_i2c {
void __iomem*reg_icr;
void __iomem*reg_isr;
void __iomem*reg_isar;
+   void __iomem*reg_ilcr;
+   void __iomem*reg_iwcr;
 
unsigned long   iobase;
unsigned long   iosize;
@@ -169,6 +202,8 @@ struct pxa_i2c {
 #define _ICR(i2c)  ((i2c)->reg_icr)
 #define _ISR(i2c)  ((i2c)->reg_isr)
 #define _ISAR(i2c) ((i2c)->reg_isar)
+#define _ILCR(i2c) ((i2c)->reg_ilcr)
+#define _IWCR(i2c) ((i2c)->reg_iwcr)
 
 /*
  * I2C Slave mode address
@@ -1135,7 +1170,7 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = 
{
 static const struct of_device_id i2c_pxa_dt_ids[] = {
{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
-   { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
+   { .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
{}
 };
 MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
@@ -1243,6 +1278,11 @@ static int i2c_pxa_probe(struct platform_device *dev)
if (i2c_type != REGS_CE4100)
i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
 
+   if (i2c_type == REGS_PXA910) {
+   i2c->reg_ilcr = i2c->reg_base + pxa_reg_layout[i2c_type].ilcr;
+   i2c->reg_iwcr = i2c->reg_base + pxa_reg_layout[i2c_type].iwcr;
+   }
+
i2c->iobase = res->start;
i2c->iosize = resource_size(res);
 
-- 
1.9.1

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


[PATCH-v5 RESEND 2/5] i2c: pxa: enable/disable i2c module across msg xfer

2015-08-23 Thread Vaibhav Hiremath
From: Yi Zhang 

Enable i2c module/unit before transmission and disable when it
finishes.

why?
It's because the i2c bus may be disturbed if the slave device,
typically a touch, powers on.

As we do not want to break slave mode support, this patch introduces
DT property to control disable of the I2C module after xfer in master
mode of operation.

i2c-disable-after-xfer : If set, driver will disable I2C module after
msg xfer

Signed-off-by: Yi Zhang 
Signed-off-by: Vaibhav Hiremath 
---
 drivers/i2c/busses/i2c-pxa.c | 43 +--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 66cf437..abf04f2 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -161,6 +161,7 @@ struct pxa_i2c {
unsigned char   master_code;
unsigned long   rate;
boolhighmode_enter;
+   booldisable_after_xfer;
 };
 
 #define _IBMR(i2c) ((i2c)->reg_ibmr)
@@ -284,6 +285,24 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c 
*i2c, const char *why)
 static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
 static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
 
+/* enable/disable i2c unit */
+static inline int i2c_pxa_is_enabled(struct pxa_i2c *i2c)
+{
+   return (readl(_ICR(i2c)) & ICR_IUE);
+}
+
+static inline void i2c_pxa_enable(struct pxa_i2c *i2c, bool enable)
+{
+   if (enable) {
+   if (!i2c_pxa_is_enabled(i2c)) {
+   writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
+   udelay(100);
+   }
+   } else {
+   writel(readl(_ICR(i2c)) & ~ICR_IUE, _ICR(i2c));
+   }
+}
+
 static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
 {
return !(readl(_ICR(i2c)) & ICR_SCLE);
@@ -480,8 +499,7 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
i2c_pxa_set_slave(i2c, 0);
 
/* enable unit */
-   writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
-   udelay(100);
+   i2c_pxa_enable(i2c, true);
 }
 
 
@@ -832,6 +850,9 @@ static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
struct pxa_i2c *i2c = adap->algo_data;
int ret, i;
 
+   /* Enable i2c unit */
+   i2c_pxa_enable(i2c, true);
+
/* If the I2C controller is disabled we need to reset it
  (probably due to a suspend/resume destroying state). We do
  this here as we can then avoid worrying about resuming the
@@ -852,6 +873,11 @@ static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
ret = -EREMOTEIO;
  out:
i2c_pxa_set_slave(i2c, ret);
+
+   /* disable i2c unit */
+   if (i2c->disable_after_xfer)
+   i2c_pxa_enable(i2c, false);
+
return ret;
 }
 
@@ -1067,6 +1093,9 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[], int num
struct pxa_i2c *i2c = adap->algo_data;
int ret, i;
 
+   /* Enable i2c unit */
+   i2c_pxa_enable(i2c, true);
+
for (i = adap->retries; i >= 0; i--) {
ret = i2c_pxa_do_xfer(i2c, msgs, num);
if (ret != I2C_RETRY)
@@ -1080,6 +1109,10 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[], int num
ret = -EREMOTEIO;
  out:
i2c_pxa_set_slave(i2c, ret);
+   /* disable i2c unit */
+   if (i2c->disable_after_xfer)
+   i2c_pxa_enable(i2c, false);
+
return ret;
 }
 
@@ -1120,6 +1153,9 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, 
struct pxa_i2c *i2c,
/* For device tree we always use the dynamic or alias-assigned ID */
i2c->adap.nr = -1;
 
+   i2c->disable_after_xfer = of_property_read_bool(np,
+   "i2c-disable-after-xfer");
+
if (of_get_property(np, "mrvl,i2c-polling", NULL))
i2c->use_pio = 1;
if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
@@ -1264,6 +1300,9 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
platform_set_drvdata(dev, i2c);
 
+   if (i2c->disable_after_xfer)
+   i2c_pxa_enable(i2c, false);
+
 #ifdef CONFIG_I2C_PXA_SLAVE
dev_info(&i2c->adap.dev, " PXA I2C adapter, slave address %d\n",
i2c->slave_addr);
-- 
1.9.1

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


[PATCH-v5 RESEND 4/5] Documentation: binding: add sclk adjustment properties to i2c-pxa

2015-08-23 Thread Vaibhav Hiremath
With addition of PXA910 family of devices, the TWSI module supports
new feature which allows us to adjust SCLK. i2c-pxa driver takes input
configuration in nsec and converts it to respective bit-fields,

 - i2c-sclk-low-time-ns : SCLK low time (tlow)
   This property is used along with mode selection.
 - i2c-sclk-high-time-ns : SCLK high time (thigh)
 - i2c-start-hold-time-ns : Used in case of high speed mode for start bit
   hold/setup wait counter.
 - i2c-stop-hold-time-ns : Used in case of high speed mode for stop bit
   hold/setup wait counter.
 - i2c-sda-hold-time-ns : Used to calculate hold/setup wait counter for
   standard and fast mode.

Signed-off-by: Vaibhav Hiremath 
---
 Documentation/devicetree/bindings/i2c/i2c-pxa.txt | 13 +
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt 
b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 9657db5..bb4df60 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -23,12 +23,25 @@ Optional properties :
  - i2c-disable-after-xfer : If set, driver will disable I2C module
after msg xfer and enable it again before xfer.
 
+   (Applicable to PXA910 family):
+
+ - i2c-sclk-low-time-ns : SCLK low time (tlow), for standard/fast/high
+   speed mode.
+   This property is used along with mode selection. Driver uses this property
+   to set low/high time for standard and fast speed mode, as HW counter
+   bit-field is same for both.
+ - i2c-sclk-high-time-ns : SCLK high time (thigh), Used in case of high speed
+   mode only.
+
 Examples:
twsi1: i2c@d4011000 {
compatible = "mrvl,mmp-twsi";
reg = <0xd4011000 0x1000>;
interrupts = <7>;
mrvl,i2c-fast-mode;
+
+   i2c-sclk-low-time-ns = <988>;
+   i2c-sclk-high-time-ns = <988>;
};

twsi2: i2c@d4025000 {
-- 
1.9.1

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


[PATCH-v5 RESEND 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration support

2015-08-23 Thread Vaibhav Hiremath
With addition of PXA910 family of devices, the TWSI module supports
SCL clock adjustment using ILCR register.

This patch enables the control and configuration of ICLR through DT
properties,

i2c-sclk-high-time-ns:
  SCLK high time (tHigh), for standard/fast/high speed mode
i2c-sclk-low-time-ns:
  SCLK low time (tLow), for standard/fast/high speed mode

Note that in case of standard and fast mod, the tLow and tHigh counters
are same, and software will use tLow value.

Also, brought up devm_clk_get() fn above i2c_pxa_probe_dt(), as it
uses clk rate for timing calculations.

Signed-off-by: Vaibhav Hiremath 
Signed-off-by: Jett.Zhou 
Signed-off-by: Yi Zhang 
Tested-by: Robert Jarzmik 
---
 drivers/i2c/busses/i2c-pxa.c | 69 
 1 file changed, 63 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 8d76197..6012ae5 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -195,6 +195,9 @@ struct pxa_i2c {
unsigned long   rate;
boolhighmode_enter;
booldisable_after_xfer;
+
+   unsigned intsclk_thigh_load_cnt;
+   unsigned intsclk_tlow_load_cnt;
 };
 
 #define _IBMR(i2c) ((i2c)->reg_ibmr)
@@ -507,6 +510,36 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int 
errcode)
 #define i2c_pxa_set_slave(i2c, err)do { } while (0)
 #endif
 
+static void i2c_pxa_do_sclk_adj(struct pxa_i2c *i2c)
+{
+   unsigned int reg_ilcr;
+
+   if (!i2c->reg_ilcr)
+   return;
+
+   reg_ilcr = readl(_ILCR(i2c));
+
+   /* For standard/fast mode tlow and thigh counters are same */
+   if (i2c->sclk_tlow_load_cnt) {
+   unsigned int mask, shift;
+
+   mask = i2c->high_mode ? ILCR_HLVL_MASK :
+   i2c->fast_mode ? ILCR_FLV_MASK : ILCR_SLV_MASK;
+   shift = i2c->high_mode ? ILCR_HLVL_SHIFT :
+   i2c->fast_mode ? ILCR_FLV_SHIFT : ILCR_SLV_SHIFT;
+
+   reg_ilcr &= ~mask;
+   reg_ilcr |= i2c->sclk_tlow_load_cnt << shift;
+   }
+
+   if (i2c->high_mode && i2c->sclk_thigh_load_cnt) {
+   reg_ilcr &= ~ILCR_HLVH_MASK;
+   reg_ilcr |= i2c->sclk_thigh_load_cnt << ILCR_HLVH_SHIFT;
+   }
+
+   writel(reg_ilcr, _ILCR(i2c));
+}
+
 static void i2c_pxa_reset(struct pxa_i2c *i2c)
 {
pr_debug("Resetting I2C Controller Unit\n");
@@ -526,6 +559,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c));
 
+   i2c_pxa_do_sclk_adj(i2c);
+
 #ifdef CONFIG_I2C_PXA_SLAVE
dev_info(&i2c->adap.dev, "Enabling slave mode\n");
writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c));
@@ -1198,6 +1233,26 @@ static int i2c_pxa_probe_dt(struct platform_device 
*pdev, struct pxa_i2c *i2c,
 
*i2c_types = (enum pxa_i2c_types)(of_id->data);
 
+   /* optional properties */
+   if (of_device_is_compatible(np, "mrvl,mmp-twsi")) {
+   unsigned int tlow = 0, thigh = 0;
+   unsigned int clk_ns;
+
+   /* clock time in nsec */
+   clk_ns = 100 / (i2c->rate / 1000);
+
+   of_property_read_u32(np, "i2c-sclk-high-time-ns", &thigh);
+   i2c->sclk_thigh_load_cnt = thigh / clk_ns;
+
+   of_property_read_u32(np, "i2c-sclk-low-time-ns", &tlow);
+   i2c->sclk_tlow_load_cnt = tlow / clk_ns;
+
+   /* For std/fast mode tlow & thigh have same bit-fields */
+   if (!i2c->high_mode &&
+   (i2c->sclk_tlow_load_cnt != i2c->sclk_thigh_load_cnt))
+   dev_warn(&i2c->adap.dev,
+   "mismatch of tLow & tHigh values, using 
tLow\n");
+   }
return 0;
 }
 
@@ -1248,6 +1303,14 @@ static int i2c_pxa_probe(struct platform_device *dev)
return irq;
}
 
+   i2c->clk = devm_clk_get(&dev->dev, NULL);
+   if (IS_ERR(i2c->clk)) {
+   dev_err(&dev->dev, "failed to get the clk: %ld\n", 
PTR_ERR(i2c->clk));
+   return PTR_ERR(i2c->clk);
+   }
+
+   i2c->rate = clk_get_rate(i2c->clk);
+
/* Default adapter num to device id; i2c_pxa_probe_dt can override. */
i2c->adap.nr = dev->id;
 
@@ -1265,12 +1328,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
strlcpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name));
 
-   i2c->clk = devm_clk_get(&dev->dev, NULL);
-   if (

[PATCH-v5 RESEND 1/5] Documentation: binding: add new property 'disable_after_xfer' to i2c-pxa

2015-08-23 Thread Vaibhav Hiremath
Driver will now supports enable/disable across msg xfer, which user
can control it by new DT property -

i2c-disable-after-xfer : If set, driver will disable I2C module after msg
 xfer and enable it back before xfer.

Signed-off-by: Vaibhav Hiremath 
---
 Documentation/devicetree/bindings/i2c/i2c-pxa.txt | 5 +
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt 
b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 12b78ac..9657db5 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -18,6 +18,11 @@ Recommended properties :
status register of i2c controller instead.
  - mrvl,i2c-fast-mode : Enable fast mode of i2c controller.
 
+Optional properties :
+
+ - i2c-disable-after-xfer : If set, driver will disable I2C module
+   after msg xfer and enable it again before xfer.
+
 Examples:
twsi1: i2c@d4011000 {
compatible = "mrvl,mmp-twsi";
-- 
1.9.1

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


[PATCH-v5 RESEND 0/5] i2c: pxa: Add support for PXA910 family of device

2015-08-23 Thread Vaibhav Hiremath
Sorry for not following up on this aggressively, was quit busy with some
other stuff. Resending this patch with Robert's Tested-By.


This patch-series is subset of the original patch-series, submitted
on 14 Jul 2015.
Link to Original Patch-series - https://lkml.org/lkml/2015/7/14/80

The first six patches have been already queued up for upstream. So this
patch-series is respin of remaining 5 patches.

Testing:
  - Basic testing on PMIC device on I2C-0 interface
  - Boot tested on platform based on PXA1928
  - Read few registers of PMIC (RTC, ID, etc...) during boot

V4 => V5
===
Link to V3: https://lkml.org/lkml/2015/7/14/80
  - Dropped First 6 patches as they are already accepted, queued for upstream
  - Fixed a bug in PATCH [5/5], where for non PXA910 devices it as resulting 
into
NULL pointer dereference.


For the record, pasting all the details from original patch-series -

V3 => V4
===
Link to V3: http://www.spinics.net/lists/devicetree/msg85904.html
  - [PATCH 06/11] Removed unnecessary dev_err on devm_kzalloc() check
  - [PATCH 06/11] Removed return check on platform_get_resource(), as 
devm_ioremap_resource() does it for us.
Also, brought up the devm_ioremap_resource() function call in the execution
sequence, as no point in delaying it if we do not have resource.
It make sense, after this change.
  - [PATCH 04/11] Typecast changed to 'enum pxa_i2c_types'
Also updated the subject line "Removed ==> Fix"

V2 => V3
===
Link to V2: http://www.spinics.net/lists/linux-i2c/msg20059.html
  - Removed PATCH [4/12] related to reset of I2C module.
Suggested by "Robert Jarzmik"
  - Updated commit description for,
  PATCH [11/12]: Mentioned reasoning about moment of clk_get code.
  PATCH [12/12]: for DT property node.
  - Added Acked by "Robert Jarzmik" to patched which he acked.

V1 => V2:

Link to V1 - 
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/347012.html
  - Fixed all comments from "Robert Jarzmik" and "Wolfram Sang"
 - Dropped Patch
 05/12: using core bus reset implementation - under work.
 08/12: NAKed and dropped
 - Separated DT binding patch from driver changes, for easy merge


Vaibhav Hiremath (4):
  Documentation: binding: add new property 'disable_after_xfer' to
i2c-pxa
  i2c: pxa: Add support for pxa910/988 & new configuration features
  Documentation: binding: add sclk adjustment properties to i2c-pxa
  i2c: pxa: Add ILCR (tLow & tHigh) configuration support

Yi Zhang (1):
  i2c: pxa: enable/disable i2c module across msg xfer

 Documentation/devicetree/bindings/i2c/i2c-pxa.txt |  18 +++
 drivers/i2c/busses/i2c-pxa.c  | 154 --
 2 files changed, 163 insertions(+), 9 deletions(-)

-- 
1.9.1

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


Re: [PATCH-v5 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration support

2015-08-09 Thread Vaibhav Hiremath



On Sunday 09 August 2015 05:48 PM, Robert Jarzmik wrote:

Vaibhav Hiremath  writes:


Robert,

It would be helpful if you can test this patch-series and confirm that
it now fixes the NULL pointer deference issue.

Tested, it works on pxa27x in master mode, in non-DT mode.

For all non-DT patches, you can add my :
Tested-by: Robert Jarzmik 



Thanks Robert,

Wolfram,
Request you to please take a look at this series.
We can have discussion on DT properties as well.

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


Re: [PATCH-v2 2/2] regulator: 88pm800: Add support for configuration of dual phase on BUCK1

2015-08-05 Thread Vaibhav Hiremath



On Thursday 06 August 2015 05:28 AM, Krzysztof Kozlowski wrote:

On 05.08.2015 17:45, Vaibhav Hiremath wrote:



On Thursday 23 July 2015 10:21 AM, Krzysztof Kozlowski wrote:

2015-07-22 1:23 GMT+09:00 Vaibhav Hiremath :

88PM860 device supports dual phase mode on BUCK1 output.
In normal usecase, BUCK1A and BUCK1B operates independently with 3A
capacity. And they both can work as a dual phase providing 6A capacity.

This patch updates the regulator driver to read the respective
DT property and enable dual-phase mode on BUCK1.

Note that, this is init time (one time) initialization.



Sorry for delayed response, was on bed rest almost for week.


Signed-off-by: Vaibhav Hiremath 
---
   drivers/regulator/88pm800.c | 31 +++
   include/linux/mfd/88pm80x.h |  3 +++
   2 files changed, 34 insertions(+)


Don't you need to update the constraints also? I think the BUCK1
regulator has fixed constraint of 3 A:
PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 300, buck1_volt_range,
0x55),
and now it can handle 6 A.



Actually, BUCK1A and BUCK1B both combined together provide 6A capacity.
And as discussed earlier, we need board change for this.

I am quite not sure.


AFAIU the regulator driver creates one BUCK1 regulator with constraints
3 A. However after your change the regulator will handle up to 6 A.

This means that constraints set by driver are wrong.

Additionally I can't find BUCK1A and BUCK1B regulators. Driver provides
only BUCK1.



My patch does add BUCK1A and BUCK1B, please refer to the PATCH[4/5] of
earlier series, which is accepted.

https://patchwork.kernel.org/patch/6810461/




Should I read the property and update the constraint runtime during
probe?


Driver should provide real constraints. Find the proper way to do this.

The pm800_regulator_info[] array is not const so you can change it in
whatever way you want (although it should be const for existing driver
because regulator core accepts const and passing it to driver_data is
not necessary).




Probably that is the only way to handle this.

how about,

As you mentioned, pm800_regulator_info[] is not constant, so I can 
update the constraint before regulator_register() and also do not

register BUCK1B, if dual phase is enabled.

So in summary,

if (dual phase is enabled)
{
Update constraint of BUCK1 to 6A
and do not register BUCK1B
} else {
register both BUCK1A and BUCK1B with default constraint of 3A.
}

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


  1   2   3   4   >