Re: [PATCH v4 04/46] staging: emxx_udc: add ep capabilities support

2015-07-29 Thread Felipe Balbi
On Mon, Jul 27, 2015 at 11:16:14AM +0200, Robert Baldyga wrote:
 Convert endpoint configuration to new capabilities model.
 
 Fixed typo in epc-nulk to epc-bulk.
 
 Signed-off-by: Robert Baldyga r.bald...@samsung.com
 ---
  drivers/staging/emxx_udc/emxx_udc.c | 60 
 ++---
  1 file changed, 29 insertions(+), 31 deletions(-)
 
 diff --git a/drivers/staging/emxx_udc/emxx_udc.c 
 b/drivers/staging/emxx_udc/emxx_udc.c
 index 3b7aa36..0d64bee 100644
 --- a/drivers/staging/emxx_udc/emxx_udc.c
 +++ b/drivers/staging/emxx_udc/emxx_udc.c
 @@ -3153,36 +3153,33 @@ static const struct usb_gadget_ops nbu2ss_gadget_ops 
 = {
   .ioctl  = nbu2ss_gad_ioctl,
  };
  
 -static const char g_ep0_name[] = ep0;
 -static const char g_ep1_name[] = ep1-bulk;
 -static const char g_ep2_name[] = ep2-bulk;
 -static const char g_ep3_name[] = ep3in-int;
 -static const char g_ep4_name[] = ep4-iso;
 -static const char g_ep5_name[] = ep5-iso;
 -static const char g_ep6_name[] = ep6-bulk;
 -static const char g_ep7_name[] = ep7-bulk;
 -static const char g_ep8_name[] = ep8in-int;
 -static const char g_ep9_name[] = ep9-iso;
 -static const char g_epa_name[] = epa-iso;
 -static const char g_epb_name[] = epb-bulk;
 -static const char g_epc_name[] = epc-nulk;
 -static const char g_epd_name[] = epdin-int;
 -
 -static const char *gp_ep_name[NUM_ENDPOINTS] = {
 - g_ep0_name,
 - g_ep1_name,
 - g_ep2_name,
 - g_ep3_name,
 - g_ep4_name,
 - g_ep5_name,
 - g_ep6_name,
 - g_ep7_name,
 - g_ep8_name,
 - g_ep9_name,
 - g_epa_name,
 - g_epb_name,
 - g_epc_name,
 - g_epd_name,
 +static const struct {
 + const char *name;
 + const struct usb_ep_caps caps;
 +} ep_info[NUM_ENDPOINTS] = {
 +#define EP_INFO(_name, _type, _dir) \
 + { \
 + .name = _name, \
 + .caps = USB_EP_CAPS(USB_EP_CAPS_TYPE_ ## _type, \
 + USB_EP_CAPS_DIR_ ## _dir), \
 + }
 +
 + EP_INFO(ep0,  CONTROL, ALL),
 + EP_INFO(ep1-bulk, BULK,   ALL),
 + EP_INFO(ep2-bulk, BULK,   ALL),
 + EP_INFO(ep3in-int,INT,IN),
 + EP_INFO(ep4-iso,  INT,ALL),
 + EP_INFO(ep5-iso,  ISO,ALL),
 + EP_INFO(ep6-bulk, ISO,ALL),
 + EP_INFO(ep7-bulk, BULK,   ALL),
 + EP_INFO(ep8in-int,INT,IN),
 + EP_INFO(ep9-iso,  ISO,ALL),
 + EP_INFO(epa-iso,  ISO,ALL),
 + EP_INFO(epb-bulk, BULK,   ALL),
 + EP_INFO(epc-bulk, BULK,   ALL),
 + EP_INFO(epdin-int,INT,IN),

IMO, this is pointless obfuscation. It just makes it a pain to grep
source around. Why don't you have UDC drivers initialize the 1-bit flags
directly ?

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH 03/12] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver

2015-07-29 Thread Roger Quadros
On 29/07/15 17:08, nick wrote:
 
 
 On 2015-07-29 09:52 AM, Roger Quadros wrote:
 On 29/07/15 15:13, nick wrote:


 On 2015-07-29 08:06 AM, Roger Quadros wrote:
 Tony,

 On 13/07/15 15:40, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150713 03:07]:
 Tony,

 On 13/07/15 10:10, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150710 05:26]:
 Since the Interrupt Events are used only by the NAND driver,
 there is no point in managing the Interrupt registers
 in the GPMC driver and complicating it with irqchip modeling.

 I don't think it's a good idea to allow external drivers to
 tinker directly with GPMC registers. How about just set up GPMC
 as an irqchip for the edge detection interrupts?

 I think we already have devices with multiple NAND chips. And
 there's nothing stopping other drivers from using the edge
 detection interrupts.

 OK. The GPMC_IRQ registers manage 2 NAND specific interrupts
 (terminalcount and fifo) and 'n' WAIT pin edge interrupts.

  So we can model this as a irqchip with 'n + 2' interrupts.

 OK

 For the wait pins irqchip is not sufficient and it needs to be gpiochip
 with irqchip. Waitpin status can be read from GPIO_STATUS register.

 Just getting the interrupt is not enough and we want to know if the
 line is high or low. That is how nand-dev_ready works.

 How about having 2 IRQ domains?
 One is irqchip with 2 interrupts (terminalcount and fifo) and second is
 gpiochip + irqchip for the n wait pins.

 The nand driver can then be modified to use GPIO to get Read/Busy
 pin status from the wait pin.

 cheers,
 -roger

 Doesn't OMAP boards support shared IRQs and if so why not share them across 
 one
 IRQ domain if possible to save IRQ domains for other hardware that needs 
 its 
 own IRQ domain. This is just a suggestion through as I don't have the 
 hardware
 spec sheet on me Roger.

 IRQ domain is a virtual abstraction introduced to prevent kernel irq number 
 overlapping
 in a single flat domain. I don't see what you can save by domain reuse.
 Some memory maybe at most.

 Shared interrupt is something totally different but we're trying to add real
 hardware interrupts here. Didn't understand what you will share it with.

 cheers,
 -roger

 My question then is do these hardware interrupts need to be on their own 
 interrupt line
 for the CPU or can they share a CPU line as my concern is if possible we may 
 be able to
 save a interrupt line for other use. I known on Intel CPUs this is a very 
 limited resource
 but not sure on OMAP based boards if not then just avoid my recommendations.

It is like adding an external interrupt controller to expand the number of 
available
hardware interrupts.
This interrupt controller will still use the same GPMC IRQ line to propagate the
irq event upwards.

cheers,
-roger

 Nick 
 Nick 
  
 We need to take care that if a GPMC chip select needs a
 wait pin then it can't be used as a generic interrupt.

 We need to get rid of omap_dev_ready() in nand/omap2.c as
 it accesses the GPMC_STATUS register directly. Plus it is
 hard coded to only monitor wait0 pin.

 OK
  
 What is the best map we should use for irqchip?
 Some Socs have 4 WAIT pins, some have 3 and some have 2.

 Should we start with 0,1,2, for the wait pins and use the next
 available free one for the NAND?

 Maybe we can just use the bits defined for each SoC in the
 GPMC_IRQSTATUS register for the mapping?  
 Regards,

 Tony


 __
 Linux MTD discussion mailing list
 http://lists.infradead.org/mailman/listinfo/linux-mtd/

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/12] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver

2015-07-29 Thread Roger Quadros
On 29/07/15 18:26, nick wrote:
 
 
 On 2015-07-29 11:12 AM, Roger Quadros wrote:
 On 29/07/15 17:08, nick wrote:


 On 2015-07-29 09:52 AM, Roger Quadros wrote:
 On 29/07/15 15:13, nick wrote:


 On 2015-07-29 08:06 AM, Roger Quadros wrote:
 Tony,

 On 13/07/15 15:40, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150713 03:07]:
 Tony,

 On 13/07/15 10:10, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150710 05:26]:
 Since the Interrupt Events are used only by the NAND driver,
 there is no point in managing the Interrupt registers
 in the GPMC driver and complicating it with irqchip modeling.

 I don't think it's a good idea to allow external drivers to
 tinker directly with GPMC registers. How about just set up GPMC
 as an irqchip for the edge detection interrupts?

 I think we already have devices with multiple NAND chips. And
 there's nothing stopping other drivers from using the edge
 detection interrupts.

 OK. The GPMC_IRQ registers manage 2 NAND specific interrupts
 (terminalcount and fifo) and 'n' WAIT pin edge interrupts.

  So we can model this as a irqchip with 'n + 2' interrupts.

 OK

 For the wait pins irqchip is not sufficient and it needs to be gpiochip
 with irqchip. Waitpin status can be read from GPIO_STATUS register.

 Just getting the interrupt is not enough and we want to know if the
 line is high or low. That is how nand-dev_ready works.

 How about having 2 IRQ domains?
 One is irqchip with 2 interrupts (terminalcount and fifo) and second is
 gpiochip + irqchip for the n wait pins.

 The nand driver can then be modified to use GPIO to get Read/Busy
 pin status from the wait pin.

 cheers,
 -roger

 Doesn't OMAP boards support shared IRQs and if so why not share them 
 across one
 IRQ domain if possible to save IRQ domains for other hardware that needs 
 its 
 own IRQ domain. This is just a suggestion through as I don't have the 
 hardware
 spec sheet on me Roger.

 IRQ domain is a virtual abstraction introduced to prevent kernel irq 
 number overlapping
 in a single flat domain. I don't see what you can save by domain reuse.
 Some memory maybe at most.

 Shared interrupt is something totally different but we're trying to add 
 real
 hardware interrupts here. Didn't understand what you will share it with.

 cheers,
 -roger

 My question then is do these hardware interrupts need to be on their own 
 interrupt line
 for the CPU or can they share a CPU line as my concern is if possible we 
 may be able to
 save a interrupt line for other use. I known on Intel CPUs this is a very 
 limited resource
 but not sure on OMAP based boards if not then just avoid my recommendations.

 It is like adding an external interrupt controller to expand the number of 
 available
 hardware interrupts.
 This interrupt controller will still use the same GPMC IRQ line to propagate 
 the
 irq event upwards.

 cheers,
 -roger

 That was my other suggestion for IRQ issues. Would you mind sending me a link 
 to a spec sheet so
 I can review your patches better as you stated you wanted me to do this for 
 you.

Sure. You can pick up any of omap3/4 or 5 Technical Reference Manuals.
e.g. omap5 TRM is here
http://www.ti.com/product/OMAP5432/technicaldocuments

cheers,
-roger
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Gta04-owner] [PATCH 08/14] twl4030_charger: allow max_current to be managed via sysfs.

2015-07-29 Thread NeilBrown
On Mon, 23 Mar 2015 13:14:50 +0100 jake42
jak...@rommel.stw.uni-erlangen.de wrote:

 Hello Neil,
 
 some suggestions:
 
 On 23.03.2015 00:20, NeilBrown wrote:
  From: NeilBrown ne...@suse.de
  diff --git a/Documentation/ABI/testing/sysfs-class-power-twl4030
  b/Documentation/ABI/testing/sysfs-class-power-twl4030
  new file mode 100644
  index ..06092209d851
  --- /dev/null
  +++ b/Documentation/ABI/testing/sysfs-class-power-twl4030
  @@ -0,0 +1,15 @@
  +What: /sys/class/power_supply/twl4030_ac/max_current
  +  /sys/class/power_supply/twl4030_usb/max_current
  +Description:
  +   Read/Write limit on current which which may
 one less which^^
  +   be drawn from the ac (Accessory Charger) or
  +   USB port.
  +
  +   Value is in micro-Amps.
  +
  +   Value is set automatically to an appropriate
  +   value when a cable is plugged on unplugged.
 s/on/or   ^^
  +
  +   Value can the set by writing to the attribute.
^^ be set?
  +   The change will only persist until the next
  +   plug event.  These event are reported via udev.
 
 Regards
 Jake
 

Thanks.
I've made those two changes.

NeilBrown
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 12/17] ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node

2015-07-29 Thread Nishanth Menon
On 07/29/2015 06:09 AM, Kishon Vijay Abraham I wrote:
 For beagle x15, both the vdd and io lines are connected to the
 same regulator (ldo1_reg). However vmmc_aux is populated to vdd_3v3.
 Remove it.
 
 Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
 ---
  arch/arm/boot/dts/am57xx-beagle-x15.dts |1 -
  1 file changed, 1 deletion(-)
 
 diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts 
 b/arch/arm/boot/dts/am57xx-beagle-x15.dts
 index a63bf78..d0db5c5 100644
 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
 +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
 @@ -579,7 +579,6 @@
   pinctrl-0 = mmc1_pins_default;
  
   vmmc-supply = ldo1_reg;
 - vmmc_aux-supply = vdd_3v3;
   pbias-supply = pbias_mmc_reg;
   bus-width = 4;
   cd-gpios = gpio6 27 0; /* gpio 219 */
 
Acked-by: Nishanth Menon n...@ti.com

-- 
Regards,
Nishanth Menon
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/13] twl4030_charger: correctly handle -EPROBE_DEFER from devm_usb_get_phy_by_node

2015-07-29 Thread NeilBrown
Now that twl4030_bci_probe can safely return -EPROBE_DEFER,
do so when devm_usb_get_phy_by_node returns that error.

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 045238370d3f..ffc123fb7158 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -636,9 +636,13 @@ static int twl4030_bci_probe(struct platform_device *pdev)
 
phynode = of_find_compatible_node(bci-dev-of_node-parent,
  NULL, ti,twl4030-usb);
-   if (phynode)
+   if (phynode) {
bci-transceiver = devm_usb_get_phy_by_node(
bci-dev, phynode, bci-usb_nb);
+   if (IS_ERR(bci-transceiver) 
+   PTR_ERR(bci-transceiver) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+   }
}
 
/* Enable interrupts now. */


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/13] twl4030_charger: convert to module_platform_driver instead of ..._probe.

2015-07-29 Thread NeilBrown
From: Pavel Machek pa...@ucw.cz

Drivers using module_platform_driver_probe cannot return
EPROBE_DEFER from the probe function, which makes them rather useless
these days...

Convert to module_platform_driver() so EPROBE_DEFER can be used.

Signed-off-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index fe71c61109f5..045238370d3f 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -568,7 +568,7 @@ static const struct power_supply_desc twl4030_bci_usb_desc 
= {
.get_property   = twl4030_bci_get_property,
 };
 
-static int __init twl4030_bci_probe(struct platform_device *pdev)
+static int twl4030_bci_probe(struct platform_device *pdev)
 {
struct twl4030_bci *bci;
const struct twl4030_bci_platform_data *pdata = pdev-dev.platform_data;
@@ -692,14 +692,14 @@ static const struct of_device_id twl_bci_of_match[] = {
 MODULE_DEVICE_TABLE(of, twl_bci_of_match);
 
 static struct platform_driver twl4030_bci_driver = {
+   .probe = twl4030_bci_probe,
.driver = {
.name   = twl4030_bci,
.of_match_table = of_match_ptr(twl_bci_of_match),
},
.remove = __exit_p(twl4030_bci_remove),
 };
-
-module_platform_driver_probe(twl4030_bci_driver, twl4030_bci_probe);
+module_platform_driver(twl4030_bci_driver);
 
 MODULE_AUTHOR(GraÅžvydas Ignotas);
 MODULE_DESCRIPTION(TWL4030 Battery Charger Interface driver);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/13] twl4030_charger: allow fine control of charger current.

2015-07-29 Thread NeilBrown
The twl4030 allows control of the incoming current.
Part of this control is a 'CGAIN' setting which doubles
the range for half the precision.  This control affects
several different current setting, so all need to be updated
at once when CGAIN is changed.

With this patch, all of these current setting are managed
by the driver, but most are left at their default settings.

The current drawn is set to 500mA if the allow_usb module parameter is
set, and to 100mA otherwise.
More fine control will appear in later patches.

Acked-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |  168 +--
 1 file changed, 160 insertions(+), 8 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 29984b263a35..3b7cc631bb8a 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -31,6 +31,11 @@
 #define TWL4030_BCIMFSTS4  0x10
 #define TWL4030_BCICTL10x23
 #define TWL4030_BB_CFG 0x12
+#define TWL4030_BCIIREF1   0x27
+#define TWL4030_BCIIREF2   0x28
+#define TWL4030_BCIMFKEY   0x11
+#define TWL4030_BCIMFTH8   0x1d
+#define TWL4030_BCIMFTH9   0x1e
 
 #define TWL4030_BCIMFSTS1  0x01
 
@@ -95,6 +100,12 @@ struct twl4030_bci {
int irq_bci;
int usb_enabled;
 
+   /*
+* ichg values in uA. If any are 'large', we set CGAIN to
+* '1' which doubles the range for half the precision.
+*/
+   unsigned intichg_eoc, ichg_lo, ichg_hi, cur;
+
unsigned long   event;
 };
 
@@ -211,6 +222,146 @@ static int ua2regval(int ua, bool cgain)
return ret;
 }
 
+static int twl4030_charger_update_current(struct twl4030_bci *bci)
+{
+   int status;
+   unsigned reg, cur_reg;
+   u8 bcictl1, oldreg, fullreg;
+   bool cgain = false;
+   u8 boot_bci;
+
+   /* First, check thresholds and see if cgain is needed */
+   if (bci-ichg_eoc = 20)
+   cgain = true;
+   if (bci-ichg_lo = 40)
+   cgain = true;
+   if (bci-ichg_hi = 82)
+   cgain = true;
+   if (bci-cur  852000)
+   cgain = true;
+
+   status = twl4030_bci_read(TWL4030_BCICTL1, bcictl1);
+   if (status  0)
+   return status;
+   if (twl_i2c_read_u8(TWL_MODULE_PM_MASTER, boot_bci,
+   TWL4030_PM_MASTER_BOOT_BCI)  0)
+   boot_bci = 0;
+   boot_bci = 7;
+
+   if ((!!cgain) != !!(bcictl1  TWL4030_CGAIN))
+   /* Need to turn for charging while we change the
+* CGAIN bit.  Leave it off while everything is
+* updated.
+*/
+   twl4030_clear_set_boot_bci(boot_bci, 0);
+
+   /*
+* For ichg_eoc, the hardware only supports reg values matching
+* 100000, and requires the  be stored in the high nibble
+* of TWL4030_BCIMFTH8.
+*/
+   reg = ua2regval(bci-ichg_eoc, cgain);
+   if (reg  0x278)
+   reg = 0x278;
+   if (reg  0x200)
+   reg = 0x200;
+   reg = (reg  3)  0xf;
+   fullreg = reg  4;
+
+   /*
+* For ichg_lo, reg value must match 10.
+*  is stored in low nibble of TWL4030_BCIMFTH8.
+*/
+   reg = ua2regval(bci-ichg_lo, cgain);
+   if (reg  0x2F0)
+   reg = 0x2F0;
+   if (reg  0x200)
+   reg = 0x200;
+   reg = (reg  4)  0xf;
+   fullreg |= reg;
+
+   /* ichg_eoc and ichg_lo live in same register */
+   status = twl4030_bci_read(TWL4030_BCIMFTH8, oldreg);
+   if (status  0)
+   return status;
+   if (oldreg != fullreg) {
+   status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xF4,
+ TWL4030_BCIMFKEY);
+   if (status  0)
+   return status;
+   twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
+fullreg, TWL4030_BCIMFTH8);
+   }
+
+   /* ichg_hi threshold must be 101100 (I think) */
+   reg = ua2regval(bci-ichg_hi, cgain);
+   if (reg  0x3E0)
+   reg = 0x3E0;
+   if (reg  0x200)
+   reg = 0x200;
+   fullreg = (reg  5)  0xF;
+   fullreg = 4;
+   status = twl4030_bci_read(TWL4030_BCIMFTH9, oldreg);
+   if (status  0)
+   return status;
+   if ((oldreg  0xF0) != fullreg) {
+   fullreg |= (oldreg  0x0F);
+   status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7,
+ TWL4030_BCIMFKEY);
+   if (status  0)
+   return status;
+   twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
+fullreg, TWL4030_BCIMFTH9);
+   }
+
+   /*
+

[PATCH 00/13] Enhance twl4030_charger functionality. - V3

2015-07-29 Thread NeilBrown

Following is most of my twl4030_charger patches, rebased against
 git://git.infradead.org/battery-2.6

Since the previous set I have added the conversion to
module_platform_driver so EPROBE_DEFER can be used, and fixed
a few minor typos.

This does not include the changes to add extcon support, in part
because extcon has seen some changes lately which leave me even more
confused about how best to use it than before.
I need to sort that out before I can resolve the rest of my usb phy
patches and then add a few more charger patches.

Thanks,
NeilBrown


---

NeilBrown (12):
  twl4030_charger: use runtime_pm to keep usb phy active while charging.
  twl4030_charger: correctly handle -EPROBE_DEFER from 
devm_usb_get_phy_by_node
  twl4030_charger: trust phy to determine when USB power is available.
  twl4030_charger: split uA calculation into a function.
  twl4030_charger: allow fine control of charger current.
  twl4030_charger: distinguish between USB current and 'AC' current
  twl4030_charger: allow max_current to be managed via sysfs.
  twl4030_charger: enable manual enable/disable of usb charging.
  twl4030_charger: add software controlled linear charging mode.
  twl4030_charger: add ac/mode to match usb/mode
  twl4030_charger: Increase current carefully while watching voltage.
  twl4030_charger: assume a 'charger' can supply maximum current.

Pavel Machek (1):
  twl4030_charger: convert to module_platform_driver instead of ..._probe.


 .../ABI/testing/sysfs-class-power-twl4030  |   45 ++
 drivers/mfd/twl-core.c |9 
 drivers/power/twl4030_charger.c|  541 ++--
 3 files changed, 531 insertions(+), 64 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-twl4030

--
Signature

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/13] twl4030_charger: allow max_current to be managed via sysfs.

2015-07-29 Thread NeilBrown
'max_current' sysfs attributes are created which allow the
max to be set.
Whenever a current source changes, the default is restored.
This will be followed by a uevent, so user-space can decide to
update again.

Acked-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 .../ABI/testing/sysfs-class-power-twl4030  |   15 
 drivers/power/twl4030_charger.c|   72 
 2 files changed, 87 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-power-twl4030

diff --git a/Documentation/ABI/testing/sysfs-class-power-twl4030 
b/Documentation/ABI/testing/sysfs-class-power-twl4030
new file mode 100644
index ..0331bba4605d
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-power-twl4030
@@ -0,0 +1,15 @@
+What: /sys/class/power_supply/twl4030_ac/max_current
+  /sys/class/power_supply/twl4030_usb/max_current
+Description:
+   Read/Write limit on current which may
+   be drawn from the ac (Accessory Charger) or
+   USB port.
+
+   Value is in micro-Amps.
+
+   Value is set automatically to an appropriate
+   value when a cable is plugged or unplugged.
+
+   Value can the set by writing to the attribute.
+   The change will only persist until the next
+   plug event.  These event are reported via udev.
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 982675df21b7..b0a50adebfda 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -482,6 +482,8 @@ static irqreturn_t twl4030_charger_interrupt(int irq, void 
*arg)
struct twl4030_bci *bci = arg;
 
dev_dbg(bci-dev, CHG_PRES irq\n);
+   /* reset current on each 'plug' event */
+   bci-ac_cur = 50;
twl4030_charger_update_current(bci);
power_supply_changed(bci-ac);
power_supply_changed(bci-usb);
@@ -536,6 +538,63 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void 
*arg)
return IRQ_HANDLED;
 }
 
+/*
+ * Provide max_current attribute in sysfs.
+ */
+static ssize_t
+twl4030_bci_max_current_store(struct device *dev, struct device_attribute 
*attr,
+   const char *buf, size_t n)
+{
+   struct twl4030_bci *bci = dev_get_drvdata(dev-parent);
+   int cur = 0;
+   int status = 0;
+   status = kstrtoint(buf, 10, cur);
+   if (status)
+   return status;
+   if (cur  0)
+   return -EINVAL;
+   if (dev == bci-ac-dev)
+   bci-ac_cur = cur;
+   else
+   bci-usb_cur = cur;
+
+   twl4030_charger_update_current(bci);
+   return n;
+}
+
+/*
+ * sysfs max_current show
+ */
+static ssize_t twl4030_bci_max_current_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   int status = 0;
+   int cur = -1;
+   u8 bcictl1;
+   struct twl4030_bci *bci = dev_get_drvdata(dev-parent);
+
+   if (dev == bci-ac-dev) {
+   if (!bci-ac_is_active)
+   cur = bci-ac_cur;
+   } else {
+   if (bci-ac_is_active)
+   cur = bci-usb_cur;
+   }
+   if (cur  0) {
+   cur = twl4030bci_read_adc_val(TWL4030_BCIIREF1);
+   if (cur  0)
+   return cur;
+   status = twl4030_bci_read(TWL4030_BCICTL1, bcictl1);
+   if (status  0)
+   return status;
+   cur = regval2ua(cur, bcictl1  TWL4030_CGAIN);
+   }
+   return scnprintf(buf, PAGE_SIZE, %u\n, cur);
+}
+
+static DEVICE_ATTR(max_current, 0644, twl4030_bci_max_current_show,
+   twl4030_bci_max_current_store);
+
 static void twl4030_bci_usb_work(struct work_struct *data)
 {
struct twl4030_bci *bci = container_of(data, struct twl4030_bci, work);
@@ -558,6 +617,12 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, 
unsigned long val,
 
dev_dbg(bci-dev, OTG notify %lu\n, val);
 
+   /* reset current on each 'plug' event */
+   if (allow_usb)
+   bci-usb_cur = 50;
+   else
+   bci-usb_cur = 10;
+
bci-event = val;
schedule_work(bci-work);
 
@@ -831,6 +896,11 @@ static int twl4030_bci_probe(struct platform_device *pdev)
dev_warn(pdev-dev, failed to unmask interrupts: %d\n, ret);
 
twl4030_charger_update_current(bci);
+   if (device_create_file(bci-usb-dev, dev_attr_max_current))
+   dev_warn(pdev-dev, could not create sysfs file\n);
+   if (device_create_file(bci-ac-dev, dev_attr_max_current))
+   dev_warn(pdev-dev, could not create sysfs file\n);
+
twl4030_charger_enable_ac(true);
if (!IS_ERR_OR_NULL(bci-transceiver))
twl4030_bci_usb_ncb(bci-usb_nb,
@@ -855,6 +925,8 @@ static int __exit twl4030_bci_remove(struct platform_device 
*pdev)
twl4030_charger_enable_usb(bci, false);

[PATCH 04/13] twl4030_charger: trust phy to determine when USB power is available.

2015-07-29 Thread NeilBrown
The usb phy driver already determines when VBUS is available,
so repeating the test in the charger driver is pointless duplication.

On probe, process the last event from the phy, and from then on,
do whatever the phy tells us without double-checking.

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |   33 ++---
 1 file changed, 6 insertions(+), 27 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index ffc123fb7158..a075216d65ed 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -178,28 +178,6 @@ static int twl4030_is_battery_present(struct twl4030_bci 
*bci)
 }
 
 /*
- * Check if VBUS power is present
- */
-static int twl4030_bci_have_vbus(struct twl4030_bci *bci)
-{
-   int ret;
-   u8 hwsts;
-
-   ret = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, hwsts,
- TWL4030_PM_MASTER_STS_HW_CONDITIONS);
-   if (ret  0)
-   return 0;
-
-   dev_dbg(bci-dev, check_vbus: HW_CONDITIONS %02x\n, hwsts);
-
-   /* in case we also have STS_USB_ID, VBUS is driven by TWL itself */
-   if ((hwsts  TWL4030_STS_VBUS)  !(hwsts  TWL4030_STS_USB_ID))
-   return 1;
-
-   return 0;
-}
-
-/*
  * Enable/Disable USB Charge functionality.
  */
 static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
@@ -207,10 +185,6 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
int ret;
 
if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
-   /* Check for USB charger connected */
-   if (!twl4030_bci_have_vbus(bci))
-   return -ENODEV;
-
/*
 * Until we can find out what current the device can provide,
 * require a module param to enable USB charging.
@@ -662,7 +636,12 @@ static int twl4030_bci_probe(struct platform_device *pdev)
dev_warn(pdev-dev, failed to unmask interrupts: %d\n, ret);
 
twl4030_charger_enable_ac(true);
-   twl4030_charger_enable_usb(bci, true);
+   if (!IS_ERR_OR_NULL(bci-transceiver))
+   twl4030_bci_usb_ncb(bci-usb_nb,
+   bci-transceiver-last_event,
+   NULL);
+   else
+   twl4030_charger_enable_usb(bci, false);
if (pdata)
twl4030_charger_enable_backup(pdata-bb_uvolt,
  pdata-bb_uamp);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/13] twl4030_charger: enable manual enable/disable of usb charging.

2015-07-29 Thread NeilBrown
'off' or 'auto' to

 /sys/class/power/twl4030_usb/mode

will now enable or disable charging from USB port.  Normally this is
enabled on 'plug' and disabled on 'unplug'.
Unplug will still disable charging.  'plug' will only enable it if
'auto' if selected.

Acked-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 .../ABI/testing/sysfs-class-power-twl4030  |   11 
 drivers/power/twl4030_charger.c|   59 
 2 files changed, 70 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-power-twl4030 
b/Documentation/ABI/testing/sysfs-class-power-twl4030
index 0331bba4605d..40e0f919cbde 100644
--- a/Documentation/ABI/testing/sysfs-class-power-twl4030
+++ b/Documentation/ABI/testing/sysfs-class-power-twl4030
@@ -13,3 +13,14 @@ Description:
Value can the set by writing to the attribute.
The change will only persist until the next
plug event.  These event are reported via udev.
+
+
+What: /sys/class/power_supply/twl4030_usb/mode
+Description:
+   Changing mode for USB port.
+   Writing to this can disable charging.
+
+   Possible values are:
+   auto - draw power as appropriate for detected
+power source and battery status.
+   off  - do not draw any power.
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index b0a50adebfda..6fa928ed3128 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -109,10 +109,16 @@ struct twl4030_bci {
unsigned intichg_eoc, ichg_lo, ichg_hi;
unsigned intusb_cur, ac_cur;
boolac_is_active;
+   int usb_mode; /* charging mode requested */
+#defineCHARGE_OFF  0
+#defineCHARGE_AUTO 1
 
unsigned long   event;
 };
 
+/* strings for 'usb_mode' values */
+static char *modes[] = { off, auto };
+
 /*
  * clear and set bits on an given register on a given module
  */
@@ -386,6 +392,8 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
 {
int ret;
 
+   if (bci-usb_mode == CHARGE_OFF)
+   enable = false;
if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
 
twl4030_charger_update_current(bci);
@@ -629,6 +637,53 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, 
unsigned long val,
return NOTIFY_OK;
 }
 
+/*
+ * sysfs charger enabled store
+ */
+static ssize_t
+twl4030_bci_mode_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+   struct twl4030_bci *bci = dev_get_drvdata(dev-parent);
+   int mode;
+   int status;
+
+   if (sysfs_streq(buf, modes[0]))
+   mode = 0;
+   else if (sysfs_streq(buf, modes[1]))
+   mode = 1;
+   else
+   return -EINVAL;
+   twl4030_charger_enable_usb(bci, false);
+   bci-usb_mode = mode;
+   status = twl4030_charger_enable_usb(bci, true);
+   return (status == 0) ? n : status;
+}
+
+/*
+ * sysfs charger enabled show
+ */
+static ssize_t
+twl4030_bci_mode_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct twl4030_bci *bci = dev_get_drvdata(dev-parent);
+   int len = 0;
+   int i;
+
+   for (i = 0; i  ARRAY_SIZE(modes); i++)
+   if (bci-usb_mode == i)
+   len += snprintf(buf+len, PAGE_SIZE-len,
+   [%s] , modes[i]);
+   else
+   len += snprintf(buf+len, PAGE_SIZE-len,
+   %s , modes[i]);
+   buf[len-1] = '\n';
+   return len;
+}
+static DEVICE_ATTR(mode, 0644, twl4030_bci_mode_show,
+  twl4030_bci_mode_store);
+
 static int twl4030_charger_get_current(void)
 {
int curr;
@@ -815,6 +870,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
bci-usb_cur = 50;  /* 500mA */
else
bci-usb_cur = 10;  /* 100mA */
+   bci-usb_mode = CHARGE_AUTO;
 
bci-dev = pdev-dev;
bci-irq_chg = platform_get_irq(pdev, 0);
@@ -898,6 +954,8 @@ static int twl4030_bci_probe(struct platform_device *pdev)
twl4030_charger_update_current(bci);
if (device_create_file(bci-usb-dev, dev_attr_max_current))
dev_warn(pdev-dev, could not create sysfs file\n);
+   if (device_create_file(bci-usb-dev, dev_attr_mode))
+   dev_warn(pdev-dev, could not create sysfs file\n);
if (device_create_file(bci-ac-dev, dev_attr_max_current))
dev_warn(pdev-dev, could not create sysfs file\n);
 
@@ -926,6 +984,7 @@ static int __exit twl4030_bci_remove(struct platform_device 
*pdev)
twl4030_charger_enable_backup(0, 0);
 
device_remove_file(bci-usb-dev, 

[PATCH 07/13] twl4030_charger: distinguish between USB current and 'AC' current

2015-07-29 Thread NeilBrown

The twl4030 charger has two current sources, 'USB' and 'AC'
(presumably Accessory Charger because it isn't Alternating Current).

If 'AC' is providing current, we should set the current limit
differently to when it isn't (and so USB is used).
So split 'cur' into 'usb_cur' and 'ac_cur' and use accordingly.

Now we must review the current setting on any interrupt or USB
event which might indicate that the charger-source has changed.

Acked-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |   36 +---
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 3b7cc631bb8a..982675df21b7 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -22,6 +22,7 @@
 #include linux/power_supply.h
 #include linux/notifier.h
 #include linux/usb/otg.h
+#include linux/i2c/twl4030-madc.h
 
 #define TWL4030_BCIMSTATEC 0x02
 #define TWL4030_BCIICHG0x08
@@ -101,10 +102,13 @@ struct twl4030_bci {
int usb_enabled;
 
/*
-* ichg values in uA. If any are 'large', we set CGAIN to
-* '1' which doubles the range for half the precision.
+* ichg_* and *_cur values in uA. If any are 'large', we set
+* CGAIN to '1' which doubles the range for half the
+* precision.
 */
-   unsigned intichg_eoc, ichg_lo, ichg_hi, cur;
+   unsigned intichg_eoc, ichg_lo, ichg_hi;
+   unsigned intusb_cur, ac_cur;
+   boolac_is_active;
 
unsigned long   event;
 };
@@ -225,11 +229,24 @@ static int ua2regval(int ua, bool cgain)
 static int twl4030_charger_update_current(struct twl4030_bci *bci)
 {
int status;
+   int cur;
unsigned reg, cur_reg;
u8 bcictl1, oldreg, fullreg;
bool cgain = false;
u8 boot_bci;
 
+   /*
+* If AC (Accessory Charger) voltage exceeds 4.5V (MADC 11)
+* and AC is enabled, set current for 'ac'
+*/
+   if (twl4030_get_madc_conversion(11)  4500) {
+   cur = bci-ac_cur;
+   bci-ac_is_active = true;
+   } else {
+   cur = bci-usb_cur;
+   bci-ac_is_active = false;
+   }
+
/* First, check thresholds and see if cgain is needed */
if (bci-ichg_eoc = 20)
cgain = true;
@@ -237,7 +254,7 @@ static int twl4030_charger_update_current(struct 
twl4030_bci *bci)
cgain = true;
if (bci-ichg_hi = 82)
cgain = true;
-   if (bci-cur  852000)
+   if (cur  852000)
cgain = true;
 
status = twl4030_bci_read(TWL4030_BCICTL1, bcictl1);
@@ -318,7 +335,7 @@ static int twl4030_charger_update_current(struct 
twl4030_bci *bci)
 * And finally, set the current.  This is stored in
 * two registers.
 */
-   reg = ua2regval(bci-cur, cgain);
+   reg = ua2regval(cur, cgain);
/* we have only 10 bits */
if (reg  0x3ff)
reg = 0x3ff;
@@ -371,6 +388,8 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
 
if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
 
+   twl4030_charger_update_current(bci);
+
/* Need to keep phy powered */
if (!bci-usb_enabled) {
pm_runtime_get_sync(bci-transceiver-dev);
@@ -463,6 +482,7 @@ static irqreturn_t twl4030_charger_interrupt(int irq, void 
*arg)
struct twl4030_bci *bci = arg;
 
dev_dbg(bci-dev, CHG_PRES irq\n);
+   twl4030_charger_update_current(bci);
power_supply_changed(bci-ac);
power_supply_changed(bci-usb);
 
@@ -495,6 +515,7 @@ static irqreturn_t twl4030_bci_interrupt(int irq, void *arg)
power_supply_changed(bci-ac);
power_supply_changed(bci-usb);
}
+   twl4030_charger_update_current(bci);
 
/* various monitoring events, for now we just log them here */
if (irqs1  (TWL4030_TBATOR2 | TWL4030_TBATOR1))
@@ -724,10 +745,11 @@ static int twl4030_bci_probe(struct platform_device *pdev)
bci-ichg_eoc = 80100; /* Stop charging when current drops to here */
bci-ichg_lo = 241000; /* Low threshold */
bci-ichg_hi = 50; /* High threshold */
+   bci-ac_cur = 50; /* 500mA */
if (allow_usb)
-   bci-cur = 50;  /* 500mA */
+   bci-usb_cur = 50;  /* 500mA */
else
-   bci-cur = 10;  /* 100mA */
+   bci-usb_cur = 10;  /* 100mA */
 
bci-dev = pdev-dev;
bci-irq_chg = platform_get_irq(pdev, 0);


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  

[PATCH 05/13] twl4030_charger: split uA calculation into a function.

2015-07-29 Thread NeilBrown
We will need this calculation in other places, so
create functions to map between register value and uA value.

Acked-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |   48 ---
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index a075216d65ed..29984b263a35 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -178,6 +178,40 @@ static int twl4030_is_battery_present(struct twl4030_bci 
*bci)
 }
 
 /*
+ * TI provided formulas:
+ * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85
+ * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7
+ * Here we use integer approximation of:
+ * CGAIN == 0: val * 1.6618 - 0.85 * 1000
+ * CGAIN == 1: (val * 1.6618 - 0.85 * 1000) * 2
+ */
+/*
+ * convert twl register value for currents into uA
+ */
+static int regval2ua(int regval, bool cgain)
+{
+   if (cgain)
+   return (regval * 16618 - 8500 * 1000) / 5;
+   else
+   return (regval * 16618 - 8500 * 1000) / 10;
+}
+
+/*
+ * convert uA currents into twl register value
+ */
+static int ua2regval(int ua, bool cgain)
+{
+   int ret;
+   if (cgain)
+   ua /= 2;
+   ret = (ua * 10 + 8500 * 1000) / 16618;
+   /* rounding problems */
+   if (ret  512)
+   ret = 512;
+   return ret;
+}
+
+/*
  * Enable/Disable USB Charge functionality.
  */
 static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
@@ -366,14 +400,6 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, 
unsigned long val,
return NOTIFY_OK;
 }
 
-/*
- * TI provided formulas:
- * CGAIN == 0: ICHG = (BCIICHG * 1.7) / (2^10 - 1) - 0.85
- * CGAIN == 1: ICHG = (BCIICHG * 3.4) / (2^10 - 1) - 1.7
- * Here we use integer approximation of:
- * CGAIN == 0: val * 1.6618 - 0.85
- * CGAIN == 1: (val * 1.6618 - 0.85) * 2
- */
 static int twl4030_charger_get_current(void)
 {
int curr;
@@ -388,11 +414,7 @@ static int twl4030_charger_get_current(void)
if (ret)
return ret;
 
-   ret = (curr * 16618 - 850 * 1) / 10;
-   if (bcictl1  TWL4030_CGAIN)
-   ret *= 2;
-
-   return ret;
+   return regval2ua(curr, bcictl1  TWL4030_CGAIN);
 }
 
 /*


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/13] twl4030_charger: use runtime_pm to keep usb phy active while charging.

2015-07-29 Thread NeilBrown
The twl4030 usb phy needs to be active while we are using
the USB VBUS as a current source for charging.
In particular, the usb3v1 regulator must be enabled and the
PHY_PWR_PHYPWD bit must be set to keep the phy powered.

commit ab37813f4093a5f59cb8e083cde277289dc72ed3
twl4030_charger: Allow charger to control the regulator that feeds it

gave the charger control over the regulator, but didn't resolve
the PHY_PWR_PHYPWD issue.

Now that both of these are controlled by runtime_pm in
phy-twl4030-usb, we can simply take a runtime_pm reference to the USB
phy whenever the charger wants to use it as a current source.

So this patch reverts the above commit, and adds the necessary
runtime_pm calls.

Acked-by: Lee Jones lee.jo...@linaro.org
Signed-off-by: NeilBrown n...@brown.name
---
 drivers/mfd/twl-core.c  |9 -
 drivers/power/twl4030_charger.c |   18 +-
 2 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 489674a2497e..831696ee2472 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -788,9 +788,8 @@ add_children(struct twl4030_platform_data *pdata, unsigned 
irq_base,
static struct regulator_consumer_supply usb1v8 = {
.supply =   usb1v8,
};
-   static struct regulator_consumer_supply usb3v1[] = {
-   { .supply = usb3v1 },
-   { .supply = bci3v1 },
+   static struct regulator_consumer_supply usb3v1 = {
+   .supply =   usb3v1,
};
 
/* First add the regulators so that they can be used by transceiver */
@@ -818,7 +817,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned 
irq_base,
return PTR_ERR(child);
 
child = add_regulator_linked(TWL4030_REG_VUSB3V1,
- usb_fixed, usb3v1, 2,
+ usb_fixed, usb3v1, 1,
  features);
if (IS_ERR(child))
return PTR_ERR(child);
@@ -838,7 +837,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned 
irq_base,
if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)  child) {
usb1v5.dev_name = dev_name(child);
usb1v8.dev_name = dev_name(child);
-   usb3v1[0].dev_name = dev_name(child);
+   usb3v1.dev_name = dev_name(child);
}
}
 
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 709d90dc75f1..fe71c61109f5 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -22,7 +22,6 @@
 #include linux/power_supply.h
 #include linux/notifier.h
 #include linux/usb/otg.h
-#include linux/regulator/machine.h
 
 #define TWL4030_BCIMSTATEC 0x02
 #define TWL4030_BCIICHG0x08
@@ -94,7 +93,6 @@ struct twl4030_bci {
struct work_struct  work;
int irq_chg;
int irq_bci;
-   struct regulator*usb_reg;
int usb_enabled;
 
unsigned long   event;
@@ -208,7 +206,7 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
 {
int ret;
 
-   if (enable) {
+   if (enable  !IS_ERR_OR_NULL(bci-transceiver)) {
/* Check for USB charger connected */
if (!twl4030_bci_have_vbus(bci))
return -ENODEV;
@@ -222,14 +220,9 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
return -EACCES;
}
 
-   /* Need to keep regulator on */
+   /* Need to keep phy powered */
if (!bci-usb_enabled) {
-   ret = regulator_enable(bci-usb_reg);
-   if (ret) {
-   dev_err(bci-dev,
-   Failed to enable regulator\n);
-   return ret;
-   }
+   pm_runtime_get_sync(bci-transceiver-dev);
bci-usb_enabled = 1;
}
 
@@ -244,7 +237,8 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
} else {
ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0);
if (bci-usb_enabled) {
-   regulator_disable(bci-usb_reg);
+   pm_runtime_mark_last_busy(bci-transceiver-dev);
+   pm_runtime_put_autosuspend(bci-transceiver-dev);
bci-usb_enabled = 0;
}
}
@@ -609,8 +603,6 @@ static int __init twl4030_bci_probe(struct 

[PATCH 11/13] twl4030_charger: add ac/mode to match usb/mode

2015-07-29 Thread NeilBrown

This allows AC charging to be turned off, much like usb charging.
continuous mode is not available though.

Acked-by: Pavel Machek pa...@ucw.cz
Signed-off-by: NeilBrown n...@brown.name
---
 .../ABI/testing/sysfs-class-power-twl4030  |   10 ++
 drivers/power/twl4030_charger.c|   35 +++-
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-power-twl4030 
b/Documentation/ABI/testing/sysfs-class-power-twl4030
index e8baa36aaa2b..be26af0f1895 100644
--- a/Documentation/ABI/testing/sysfs-class-power-twl4030
+++ b/Documentation/ABI/testing/sysfs-class-power-twl4030
@@ -33,3 +33,13 @@ Description:
 This is useful for unstable power sources
 such as bicycle dynamo, but care should
 be taken that battery is not over-charged.
+
+What: /sys/class/power_supply/twl4030_ac/mode
+Description:
+   Changing mode for 'ac' port.
+   Writing to this can disable charging.
+
+   Possible values are:
+   auto - draw power as appropriate for detected
+power source and battery status.
+   off  - do not draw any power.
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index de5430deaf23..68117ad23564 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -114,7 +114,7 @@ struct twl4030_bci {
unsigned intichg_eoc, ichg_lo, ichg_hi;
unsigned intusb_cur, ac_cur;
boolac_is_active;
-   int usb_mode; /* charging mode requested */
+   int usb_mode, ac_mode; /* charging mode requested */
 #defineCHARGE_OFF  0
 #defineCHARGE_AUTO 1
 #defineCHARGE_LINEAR   2
@@ -459,10 +459,13 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
 /*
  * Enable/Disable AC Charge funtionality.
  */
-static int twl4030_charger_enable_ac(bool enable)
+static int twl4030_charger_enable_ac(struct twl4030_bci *bci, bool enable)
 {
int ret;
 
+   if (bci-ac_mode == CHARGE_OFF)
+   enable = false;
+
if (enable)
ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOAC);
else
@@ -688,9 +691,17 @@ twl4030_bci_mode_store(struct device *dev, struct 
device_attribute *attr,
mode = 2;
else
return -EINVAL;
-   twl4030_charger_enable_usb(bci, false);
-   bci-usb_mode = mode;
-   status = twl4030_charger_enable_usb(bci, true);
+   if (dev == bci-ac-dev) {
+   if (mode == 2)
+   return -EINVAL;
+   twl4030_charger_enable_ac(bci, false);
+   bci-ac_mode = mode;
+   status = twl4030_charger_enable_ac(bci, true);
+   } else {
+   twl4030_charger_enable_usb(bci, false);
+   bci-usb_mode = mode;
+   status = twl4030_charger_enable_usb(bci, true);
+   }
return (status == 0) ? n : status;
 }
 
@@ -704,9 +715,13 @@ twl4030_bci_mode_show(struct device *dev,
struct twl4030_bci *bci = dev_get_drvdata(dev-parent);
int len = 0;
int i;
+   int mode = bci-usb_mode;
+
+   if (dev == bci-ac-dev)
+   mode = bci-ac_mode;
 
for (i = 0; i  ARRAY_SIZE(modes); i++)
-   if (bci-usb_mode == i)
+   if (mode == i)
len += snprintf(buf+len, PAGE_SIZE-len,
[%s] , modes[i]);
else
@@ -916,6 +931,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
else
bci-usb_cur = 10;  /* 100mA */
bci-usb_mode = CHARGE_AUTO;
+   bci-ac_mode = CHARGE_AUTO;
 
bci-dev = pdev-dev;
bci-irq_chg = platform_get_irq(pdev, 0);
@@ -1001,10 +1017,12 @@ static int twl4030_bci_probe(struct platform_device 
*pdev)
dev_warn(pdev-dev, could not create sysfs file\n);
if (device_create_file(bci-usb-dev, dev_attr_mode))
dev_warn(pdev-dev, could not create sysfs file\n);
+   if (device_create_file(bci-ac-dev, dev_attr_mode))
+   dev_warn(pdev-dev, could not create sysfs file\n);
if (device_create_file(bci-ac-dev, dev_attr_max_current))
dev_warn(pdev-dev, could not create sysfs file\n);
 
-   twl4030_charger_enable_ac(true);
+   twl4030_charger_enable_ac(bci, true);
if (!IS_ERR_OR_NULL(bci-transceiver))
twl4030_bci_usb_ncb(bci-usb_nb,
bci-transceiver-last_event,
@@ -1024,13 +1042,14 @@ static int __exit twl4030_bci_remove(struct 
platform_device *pdev)
 {
struct twl4030_bci *bci = platform_get_drvdata(pdev);
 
-   twl4030_charger_enable_ac(false);
+   twl4030_charger_enable_ac(bci, 

Re: [PATCH v2 2/5] ARM: OMAP2+: DRA7: Add hwmod entries for PWMSS

2015-07-29 Thread Vignesh R


On 07/23/2015 09:05 PM, R, Vignesh wrote:
 
 
 On 7/16/2015 9:01 PM, R, Vignesh wrote:
 Hi,

 On 07/16/2015 03:24 AM, Paul Walmsley wrote:
 Hi,

 some comments.

 On Wed, 3 Jun 2015, Vignesh R wrote:

 Add hwmod entries for the PWMSS on DRA7.

 Set l4_root_clk_div as the main_clk of PWMSS. It is fixed-factored clock
 equal to L4PER2_L3_GICLK/2(l3_iclk_div/2).
 As per AM57x TRM SPRUHZ6[1], October 2014, Section 29.1.3 Table 29-4,
 clock source to PWMSS is L4PER2_L3_GICLK. But it is actually
 L4PER2_L3_GICLK/2. The TRM does not show the division by 2.

 Is the divide-by-two coming from PWMSS_EPWM.EPWM_TBCTL[HSPCLKDIV]?  Or is 
 HSPCLKDIV a separate divider after the divide-by-2 you mention above?

 No, it not related to HSPCLKDIV. The TRM wrongly states L4PER2_L3_GICLK
 as clock input for PWMSS. But actually  L4PER2_L4_GICLK(=L3_GICLK/2) is
 the clock input for PWMSS. This will be updated in TRM soon.


 [1] www.ti.com/lit/ug/spruhz6/spruhz6.pdf

 Signed-off-by: Vignesh R vigne...@ti.com
 ---

 v2:
  * add TRM references.

  arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 239 
 ++
  1 file changed, 239 insertions(+)

 diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
 b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
 index 0e64c2fac0b5..86a7ac9a3138 100644
 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
 +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
 @@ -362,6 +362,149 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = {
},
  };
  
 +/* pwmss  */
 +static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
 +  .rev_offs   = 0x0,
 +  .sysc_offs  = 0x4,
 +  .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_RESET_STATUS,

 This doesn't match SPRUHZ6 Table 29-13 PWMSS_SYSCONFIG.  There's no 
 RESETSTATUS bit.  There is a SOFTRESET bit. 

 Could you please confirm whether this is intentional?

 sorry my bad... I will change this in v3.


 +  .idlemodes  = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
 +  .sysc_fields= omap_hwmod_sysc_type2,
 +};
 +
 +struct omap_hwmod_class dra7xx_epwmss_hwmod_class = {
 +  .name   = epwmss,
 +  .sysc   = dra7xx_epwmss_sysc,
 +};
 +
 +static struct omap_hwmod_class dra7xx_ecap_hwmod_class = {
 +  .name   = ecap,
 +};
 +
 +static struct omap_hwmod_class dra7xx_eqep_hwmod_class = {
 +  .name   = eqep,
 +};
 +
 +struct omap_hwmod_class dra7xx_ehrpwm_hwmod_class = {
 +  .name   = ehrpwm,
 +};
 +
 +/* epwmss0 */
 +struct omap_hwmod dra7xx_epwmss0_hwmod = {
 +  .name   = epwmss0,
 +  .class  = dra7xx_epwmss_hwmod_class,
 +  .clkdm_name = l4per2_clkdm,
 +  .main_clk   = l4_root_clk_div,
 +  .prcm   = {
 +  .omap4  = {
 +  .modulemode = MODULEMODE_SWCTRL,
 +  .clkctrl_offs   = 
 DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL_OFFSET,
 +  .context_offs   = 
 DRA7XX_RM_L4PER2_PWMSS1_CONTEXT_OFFSET,
 +  },
 +  },

 Per my comment on the previous patch, sounds like it might be better to 
 mark this as HWMOD_SWSUP_SIDLE?  Then again, see the next comment below 
 re: main_clk.

 +};
 +
 +/* ecap0 */
 +struct omap_hwmod dra7xx_ecap0_hwmod = {
 +  .name   = ecap0,
 +  .class  = dra7xx_ecap_hwmod_class,
 +  .clkdm_name = l4per2_clkdm,
 +  .main_clk   = l4_root_clk_div,

 Looking at SPRUHZ6 Section 29.1.4.2 PWMSS Modules Local Clock Gating, 
 there appears to be a local mini-PRCM for the PWMSS which implements 
 clock gating and reports back on the status of what I'd guess is the local 
 clock gating FSM.

 So from that point of view, you should probably create a clock driver that 
 manages both the clock gate request bit and the FSM status bit.  It should 
 be something that can be reused for the other PWMSS IP blocks.  Then 
 you'd create per-IP block clock nodes and set the main_clk to point to 
 that node.


 Since, this register is within the config space of PWMSS, the individual
 gating and reporting for the modules within PWMSS
 (PWMSS_CLKCONFIG) is currently being taken care by pwm-tipwmss.c(almost
 the sole function this driver is doing). It has been the same since
 am335x. Adding new clock nodes will result in driver changes and also
 changes to am335x, am437x (and other platforms) hwmod files. It also
 involves adding new nodes to clocks.dtsi and it will be difficult to
 maintain backward compatibility for older platforms. Is it not better to
 keep this as is, in order to maintain consistency (with am335x, am437x
 etc) and also that these clock bits are within IP's config space?

 ping...
 

I really want PWMSS support to go into v4.3... I see two options:

1. Drop pwm-tipwmss.c that is currently managing PWMSS Modules Local
Clock Gating and change am335x, am437x and dra7 to use new main_clk and
update clocks.dtsi (Breaks DT backward compatibility for am335x, am437x)
2. Or stick with $subject approach to maintain consistency.

I prefer second option, Shall I send a v3 fixing other comments for 

Re: [PATCH 1/2] regulator: pbias: use untranslated address to program pbias regulator

2015-07-29 Thread Grygorii Strashko

On 07/27/2015 02:24 PM, Kishon Vijay Abraham I wrote:

vsel_reg and enable_reg of the pbias regulator descriptor should actually
have the offset from syscon. However after the pbias device tree node
is moved as a child node of syscon, vsel_reg and enable_reg has the
absolute address because of the address translation that happens while
creating device from device tree node.
So avoid using platform_get_resource and use of_get_address in order to
get only the offset (untranslated address) and populate these in
vsel_reg and enable_reg.

Cc: sta...@vger.kernel.org
Cc: Tero Kristo t-kri...@ti.com
Signed-off-by: Kishon Vijay Abraham I kis...@ti.com


For dra7-evm:
Tested-by: Grygorii Strashko grygorii.stras...@ti.com


--
regards,
-grygorii
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/4] omap: Fix broken pbias device creation

2015-07-29 Thread Grygorii Strashko

On 07/27/2015 03:16 PM, Kishon Vijay Abraham I wrote:

pbias device creation got broken once SCM cleanup got merged.
This patch series re-enables device creation by adding
simple-bus in the compatible property of the syscon
dt node.

validated this series in DRA72, OMAP4 PANDA and OMAP5 UEVM
boards.

Kishon Vijay Abraham I (4):
   ARM: dts: omap24xx: Fix broken pbias device creation
   ARM: dts: OMAP4: Fix broken pbias device creation
   ARM: dts: OMAP5: Fix broken pbias device creation
   ARM: dts: dra7: Fix broken pbias device creation

  arch/arm/boot/dts/dra7.dtsi |2 +-
  arch/arm/boot/dts/omap2430.dtsi |3 ++-
  arch/arm/boot/dts/omap4.dtsi|3 ++-
  arch/arm/boot/dts/omap5.dtsi|3 ++-
  4 files changed, 7 insertions(+), 4 deletions(-)



For dra7-evm:
Tested-by: Grygorii Strashko grygorii.stras...@ti.com

--
regards,
-grygorii
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] i2c: omap: fix bus recovery setup

2015-07-29 Thread Jan LÃŧbbe
On Di, 2015-07-14 at 14:12 +0200, Wolfram Sang wrote:
 On Tue, Jul 14, 2015 at 03:10:01PM +0300, Grygorii Strashko wrote:
  Hi Wolfram,
  
  On 07/14/2015 02:10 PM, Wolfram Sang wrote:
   On Wed, Jul 08, 2015 at 04:35:27PM +0200, Jan Luebbe wrote:
   At least on the AM335x, enabling OMAP_I2C_SYSTEST_ST_EN is not enough to
   
   Felipe: it seems you did not need this; is this AM335x specific?
  
  We need it (Felipe's reply can be delayed).
 
 So, how did it work for him?
 
  It's not AM335x specific. TMODE has to be configured for all OMAP4+ SoCs 
  too.
 
 Okay, thanks for the stepping in!

Wolfram, will you pick this as-is?

Regards,
Jan
-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/17] mmc: host: omap_hsmmc: add separate functions for enable/disable supply

2015-07-29 Thread Kishon Vijay Abraham I
No functional change. Cleanup omap_hsmmc_set_power by adding separate
functions for enable/disable supply and invoke it from
omap_hsmmc_set_power.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |  101 +++--
 1 file changed, 66 insertions(+), 35 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d308552..a0f8c1d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -247,6 +247,65 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
 
 #ifdef CONFIG_REGULATOR
 
+static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd)
+{
+   int ret;
+
+   if (mmc-supply.vmmc) {
+   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd);
+   if (ret)
+   return ret;
+   }
+
+   /* Enable interface voltage rail, if needed */
+   if (mmc-supply.vqmmc) {
+   ret = regulator_enable(mmc-supply.vqmmc);
+   if (ret) {
+   dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n);
+   goto err_vqmmc;
+   }
+   }
+
+   return 0;
+
+err_vqmmc:
+   if (mmc-supply.vmmc)
+   mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
+
+   return ret;
+}
+
+static int omap_hsmmc_disable_supply(struct mmc_host *mmc)
+{
+   int ret;
+   int status;
+
+   if (mmc-supply.vqmmc) {
+   ret = regulator_disable(mmc-supply.vqmmc);
+   if (ret) {
+   dev_err(mmc_dev(mmc), vmmc_aux reg disable failed\n);
+   return ret;
+   }
+   }
+
+   if (mmc-supply.vmmc) {
+   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
+   if (ret)
+   goto err_set_ocr;
+   }
+
+   return 0;
+
+err_set_ocr:
+   if (mmc-supply.vqmmc) {
+   status = regulator_enable(mmc-supply.vqmmc);
+   if (status)
+   dev_err(mmc_dev(mmc), vmmc_aux re-enable failed\n);
+   }
+
+   return ret;
+}
+
 static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_host *host =
@@ -289,36 +348,13 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   if (mmc-supply.vmmc) {
-   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd);
-   if (ret)
-   return ret;
-   }
-
-   /* Enable interface voltage rail, if needed */
-   if (mmc-supply.vqmmc) {
-   ret = regulator_enable(mmc-supply.vqmmc);
-   if (ret) {
-   dev_err(dev, vmmc_aux reg enable failed\n);
-   goto err_set_vqmmc;
-   }
-   }
+   ret = omap_hsmmc_enable_supply(mmc, vdd);
+   if (ret)
+   return ret;
} else {
-   /* Shut down the rail */
-   if (mmc-supply.vqmmc) {
-   ret = regulator_disable(mmc-supply.vqmmc);
-   if (ret) {
-   dev_err(dev, vmmc_aux reg disable failed\n);
-   return ret;
-   }
-   }
-
-   if (mmc-supply.vmmc) {
-   /* Then proceed to shut down the local regulator */
-   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
-   if (ret)
-   return ret;
-   }
+   ret = omap_hsmmc_disable_supply(mmc);
+   if (ret)
+   return ret;
}
 
if (host-pbias) {
@@ -348,12 +384,7 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
return 0;
 
 err_set_voltage:
-   if (mmc-supply.vqmmc)
-   regulator_disable(mmc-supply.vqmmc);
-
-err_set_vqmmc:
-   if (mmc-supply.vmmc)
-   mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
+   omap_hsmmc_disable_supply(mmc);
 
return ret;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/17] mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc

2015-07-29 Thread Kishon Vijay Abraham I
No functional change. Instead of using our own vcc and vcc_aux
members, use vmmc and vqmmc present in mmc_host which is present
for the same purpose.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
Reviewed-by: Roger Quadros rog...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   63 ++---
 1 file changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 0e690d7..dad1473 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -181,15 +181,6 @@ struct omap_hsmmc_host {
struct  mmc_data*data;
struct  clk *fclk;
struct  clk *dbclk;
-   /*
-* vcc == configured supply
-* vcc_aux == optional
-*   -  MMC1, supply for DAT4..DAT7
-*   -  MMC2/MMC2, external level shifter voltage supply, for
-*  chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
-*/
-   struct  regulator   *vcc;
-   struct  regulator   *vcc_aux;
struct  regulator   *pbias;
boolpbias_enabled;
void__iomem *base;
@@ -260,13 +251,14 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 {
struct omap_hsmmc_host *host =
platform_get_drvdata(to_platform_device(dev));
+   struct mmc_host *mmc = host-mmc;
int ret = 0;
 
/*
 * If we don't see a Vcc regulator, assume it's a fixed
 * voltage always-on regulator.
 */
-   if (!host-vcc)
+   if (!mmc-supply.vmmc)
return 0;
 
if (mmc_pdata(host)-before_set_reg)
@@ -295,23 +287,23 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   if (host-vcc)
-   ret = mmc_regulator_set_ocr(host-mmc, host-vcc, vdd);
+   if (mmc-supply.vmmc)
+   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd);
/* Enable interface voltage rail, if needed */
-   if (ret == 0  host-vcc_aux) {
-   ret = regulator_enable(host-vcc_aux);
-   if (ret  0  host-vcc)
-   ret = mmc_regulator_set_ocr(host-mmc,
-   host-vcc, 0);
+   if (ret == 0  mmc-supply.vqmmc) {
+   ret = regulator_enable(mmc-supply.vqmmc);
+   if (ret  0  mmc-supply.vmmc)
+   ret = mmc_regulator_set_ocr(mmc,
+   mmc-supply.vmmc,
+   0);
}
} else {
/* Shut down the rail */
-   if (host-vcc_aux)
-   ret = regulator_disable(host-vcc_aux);
-   if (host-vcc) {
+   if (mmc-supply.vqmmc)
+   ret = regulator_disable(mmc-supply.vqmmc);
+   if (mmc-supply.vmmc) {
/* Then proceed to shut down the local regulator */
-   ret = mmc_regulator_set_ocr(host-mmc,
-   host-vcc, 0);
+   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
}
}
 
@@ -342,29 +334,30 @@ error_set_power:
 static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
int ocr_value = 0;
+   struct mmc_host *mmc = host-mmc;
 
-   host-vcc = devm_regulator_get_optional(host-dev, vmmc);
-   if (IS_ERR(host-vcc)) {
-   if (PTR_ERR(host-vcc) == -EPROBE_DEFER)
+   mmc-supply.vmmc = devm_regulator_get_optional(host-dev, vmmc);
+   if (IS_ERR(mmc-supply.vmmc)) {
+   if (PTR_ERR(mmc-supply.vmmc) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_dbg(host-dev, unable to get vmmc regulator %ld\n,
-   PTR_ERR(host-vcc));
-   host-vcc = NULL;
+   PTR_ERR(mmc-supply.vmmc));
+   mmc-supply.vmmc = NULL;
} else {
-   ocr_value = mmc_regulator_get_ocrmask(host-vcc);
+   ocr_value = mmc_regulator_get_ocrmask(mmc-supply.vmmc);
if (ocr_value  0)
mmc_pdata(host)-ocr_mask = ocr_value;
}
mmc_pdata(host)-set_power = omap_hsmmc_set_power;
 
/* Allow an aux regulator */
-   host-vcc_aux = devm_regulator_get_optional(host-dev, vmmc_aux);
-   if (IS_ERR(host-vcc_aux)) {
-   if (PTR_ERR(host-vcc_aux) == -EPROBE_DEFER)
+   mmc-supply.vqmmc = devm_regulator_get_optional(host-dev, vmmc_aux);
+   if (IS_ERR(mmc-supply.vqmmc)) {
+   if (PTR_ERR(mmc-supply.vqmmc) == 

[PATCH 11/17] mmc: host: omap_hsmmc: don't use -set_power to set initial regulator state

2015-07-29 Thread Kishon Vijay Abraham I
If the regulator is enabled on boot (checked using regulator_is_enabled),
invoke regulator_enable() so that the usecount reflects the correct
state of the regulator and then disable the regulator so that the
initial state of the regulator is disabled. Avoid using -set_power,
since set_power also takes care of setting the voltages which is not
needed at this point.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   67 +++--
 1 file changed, 57 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 2e5c7cd..58bda42 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -407,9 +407,63 @@ err_set_voltage:
return ret;
 }
 
+static int omap_hsmmc_disable_boot_regulator(struct regulator *reg)
+{
+   int ret;
+
+   if (!reg)
+   return 0;
+
+   if (regulator_is_enabled(reg)) {
+   ret = regulator_enable(reg);
+   if (ret)
+   return ret;
+
+   ret = regulator_disable(reg);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int omap_hsmmc_disable_boot_regulators(struct omap_hsmmc_host *host)
+{
+   struct mmc_host *mmc = host-mmc;
+   int ret;
+
+   /*
+* disable regulators enabled during boot and get the usecount
+* right so that regulators can be enabled/disabled by checking
+* the return value of regulator_is_enabled
+*/
+   ret = omap_hsmmc_disable_boot_regulator(mmc-supply.vmmc);
+   if (ret) {
+   dev_err(host-dev, fail to disable boot enabled vmmc reg\n);
+   return ret;
+   }
+
+   ret = omap_hsmmc_disable_boot_regulator(mmc-supply.vqmmc);
+   if (ret) {
+   dev_err(host-dev,
+   fail to disable boot enabled vmmc_aux reg\n);
+   return ret;
+   }
+
+   ret = omap_hsmmc_disable_boot_regulator(host-pbias);
+   if (ret) {
+   dev_err(host-dev,
+   failed to disable boot enabled pbias reg\n);
+   return ret;
+   }
+
+   return 0;
+}
+
 static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
int ocr_value = 0;
+   int ret;
struct mmc_host *mmc = host-mmc;
 
mmc-supply.vmmc = devm_regulator_get_optional(host-dev, vmmc);
@@ -448,17 +502,10 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
/* For eMMC do not power off when not in sleep state */
if (mmc_pdata(host)-no_regulator_off_init)
return 0;
-   /*
-* To disable boot_on regulator, enable regulator
-* to increase usecount and then disable it.
-*/
-   if ((mmc-supply.vmmc  regulator_is_enabled(mmc-supply.vmmc)  0) ||
-   (mmc-supply.vqmmc  regulator_is_enabled(mmc-supply.vqmmc))) {
-   int vdd = ffs(mmc_pdata(host)-ocr_mask) - 1;
 
-   mmc_pdata(host)-set_power(host-dev, 1, vdd);
-   mmc_pdata(host)-set_power(host-dev, 0, 0);
-   }
+   ret = omap_hsmmc_disable_boot_regulators(host);
+   if (ret)
+   return ret;
 
return 0;
 }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/17] ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node

2015-07-29 Thread Kishon Vijay Abraham I
For beagle x15, both the vdd and io lines are connected to the
same regulator (ldo1_reg). However vmmc_aux is populated to vdd_3v3.
Remove it.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 arch/arm/boot/dts/am57xx-beagle-x15.dts |1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts 
b/arch/arm/boot/dts/am57xx-beagle-x15.dts
index a63bf78..d0db5c5 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -579,7 +579,6 @@
pinctrl-0 = mmc1_pins_default;
 
vmmc-supply = ldo1_reg;
-   vmmc_aux-supply = vdd_3v3;
pbias-supply = pbias_mmc_reg;
bus-width = 4;
cd-gpios = gpio6 27 0; /* gpio 219 */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/17] mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator

2015-07-29 Thread Kishon Vijay Abraham I
If the vmmc regulator provides a valid ocrmask, use it. By this even if
the pdata has a valid ocrmask, it will be overwritten with the ocrmask
of the vmmc regulator.
Also remove the unnecessary compatibility check between the ocrmask in
the pdata and the ocrmask from the vmmc regulator.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a78e15e..0e690d7 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -352,16 +352,8 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
host-vcc = NULL;
} else {
ocr_value = mmc_regulator_get_ocrmask(host-vcc);
-   if (!mmc_pdata(host)-ocr_mask) {
+   if (ocr_value  0)
mmc_pdata(host)-ocr_mask = ocr_value;
-   } else {
-   if (!(mmc_pdata(host)-ocr_mask  ocr_value)) {
-   dev_err(host-dev, ocrmask %x is not 
supported\n,
-   mmc_pdata(host)-ocr_mask);
-   mmc_pdata(host)-ocr_mask = 0;
-   return -EINVAL;
-   }
-   }
}
mmc_pdata(host)-set_power = omap_hsmmc_set_power;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 13/17] mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on prior state

2015-07-29 Thread Kishon Vijay Abraham I
enable vmmc_aux regulator only if it is in disabled state and disable
vmmc_aux regulator only if it is in enabled state.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 58bda42..001f8a0 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -258,7 +258,7 @@ static int omap_hsmmc_enable_supply(struct mmc_host *mmc, 
int vdd)
}
 
/* Enable interface voltage rail, if needed */
-   if (mmc-supply.vqmmc) {
+   if (mmc-supply.vqmmc  !regulator_is_enabled(mmc-supply.vqmmc)) {
ret = regulator_enable(mmc-supply.vqmmc);
if (ret) {
dev_err(mmc_dev(mmc), vmmc_aux reg enable failed\n);
@@ -280,7 +280,7 @@ static int omap_hsmmc_disable_supply(struct mmc_host *mmc)
int ret;
int status;
 
-   if (mmc-supply.vqmmc) {
+   if (mmc-supply.vqmmc  regulator_is_enabled(mmc-supply.vqmmc)) {
ret = regulator_disable(mmc-supply.vqmmc);
if (ret) {
dev_err(mmc_dev(mmc), vmmc_aux reg disable failed\n);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 15/17] mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage

2015-07-29 Thread Kishon Vijay Abraham I
vdd voltage is set in mmc core to ios-vdd and vmmc should actually
be set to this voltage. Modify omap_hsmmc_enable_supply
to not take vdd as argument since now it's directly set to
the voltage in ios-vdd.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a50edbc..5116c42 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -246,12 +246,13 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
 
 #ifdef CONFIG_REGULATOR
 
-static int omap_hsmmc_enable_supply(struct mmc_host *mmc, int vdd)
+static int omap_hsmmc_enable_supply(struct mmc_host *mmc)
 {
int ret;
+   struct mmc_ios *ios = mmc-ios;
 
if (mmc-supply.vmmc) {
-   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd);
+   ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, ios-vdd);
if (ret)
return ret;
}
@@ -380,7 +381,7 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   ret = omap_hsmmc_enable_supply(mmc, vdd);
+   ret = omap_hsmmc_enable_supply(mmc);
if (ret)
return ret;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 14/17] mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status

2015-07-29 Thread Kishon Vijay Abraham I
Use regulator_is_enabled of pbias regulator to find pbias regulator
status instead of maintaining a custom bookkeeping
pbias_enabled variable.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 001f8a0..a50edbc 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -182,7 +182,6 @@ struct omap_hsmmc_host {
struct  clk *fclk;
struct  clk *dbclk;
struct  regulator   *pbias;
-   boolpbias_enabled;
void__iomem *base;
resource_size_t mapbase;
spinlock_t  irq_lock; /* Prevent races with irq handler */
@@ -326,22 +325,20 @@ static int omap_hsmmc_set_pbias(struct omap_hsmmc_host 
*host, bool power_on,
return ret;
}
 
-   if (host-pbias_enabled == 0) {
+   if (!regulator_is_enabled(host-pbias)) {
ret = regulator_enable(host-pbias);
if (ret) {
dev_err(host-dev, pbias reg enable fail\n);
return ret;
}
-   host-pbias_enabled = 1;
}
} else {
-   if (host-pbias_enabled == 1) {
+   if (regulator_is_enabled(host-pbias)) {
ret = regulator_disable(host-pbias);
if (ret) {
dev_err(host-dev, pbias reg disable fail\n);
return ret;
}
-   host-pbias_enabled = 0;
}
}
 
@@ -2073,7 +2070,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host-base  = base + pdata-reg_offset;
host-power_mode = MMC_POWER_OFF;
host-next_data.cookie = 1;
-   host-pbias_enabled = 0;
 
ret = omap_hsmmc_gpio_init(mmc, host, pdata);
if (ret)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 16/17] mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check

2015-07-29 Thread Kishon Vijay Abraham I
Now that support for platforms which have optional regulator is added,
remove CONFIG_REGULATOR check in omap_hsmmc.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   35 +++
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5116c42..aa4ba28 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -203,7 +203,6 @@ struct omap_hsmmc_host {
int context_loss;
int protect_card;
int reqs_blocked;
-   int use_reg;
int req_in_progress;
unsigned long   clk_rate;
unsigned intflags;
@@ -244,8 +243,6 @@ static int omap_hsmmc_get_cover_state(struct device *dev)
return mmc_gpio_get_cd(host-mmc);
 }
 
-#ifdef CONFIG_REGULATOR
-
 static int omap_hsmmc_enable_supply(struct mmc_host *mmc)
 {
int ret;
@@ -513,29 +510,6 @@ static void omap_hsmmc_reg_put(struct omap_hsmmc_host 
*host)
mmc_pdata(host)-set_power = NULL;
 }
 
-static inline int omap_hsmmc_have_reg(void)
-{
-   return 1;
-}
-
-#else
-
-static inline int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
-{
-   return -EINVAL;
-}
-
-static inline void omap_hsmmc_reg_put(struct omap_hsmmc_host *host)
-{
-}
-
-static inline int omap_hsmmc_have_reg(void)
-{
-   return 0;
-}
-
-#endif
-
 static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id);
 
 static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
@@ -2195,11 +2169,10 @@ static int omap_hsmmc_probe(struct platform_device 
*pdev)
goto err_irq;
}
 
-   if (omap_hsmmc_have_reg()  !mmc_pdata(host)-set_power) {
+   if (!mmc_pdata(host)-set_power) {
ret = omap_hsmmc_reg_get(host);
if (ret)
goto err_irq;
-   host-use_reg = 1;
}
 
mmc-ocr_avail = mmc_pdata(host)-ocr_mask;
@@ -2242,8 +2215,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name:
mmc_remove_host(mmc);
-   if (host-use_reg)
-   omap_hsmmc_reg_put(host);
+   omap_hsmmc_reg_put(host);
 err_irq:
device_init_wakeup(pdev-dev, false);
if (host-tx_chan)
@@ -2267,8 +2239,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
 
pm_runtime_get_sync(host-dev);
mmc_remove_host(host-mmc);
-   if (host-use_reg)
-   omap_hsmmc_reg_put(host);
+   omap_hsmmc_reg_put(host);
 
if (host-tx_chan)
dma_release_channel(host-tx_chan);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/17] mmc: host: omap_hsmmc: add separate function to set pbias

2015-07-29 Thread Kishon Vijay Abraham I
No functional change. Cleanup omap_hsmmc_set_power by adding separate
functions to set pbias and invoke it from omap_hsmmc_set_power.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   78 +
 1 file changed, 48 insertions(+), 30 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a0f8c1d..8bb3f60 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -306,6 +306,48 @@ err_set_ocr:
return ret;
 }
 
+static int omap_hsmmc_set_pbias(struct omap_hsmmc_host *host, bool power_on,
+   int vdd)
+{
+   int ret;
+
+   if (!host-pbias)
+   return 0;
+
+   if (power_on) {
+   if (vdd = VDD_165_195)
+   ret = regulator_set_voltage(host-pbias, VDD_1V8,
+   VDD_1V8);
+   else
+   ret = regulator_set_voltage(host-pbias, VDD_3V0,
+   VDD_3V0);
+   if (ret  0) {
+   dev_err(host-dev, pbias set voltage fail\n);
+   return ret;
+   }
+
+   if (host-pbias_enabled == 0) {
+   ret = regulator_enable(host-pbias);
+   if (ret) {
+   dev_err(host-dev, pbias reg enable fail\n);
+   return ret;
+   }
+   host-pbias_enabled = 1;
+   }
+   } else {
+   if (host-pbias_enabled == 1) {
+   ret = regulator_disable(host-pbias);
+   if (ret) {
+   dev_err(host-dev, pbias reg disable fail\n);
+   return ret;
+   }
+   host-pbias_enabled = 0;
+   }
+   }
+
+   return 0;
+}
+
 static int omap_hsmmc_set_power(struct device *dev, int power_on, int vdd)
 {
struct omap_hsmmc_host *host =
@@ -323,16 +365,9 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
if (mmc_pdata(host)-before_set_reg)
mmc_pdata(host)-before_set_reg(dev, power_on, vdd);
 
-   if (host-pbias) {
-   if (host-pbias_enabled == 1) {
-   ret = regulator_disable(host-pbias);
-   if (ret) {
-   dev_err(dev, pbias reg disable failed\n);
-   return ret;
-   }
-   host-pbias_enabled = 0;
-   }
-   }
+   ret = omap_hsmmc_set_pbias(host, false, 0);
+   if (ret)
+   return ret;
 
/*
 * Assume Vcc regulator is used only to power the card ... OMAP
@@ -357,26 +392,9 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
return ret;
}
 
-   if (host-pbias) {
-   if (vdd = VDD_165_195)
-   ret = regulator_set_voltage(host-pbias, VDD_1V8,
-   VDD_1V8);
-   else
-   ret = regulator_set_voltage(host-pbias, VDD_3V0,
-   VDD_3V0);
-   if (ret  0)
-   goto err_set_voltage;
-
-   if (host-pbias_enabled == 0) {
-   ret = regulator_enable(host-pbias);
-   if (ret) {
-   dev_err(dev, pbias reg enable failed\n);
-   goto err_set_voltage;
-   } else {
-   host-pbias_enabled = 1;
-   }
-   }
-   }
+   ret = omap_hsmmc_set_pbias(host, true, vdd);
+   if (ret)
+   goto err_set_voltage;
 
if (mmc_pdata(host)-after_set_reg)
mmc_pdata(host)-after_set_reg(dev, power_on, vdd);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 17/17] mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail

2015-07-29 Thread Kishon Vijay Abraham I
From: Roger Quadros rog...@ti.com

For platforms that doesn't have explicit regulator control in MMC,
populate voltage-ranges in MMC device tree node and use
mmc_of_parse_voltage to get ocr_avail

Signed-off-by: Roger Quadros rog...@ti.com
Signed-off-by: Lokesh Vutla lokeshvu...@ti.com
Signed-off-by: Murali Karicheri m-kariche...@ti.com
Signed-off-by: Franklin S Cooper Jr fcoo...@ti.com
Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 ++
 drivers/mmc/host/omap_hsmmc.c  |9 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt 
b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 76bf087..2408e87 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -22,6 +22,8 @@ ti,dual-volt: boolean, supports dual voltage cards
 ti,non-removable: non-removable slot (like eMMC)
 ti,needs-special-reset: Requires a special softreset sequence
 ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High 
Speed
+voltage-ranges: Specify the voltage range supported if regulator framework
+isn't enabled.
 dmas: List of DMA specifiers with the controller specific format
 as described in the generic DMA client binding. A tx and rx
 specifier is required.
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index aa4ba28..6d52873 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -2175,7 +2175,13 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
goto err_irq;
}
 
-   mmc-ocr_avail = mmc_pdata(host)-ocr_mask;
+   if (!mmc_pdata(host)-ocr_mask) {
+   ret = mmc_of_parse_voltage(pdev-dev.of_node, mmc-ocr_avail);
+   if (ret)
+   goto err_parse_voltage;
+   } else {
+   mmc-ocr_avail = mmc_pdata(host)-ocr_mask;
+   }
 
omap_hsmmc_disable_irq(host);
 
@@ -2215,6 +2221,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
 
 err_slot_name:
mmc_remove_host(mmc);
+err_parse_voltage:
omap_hsmmc_reg_put(host);
 err_irq:
device_init_wakeup(pdev-dev, false);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/17] mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc

2015-07-29 Thread Kishon Vijay Abraham I
Since vmmc can be optional for some platforms, use
devm_regulator_get_optional() for vmmc. Now return error only
in the case of -EPROBE_DEFER and for all other cases set
host-vcc to NULL.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4d12032..b673e59 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -344,11 +344,13 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
struct regulator *reg;
int ocr_value = 0;
 
-   reg = devm_regulator_get(host-dev, vmmc);
+   reg = devm_regulator_get_optional(host-dev, vmmc);
if (IS_ERR(reg)) {
-   dev_err(host-dev, unable to get vmmc regulator %ld\n,
+   if (PTR_ERR(reg) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+   host-vcc = NULL;
+   dev_dbg(host-dev, unable to get vmmc regulator %ld\n,
PTR_ERR(reg));
-   return PTR_ERR(reg);
} else {
host-vcc = reg;
ocr_value = mmc_regulator_get_ocrmask(reg);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/17] mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()

2015-07-29 Thread Kishon Vijay Abraham I
No functional change. Instead of using a local regulator variable
in omap_hsmmc_reg_get() for holding the return value of
devm_regulator_get_optional() and then assigning to omap_hsmmc_host
regulator members: vcc, vcc_aux and pbias, directly use the
omap_hsmmc_host regulator members.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
Reviewed-by: Roger Quadros rog...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   38 --
 1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 7f7625d..a78e15e 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -341,19 +341,17 @@ error_set_power:
 
 static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
 {
-   struct regulator *reg;
int ocr_value = 0;
 
-   reg = devm_regulator_get_optional(host-dev, vmmc);
-   if (IS_ERR(reg)) {
-   if (PTR_ERR(reg) == -EPROBE_DEFER)
+   host-vcc = devm_regulator_get_optional(host-dev, vmmc);
+   if (IS_ERR(host-vcc)) {
+   if (PTR_ERR(host-vcc) == -EPROBE_DEFER)
return -EPROBE_DEFER;
-   host-vcc = NULL;
dev_dbg(host-dev, unable to get vmmc regulator %ld\n,
-   PTR_ERR(reg));
+   PTR_ERR(host-vcc));
+   host-vcc = NULL;
} else {
-   host-vcc = reg;
-   ocr_value = mmc_regulator_get_ocrmask(reg);
+   ocr_value = mmc_regulator_get_ocrmask(host-vcc);
if (!mmc_pdata(host)-ocr_mask) {
mmc_pdata(host)-ocr_mask = ocr_value;
} else {
@@ -368,26 +366,22 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
mmc_pdata(host)-set_power = omap_hsmmc_set_power;
 
/* Allow an aux regulator */
-   reg = devm_regulator_get_optional(host-dev, vmmc_aux);
-   if (IS_ERR(reg)) {
-   if (PTR_ERR(reg) == -EPROBE_DEFER)
+   host-vcc_aux = devm_regulator_get_optional(host-dev, vmmc_aux);
+   if (IS_ERR(host-vcc_aux)) {
+   if (PTR_ERR(host-vcc_aux) == -EPROBE_DEFER)
return -EPROBE_DEFER;
-   host-vcc_aux = NULL;
dev_dbg(host-dev, unable to get vmmc_aux regulator %ld\n,
-   PTR_ERR(reg));
-   } else {
-   host-vcc_aux = reg;
+   PTR_ERR(host-vcc_aux));
+   host-vcc_aux = NULL;
}
 
-   reg = devm_regulator_get_optional(host-dev, pbias);
-   if (IS_ERR(reg)) {
-   if (PTR_ERR(reg) == -EPROBE_DEFER)
+   host-pbias = devm_regulator_get_optional(host-dev, pbias);
+   if (IS_ERR(host-pbias)) {
+   if (PTR_ERR(host-pbias) == -EPROBE_DEFER)
return -EPROBE_DEFER;
-   host-pbias = NULL;
dev_dbg(host-dev, unable to get pbias regulator %ld\n,
-   PTR_ERR(reg));
-   } else {
-   host-pbias = reg;
+   PTR_ERR(host-pbias));
+   host-pbias = NULL;
}
 
/* For eMMC do not power off when not in sleep state */
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/17] mmc: host: omap_hsmmc: avoid pbias regulator enable on power off

2015-07-29 Thread Kishon Vijay Abraham I
Fix omap_hsmmc_set_power so that pbias regulator is not enabled
during power off.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 8bb3f60..2e5c7cd 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -386,16 +386,16 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
ret = omap_hsmmc_enable_supply(mmc, vdd);
if (ret)
return ret;
+
+   ret = omap_hsmmc_set_pbias(host, true, vdd);
+   if (ret)
+   goto err_set_voltage;
} else {
ret = omap_hsmmc_disable_supply(mmc);
if (ret)
return ret;
}
 
-   ret = omap_hsmmc_set_pbias(host, true, vdd);
-   if (ret)
-   goto err_set_voltage;
-
if (mmc_pdata(host)-after_set_reg)
mmc_pdata(host)-after_set_reg(dev, power_on, vdd);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes

2015-07-29 Thread Kishon Vijay Abraham I
This patch series does the following
*) Uses devm_regulator_get_optional() for vmmc and then removes the
   CONFIG_REGULATOR check altogether.
*) return on -EPROBE_DEFER
*) enable/disable vmmc_aux regulator based on prior state

This series is in preparation for implementing the voltage switch
sequence so that UHS cards can be supported.

Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.

Kishon Vijay Abraham I (16):
  mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
  mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
-EPROBE_DEFER
  mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
  mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
  mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
  mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
  mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
  mmc: host: omap_hsmmc: add separate functions for enable/disable
supply
  mmc: host: omap_hsmmc: add separate function to set pbias
  mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
  mmc: host: omap_hsmmc: don't use -set_power to set initial regulator
state
  ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
  mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
prior state
  mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
  mmc: host: omap_hsmmc: use ios-vdd for setting vmmc voltage
  mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check

Roger Quadros (1):
  mmc: host: omap_hsmmc: use mmc_of_parse_voltage to get ocr_avail

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt  |2 +
 arch/arm/boot/dts/am57xx-beagle-x15.dts|1 -
 drivers/mmc/host/omap_hsmmc.c  |  333 +---
 3 files changed, 216 insertions(+), 120 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/17] mmc: host: omap_hsmmc: return error if any of the regulator APIs fail

2015-07-29 Thread Kishon Vijay Abraham I
Return error if any of the regulator APIs (regulator_enable,
regulator_disable, regulator_set_voltage) fails in
omap_hsmmc_set_power to avoid undefined behavior.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   52 +++--
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 7aee1a0..d308552 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -267,8 +267,11 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
if (host-pbias) {
if (host-pbias_enabled == 1) {
ret = regulator_disable(host-pbias);
-   if (!ret)
-   host-pbias_enabled = 0;
+   if (ret) {
+   dev_err(dev, pbias reg disable failed\n);
+   return ret;
+   }
+   host-pbias_enabled = 0;
}
}
 
@@ -286,23 +289,35 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
 * chips/cards need an interface voltage rail too.
 */
if (power_on) {
-   if (mmc-supply.vmmc)
+   if (mmc-supply.vmmc) {
ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, vdd);
+   if (ret)
+   return ret;
+   }
+
/* Enable interface voltage rail, if needed */
-   if (ret == 0  mmc-supply.vqmmc) {
+   if (mmc-supply.vqmmc) {
ret = regulator_enable(mmc-supply.vqmmc);
-   if (ret  0  mmc-supply.vmmc)
-   ret = mmc_regulator_set_ocr(mmc,
-   mmc-supply.vmmc,
-   0);
+   if (ret) {
+   dev_err(dev, vmmc_aux reg enable failed\n);
+   goto err_set_vqmmc;
+   }
}
} else {
/* Shut down the rail */
-   if (mmc-supply.vqmmc)
+   if (mmc-supply.vqmmc) {
ret = regulator_disable(mmc-supply.vqmmc);
+   if (ret) {
+   dev_err(dev, vmmc_aux reg disable failed\n);
+   return ret;
+   }
+   }
+
if (mmc-supply.vmmc) {
/* Then proceed to shut down the local regulator */
ret = mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
+   if (ret)
+   return ret;
}
}
 
@@ -314,19 +329,32 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
ret = regulator_set_voltage(host-pbias, VDD_3V0,
VDD_3V0);
if (ret  0)
-   goto error_set_power;
+   goto err_set_voltage;
 
if (host-pbias_enabled == 0) {
ret = regulator_enable(host-pbias);
-   if (!ret)
+   if (ret) {
+   dev_err(dev, pbias reg enable failed\n);
+   goto err_set_voltage;
+   } else {
host-pbias_enabled = 1;
+   }
}
}
 
if (mmc_pdata(host)-after_set_reg)
mmc_pdata(host)-after_set_reg(dev, power_on, vdd);
 
-error_set_power:
+   return 0;
+
+err_set_voltage:
+   if (mmc-supply.vqmmc)
+   regulator_disable(mmc-supply.vqmmc);
+
+err_set_vqmmc:
+   if (mmc-supply.vmmc)
+   mmc_regulator_set_ocr(mmc, mmc-supply.vmmc, 0);
+
return ret;
 }
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/17] mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on -EPROBE_DEFER

2015-07-29 Thread Kishon Vijay Abraham I
EPROBE_DEFER is not fatal and it means the regulator can still be
obtained. Hence return error if devm_regulator_get_optional for
vmmc_aux and pbias returns -EPROBE_DEFER. This gives omap_hsmmc
driver another chance to get these regulators.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |   20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index b673e59..7f7625d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -369,10 +369,26 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
*host)
 
/* Allow an aux regulator */
reg = devm_regulator_get_optional(host-dev, vmmc_aux);
-   host-vcc_aux = IS_ERR(reg) ? NULL : reg;
+   if (IS_ERR(reg)) {
+   if (PTR_ERR(reg) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+   host-vcc_aux = NULL;
+   dev_dbg(host-dev, unable to get vmmc_aux regulator %ld\n,
+   PTR_ERR(reg));
+   } else {
+   host-vcc_aux = reg;
+   }
 
reg = devm_regulator_get_optional(host-dev, pbias);
-   host-pbias = IS_ERR(reg) ? NULL : reg;
+   if (IS_ERR(reg)) {
+   if (PTR_ERR(reg) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+   host-pbias = NULL;
+   dev_dbg(host-dev, unable to get pbias regulator %ld\n,
+   PTR_ERR(reg));
+   } else {
+   host-pbias = reg;
+   }
 
/* For eMMC do not power off when not in sleep state */
if (mmc_pdata(host)-no_regulator_off_init)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/17] mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage

2015-07-29 Thread Kishon Vijay Abraham I
Remove the unnecessary pbias regulator_set_voltage done after
pbias regulator_disable in omap_hsmmc_set_power.

Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
Reviewed-by: Roger Quadros rog...@ti.com
---
 drivers/mmc/host/omap_hsmmc.c |1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index dad1473..7aee1a0 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -270,7 +270,6 @@ static int omap_hsmmc_set_power(struct device *dev, int 
power_on, int vdd)
if (!ret)
host-pbias_enabled = 0;
}
-   regulator_set_voltage(host-pbias, VDD_3V0, VDD_3V0);
}
 
/*
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/12] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver

2015-07-29 Thread Roger Quadros
Tony,

On 13/07/15 15:40, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150713 03:07]:
 Tony,

 On 13/07/15 10:10, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150710 05:26]:
 Since the Interrupt Events are used only by the NAND driver,
 there is no point in managing the Interrupt registers
 in the GPMC driver and complicating it with irqchip modeling.

 I don't think it's a good idea to allow external drivers to
 tinker directly with GPMC registers. How about just set up GPMC
 as an irqchip for the edge detection interrupts?

 I think we already have devices with multiple NAND chips. And
 there's nothing stopping other drivers from using the edge
 detection interrupts.

 OK. The GPMC_IRQ registers manage 2 NAND specific interrupts
 (terminalcount and fifo) and 'n' WAIT pin edge interrupts.

  So we can model this as a irqchip with 'n + 2' interrupts.
 
 OK

For the wait pins irqchip is not sufficient and it needs to be gpiochip
with irqchip. Waitpin status can be read from GPIO_STATUS register.

Just getting the interrupt is not enough and we want to know if the
line is high or low. That is how nand-dev_ready works.

How about having 2 IRQ domains?
One is irqchip with 2 interrupts (terminalcount and fifo) and second is
gpiochip + irqchip for the n wait pins.

The nand driver can then be modified to use GPIO to get Read/Busy
pin status from the wait pin.

cheers,
-roger

  
 We need to take care that if a GPMC chip select needs a
 wait pin then it can't be used as a generic interrupt.

 We need to get rid of omap_dev_ready() in nand/omap2.c as
 it accesses the GPMC_STATUS register directly. Plus it is
 hard coded to only monitor wait0 pin.
 
 OK
  
 What is the best map we should use for irqchip?
 Some Socs have 4 WAIT pins, some have 3 and some have 2.

 Should we start with 0,1,2, for the wait pins and use the next
 available free one for the NAND?
 
 Maybe we can just use the bits defined for each SoC in the
 GPMC_IRQSTATUS register for the mapping?  
 Regards,
 
 Tony
 
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 01/17] mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc

2015-07-29 Thread Grygorii Strashko
On 07/29/2015 02:09 PM, Kishon Vijay Abraham I wrote:
 Since vmmc can be optional for some platforms, use
 devm_regulator_get_optional() for vmmc. Now return error only
 in the case of -EPROBE_DEFER and for all other cases set
 host-vcc to NULL.
 
 Signed-off-by: Kishon Vijay Abraham I kis...@ti.com
 ---
   drivers/mmc/host/omap_hsmmc.c |8 +---
   1 file changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
 index 4d12032..b673e59 100644
 --- a/drivers/mmc/host/omap_hsmmc.c
 +++ b/drivers/mmc/host/omap_hsmmc.c
 @@ -344,11 +344,13 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host 
 *host)
   struct regulator *reg;
   int ocr_value = 0;
   
 - reg = devm_regulator_get(host-dev, vmmc);
 + reg = devm_regulator_get_optional(host-dev, vmmc);
   if (IS_ERR(reg)) {
 - dev_err(host-dev, unable to get vmmc regulator %ld\n,
 + if (PTR_ERR(reg) == -EPROBE_DEFER)
 + return -EPROBE_DEFER;
 + host-vcc = NULL;
 + dev_dbg(host-dev, unable to get vmmc regulator %ld\n,
   PTR_ERR(reg));
 - return PTR_ERR(reg);

I think, It could be unsafe to just drop this return.
regulator_get_optional may return:
1 valid pointer on regulator : success;
2 ERR_PTR(-ENODEV)   : regulator is not assigned, can proceed.
3 ERR_PTR(-EPROBE_DEFER) : regulator is assigned, but not ready yet, retry.
4 ERR_PTR(other error codes: regulator is assigned, but can't be retrieved, 
failure, can't proceed

So, It's allowed to continue with host-vcc = NULL; only in case [2], while
in case [4] probe should fail.

   } else {
   host-vcc = reg;
   ocr_value = mmc_regulator_get_ocrmask(reg);
 


-- 
regards,
-grygorii
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 13/13] twl4030_charger: assume a 'charger' can supply maximum current.

2015-07-29 Thread NeilBrown
If it cannot, we will stop pulling more current when voltage drops.

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 2c537ee11bbe..c7432f532a83 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -697,8 +697,10 @@ static void twl4030_bci_usb_work(struct work_struct *data)
struct twl4030_bci *bci = container_of(data, struct twl4030_bci, work);
 
switch (bci-event) {
-   case USB_EVENT_VBUS:
case USB_EVENT_CHARGER:
+   bci-usb_cur = USB_MAX_CURRENT;
+   /* FALL THROUGH */
+   case USB_EVENT_VBUS:
twl4030_charger_enable_usb(bci, true);
break;
case USB_EVENT_NONE:


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/13] twl4030_charger: Increase current carefully while watching voltage.

2015-07-29 Thread NeilBrown

The USB Battery Charging spec (BC1.2) suggests a dedicated
charging port can deliver from 0.5 to 5.0A at between 4.75 and 5.25
volts.

To choose the correct current voltage setting requires a trial
and error approach: try to draw current and see if the voltage drops
too low.

Even with a configured Standard Downstream Port, it may not be possible
to reliably pull 500mA - depending on cable quality and source
quality I have reports of charging failure due to the voltage dropping
too low.

To address both these concerns, this patch introduce incremental
current setting.
The current pull from VBUS is increased in steps of 20mA every 100ms
until the target is reached or until the measure voltage drops below
4.75V.  If the voltage does go too low, the target current is reduced
by 20mA and kept there.

This applies to currents selected automatically, or to values
set via sysfs.  So setting a large value will cause the maximum
available to be used - up to the limit of 1.7A imposed by the
hardware.

Signed-off-by: NeilBrown n...@brown.name
---
 drivers/power/twl4030_charger.c |   67 ---
 1 file changed, 61 insertions(+), 6 deletions(-)

diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 68117ad23564..2c537ee11bbe 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -119,6 +119,18 @@ struct twl4030_bci {
 #defineCHARGE_AUTO 1
 #defineCHARGE_LINEAR   2
 
+   /* When setting the USB current we slowly increase the
+* requested current until target is reached or the voltage
+* drops below 4.75V.  In the latter case we step back one
+* step.
+*/
+   unsigned intusb_cur_target;
+   struct delayed_work current_worker;
+#defineUSB_CUR_STEP2   /* 20mA at a time */
+#defineUSB_MIN_VOLT475 /* 4.75V */
+#defineUSB_CUR_DELAY   msecs_to_jiffies(100)
+#defineUSB_MAX_CURRENT 170 /* TWL4030 caps at 1.7A */
+
unsigned long   event;
 };
 
@@ -257,6 +269,12 @@ static int twl4030_charger_update_current(struct 
twl4030_bci *bci)
} else {
cur = bci-usb_cur;
bci-ac_is_active = false;
+   if (cur  bci-usb_cur_target) {
+   cur = bci-usb_cur_target;
+   bci-usb_cur = cur;
+   }
+   if (cur  bci-usb_cur_target)
+   schedule_delayed_work(bci-current_worker, 
USB_CUR_DELAY);
}
 
/* First, check thresholds and see if cgain is needed */
@@ -391,6 +409,41 @@ static int twl4030_charger_update_current(struct 
twl4030_bci *bci)
return 0;
 }
 
+static int twl4030_charger_get_current(void);
+
+static void twl4030_current_worker(struct work_struct *data)
+{
+   int v, curr;
+   int res;
+   struct twl4030_bci *bci = container_of(data, struct twl4030_bci,
+  current_worker.work);
+
+   res = twl4030bci_read_adc_val(TWL4030_BCIVBUS);
+   if (res  0)
+   v = 0;
+   else
+   /* BCIVBUS uses ADCIN8, 7/1023 V/step */
+   v = res * 6843;
+   curr = twl4030_charger_get_current();
+
+   dev_dbg(bci-dev, v=%d cur=%d limit=%d target=%d\n, v, curr,
+   bci-usb_cur, bci-usb_cur_target);
+
+   if (v  USB_MIN_VOLT) {
+   /* Back up and stop adjusting. */
+   bci-usb_cur -= USB_CUR_STEP;
+   bci-usb_cur_target = bci-usb_cur;
+   } else if (bci-usb_cur = bci-usb_cur_target ||
+  bci-usb_cur + USB_CUR_STEP  USB_MAX_CURRENT) {
+   /* Reached target and voltage is OK - stop */
+   return;
+   } else {
+   bci-usb_cur += USB_CUR_STEP;
+   schedule_delayed_work(bci-current_worker, USB_CUR_DELAY);
+   }
+   twl4030_charger_update_current(bci);
+}
+
 /*
  * Enable/Disable USB Charge functionality.
  */
@@ -451,6 +504,7 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
pm_runtime_put_autosuspend(bci-transceiver-dev);
bci-usb_enabled = 0;
}
+   bci-usb_cur = 0;
}
 
return ret;
@@ -599,7 +653,7 @@ twl4030_bci_max_current_store(struct device *dev, struct 
device_attribute *attr,
if (dev == bci-ac-dev)
bci-ac_cur = cur;
else
-   bci-usb_cur = cur;
+   bci-usb_cur_target = cur;
 
twl4030_charger_update_current(bci);
return n;
@@ -621,7 +675,7 @@ static ssize_t twl4030_bci_max_current_show(struct device 
*dev,
cur = bci-ac_cur;
} else {
if (bci-ac_is_active)
-   cur = bci-usb_cur;
+   cur = bci-usb_cur_target;
}
if (cur  0) {
cur 

[PATCH 10/13] twl4030_charger: add software controlled linear charging mode.

2015-07-29 Thread NeilBrown

Add a 'continuous' option for usb charging which enables
the linear charging mode of the twl4030.

Linear charging does a good job with not-so-reliable power sources.
Auto mode does not work well as it switches off when voltage drops
momentarily.  Care must be taken not to over-charge.

It was used with a bike hub dynamo since a year or so. In that case
there are automatically charging stops when the cyclist needs a break.

Original-by: Andreas Kemnade andr...@kemnade.info
Signed-off-by: NeilBrown n...@brown.name
---
 .../ABI/testing/sysfs-class-power-twl4030  |9 +++
 drivers/power/twl4030_charger.c|   55 ++--
 2 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-class-power-twl4030 
b/Documentation/ABI/testing/sysfs-class-power-twl4030
index 40e0f919cbde..e8baa36aaa2b 100644
--- a/Documentation/ABI/testing/sysfs-class-power-twl4030
+++ b/Documentation/ABI/testing/sysfs-class-power-twl4030
@@ -24,3 +24,12 @@ Description:
auto - draw power as appropriate for detected
 power source and battery status.
off  - do not draw any power.
+   continuous
+  - activate mode described as linear in
+TWL data sheets.  This uses whatever
+current is available and doesn't switch off
+when voltage drops.
+
+This is useful for unstable power sources
+such as bicycle dynamo, but care should
+be taken that battery is not over-charged.
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index 6fa928ed3128..de5430deaf23 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -24,6 +24,8 @@
 #include linux/usb/otg.h
 #include linux/i2c/twl4030-madc.h
 
+#define TWL4030_BCIMDEN0x00
+#define TWL4030_BCIMDKEY   0x01
 #define TWL4030_BCIMSTATEC 0x02
 #define TWL4030_BCIICHG0x08
 #define TWL4030_BCIVAC 0x0a
@@ -35,13 +37,16 @@
 #define TWL4030_BCIIREF1   0x27
 #define TWL4030_BCIIREF2   0x28
 #define TWL4030_BCIMFKEY   0x11
+#define TWL4030_BCIMFEN3   0x14
 #define TWL4030_BCIMFTH8   0x1d
 #define TWL4030_BCIMFTH9   0x1e
+#define TWL4030_BCIWDKEY   0x21
 
 #define TWL4030_BCIMFSTS1  0x01
 
 #define TWL4030_BCIAUTOWEN BIT(5)
 #define TWL4030_CONFIG_DONEBIT(4)
+#define TWL4030_CVENAC BIT(2)
 #define TWL4030_BCIAUTOUSB BIT(1)
 #define TWL4030_BCIAUTOAC  BIT(0)
 #define TWL4030_CGAIN  BIT(5)
@@ -112,12 +117,13 @@ struct twl4030_bci {
int usb_mode; /* charging mode requested */
 #defineCHARGE_OFF  0
 #defineCHARGE_AUTO 1
+#defineCHARGE_LINEAR   2
 
unsigned long   event;
 };
 
 /* strings for 'usb_mode' values */
-static char *modes[] = { off, auto };
+static char *modes[] = { off, auto, continuous };
 
 /*
  * clear and set bits on an given register on a given module
@@ -404,16 +410,42 @@ static int twl4030_charger_enable_usb(struct twl4030_bci 
*bci, bool enable)
bci-usb_enabled = 1;
}
 
-   /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
-   ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
-   if (ret  0)
-   return ret;
+   if (bci-usb_mode == CHARGE_AUTO)
+   /* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
+   ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
 
/* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0,
TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
+   if (bci-usb_mode == CHARGE_LINEAR) {
+   
twl4030_clear_set_boot_bci(TWL4030_BCIAUTOAC|TWL4030_CVENAC, 0);
+   /* Watch dog key: WOVF acknowledge */
+   ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,
+  TWL4030_BCIWDKEY);
+   /* 0x24 + EKEY6: off mode */
+   ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a,
+  TWL4030_BCIMDKEY);
+   /* EKEY2: Linear charge: USB path */
+   ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x26,
+  TWL4030_BCIMDKEY);
+   /* WDKEY5: stop watchdog count */
+   ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xf3,
+  TWL4030_BCIWDKEY);
+   /* enable MFEN3 access */
+   ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 

RE: [PATCH 2/3] drivers: usb: dwc3: Add adjust_frame_length_quirk

2015-07-29 Thread Badola Nikhil
 -Original Message-
 From: Felipe Balbi [mailto:ba...@ti.com]
 Sent: Monday, July 27, 2015 8:38 PM
 To: Badola Nikhil-B46172
 Cc: ba...@ti.com; linux-ker...@vger.kernel.org; linux-...@vger.kernel.org;
 linux-omap@vger.kernel.org; gre...@linuxfoundation.org
 Subject: Re: [PATCH 2/3] drivers: usb: dwc3: Add adjust_frame_length_quirk
 
 On Mon, Jul 27, 2015 at 06:56:48AM +, Badola Nikhil wrote:
   -Original Message-
   From: Felipe Balbi [mailto:ba...@ti.com]
   Sent: Thursday, July 23, 2015 8:39 PM
   To: Felipe Balbi
   Cc: Badola Nikhil-B46172; linux-ker...@vger.kernel.org; linux-
   u...@vger.kernel.org; linux-omap@vger.kernel.org;
   gre...@linuxfoundation.org
   Subject: Re: [PATCH 2/3] drivers: usb: dwc3: Add
   adjust_frame_length_quirk
  
   Hi again,
  
   On Thu, Jul 23, 2015 at 09:55:32AM -0500, Felipe Balbi wrote:
 diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
 index
 0447788..b7a5119 100644
 --- a/drivers/usb/dwc3/core.h
 +++ b/drivers/usb/dwc3/core.h
 @@ -124,6 +124,7 @@
  #define DWC3_GEVNTCOUNT(n)   (0xc40c + (n * 0x10))

  #define DWC3_GHWPARAMS8  0xc600
 +#define DWC3_GFLADJ  0xc630

  /* Device Registers */
  #define DWC3_DCFG0xc700
 @@ -234,6 +235,10 @@
  /* Global HWPARAMS6 Register */
  #define DWC3_GHWPARAMS6_EN_FPGA  (1 
 7)

 +/* Global Frame Length Adjustment Register */
 +#define GFLADJ_30MHZ_REG_SEL (1  7)
   
always prepend with DWC3_ like *all* other macros in this file.
   
Also, match docs to ease grepping. This should be called
DWC3_GFLADJ_30MHZ_SDBND_SEL
 
  GFLADJ_30MHZ_REG_SEL is the field's name in LS1021A Reference Manual
  as well as dwc3 databook. Though DWC3_GFLADJ_30MHZ_SDBND_SEL
 seems
  more relevant.
 
 databook calls it GFLADJ_30MHZ_SDBND_SEL, I checked before sending my
 email.
 
   yet another problem is that this register doesn't exist in *all*
   versions of DWC3. It was introduced in version 2.50a so the branch I
   typed above needs one extra check, and since it's getting so large,
   it deserves be factored out into its own function.
  
   static int dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) {
 u32 reg;
 u32 dft;
  
 if (dwc-revision = DWC3_REVISION_250A)
 return 0;
  
 if (fladj == 0)
 return 0;
  
 reg = dwc3_readl(dwc-regs, DWC3_GFLADJ);
 dft = reg  0x3f; /* needs a mask macro */
  
 if (!dev_WARN_ONCE(dwc-dev, dft == fladj,
 requested value same as default, ignoring\n)) {
 reg = ~0x3f; /* needs a mask macro */
 reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL |
 DWC3_GFLADJ_30MHZ(fladj_value);
  
 dwc3_writel(dwc-regs, DWC3_GFLADJ, reg);
 }
   }
  
   you really *MUST* check this sort of this out when writing patches.
   It's not only about *your* SoC. You gotta remember we have a ton of
   different users and those a prone to major grumpyness should a
   completely unrelated patch break their use case.
  
   You have access to the IP's documentation, and that contains the
   entire history of the IP itself, so it's easy to figure all of this
   out with a simple search in the documentation.
  
   One extra detail is that you were very careless when writing to the
   GFLADJ register too. You simply wrote your 30MHz sideband value,
   potentially clearing other bits which shouldn't be touched. That
   alone can add regressions.
  
   When resending, make sure all 3 patches reach linux-usb. I still
   can't find patch 3/3.
  
 
  Will take care of above scenarios and resend patches cc'ing linux-usb
  in each of them.
 
  Regarding acceptance of the patch only when it's used in glue layer,
  there is no freescale's glue layer present for dwc3 as of now.
 
 if there is no glue layer, how are you testing your patch ?

We directly call dwc3_probe() . Please see usb node in file 
arch/arm/boot/dts/ls1021a.dtsi 
For your reference : 

usb3@310 {
compatible = snps,dwc3;
reg = 0x0 0x310 0x0 0x1;
interrupts = GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH;
dr_mode = host;
};

 
  Furthermore, there is not any platform specific code required in glue
  layer apart from the ones present in dwc3/core.c.
 
 sorry ? core.c is generic for all users, the glue layer should somewhat hide
 platform details such as clocks and PM. It's surprising if you don't need
 anything on that side.

We do not support power management for now. Also we are not sure
If we need clocks and will look into it when we start working on power 
management.
I would request you to accept this patch set (after modifications which you 
suggested) so that usb functionality doesn't break.
I will send an incremental patch to use this frame length adjust patch via glue 
layer
as soon as we 

Re: [PATCH 03/12] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver

2015-07-29 Thread Roger Quadros
On 29/07/15 15:13, nick wrote:
 
 
 On 2015-07-29 08:06 AM, Roger Quadros wrote:
 Tony,

 On 13/07/15 15:40, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150713 03:07]:
 Tony,

 On 13/07/15 10:10, Tony Lindgren wrote:
 * Roger Quadros rog...@ti.com [150710 05:26]:
 Since the Interrupt Events are used only by the NAND driver,
 there is no point in managing the Interrupt registers
 in the GPMC driver and complicating it with irqchip modeling.

 I don't think it's a good idea to allow external drivers to
 tinker directly with GPMC registers. How about just set up GPMC
 as an irqchip for the edge detection interrupts?

 I think we already have devices with multiple NAND chips. And
 there's nothing stopping other drivers from using the edge
 detection interrupts.

 OK. The GPMC_IRQ registers manage 2 NAND specific interrupts
 (terminalcount and fifo) and 'n' WAIT pin edge interrupts.

  So we can model this as a irqchip with 'n + 2' interrupts.

 OK

 For the wait pins irqchip is not sufficient and it needs to be gpiochip
 with irqchip. Waitpin status can be read from GPIO_STATUS register.

 Just getting the interrupt is not enough and we want to know if the
 line is high or low. That is how nand-dev_ready works.

 How about having 2 IRQ domains?
 One is irqchip with 2 interrupts (terminalcount and fifo) and second is
 gpiochip + irqchip for the n wait pins.

 The nand driver can then be modified to use GPIO to get Read/Busy
 pin status from the wait pin.

 cheers,
 -roger

 Doesn't OMAP boards support shared IRQs and if so why not share them across 
 one
 IRQ domain if possible to save IRQ domains for other hardware that needs its 
 own IRQ domain. This is just a suggestion through as I don't have the hardware
 spec sheet on me Roger.

IRQ domain is a virtual abstraction introduced to prevent kernel irq number 
overlapping
in a single flat domain. I don't see what you can save by domain reuse.
Some memory maybe at most.

Shared interrupt is something totally different but we're trying to add real
hardware interrupts here. Didn't understand what you will share it with.

cheers,
-roger

 Nick 
  
 We need to take care that if a GPMC chip select needs a
 wait pin then it can't be used as a generic interrupt.

 We need to get rid of omap_dev_ready() in nand/omap2.c as
 it accesses the GPMC_STATUS register directly. Plus it is
 hard coded to only monitor wait0 pin.

 OK
  
 What is the best map we should use for irqchip?
 Some Socs have 4 WAIT pins, some have 3 and some have 2.

 Should we start with 0,1,2, for the wait pins and use the next
 available free one for the NAND?

 Maybe we can just use the bits defined for each SoC in the
 GPMC_IRQSTATUS register for the mapping?  
 Regards,

 Tony


 __
 Linux MTD discussion mailing list
 http://lists.infradead.org/mailman/listinfo/linux-mtd/

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] drivers: usb: dwc3: Add adjust_frame_length_quirk

2015-07-29 Thread Felipe Balbi
Hi,

On Wed, Jul 29, 2015 at 11:19:01AM +, Badola Nikhil wrote:
yet another problem is that this register doesn't exist in *all*
versions of DWC3. It was introduced in version 2.50a so the branch I
typed above needs one extra check, and since it's getting so large,
it deserves be factored out into its own function.
   
static int dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) {
u32 reg;
u32 dft;
   
if (dwc-revision = DWC3_REVISION_250A)
return 0;
   
if (fladj == 0)
return 0;
   
reg = dwc3_readl(dwc-regs, DWC3_GFLADJ);
dft = reg  0x3f; /* needs a mask macro */
   
if (!dev_WARN_ONCE(dwc-dev, dft == fladj,
requested value same as default, ignoring\n)) {
reg = ~0x3f; /* needs a mask macro */
reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL |
DWC3_GFLADJ_30MHZ(fladj_value);
   
dwc3_writel(dwc-regs, DWC3_GFLADJ, reg);
}
}
   
you really *MUST* check this sort of this out when writing patches.
It's not only about *your* SoC. You gotta remember we have a ton of
different users and those a prone to major grumpyness should a
completely unrelated patch break their use case.
   
You have access to the IP's documentation, and that contains the
entire history of the IP itself, so it's easy to figure all of this
out with a simple search in the documentation.
   
One extra detail is that you were very careless when writing to the
GFLADJ register too. You simply wrote your 30MHz sideband value,
potentially clearing other bits which shouldn't be touched. That
alone can add regressions.
   
When resending, make sure all 3 patches reach linux-usb. I still
can't find patch 3/3.
   
  
   Will take care of above scenarios and resend patches cc'ing linux-usb
   in each of them.
  
   Regarding acceptance of the patch only when it's used in glue layer,
   there is no freescale's glue layer present for dwc3 as of now.
  
  if there is no glue layer, how are you testing your patch ?
 
 We directly call dwc3_probe() . Please see usb node in file
 arch/arm/boot/dts/ls1021a.dtsi For your reference : 
 
 usb3@310 {
 compatible = snps,dwc3;
 reg = 0x0 0x310 0x0 0x1;
 interrupts = GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH;
 dr_mode = host;
 };

first time I see an SoC which needs nothing for its IP wrapper :-)
pretty cool.

   Furthermore, there is not any platform specific code required in glue
   layer apart from the ones present in dwc3/core.c.
  
  sorry ? core.c is generic for all users, the glue layer should somewhat hide
  platform details such as clocks and PM. It's surprising if you don't need
  anything on that side.
 
 We do not support power management for now. Also we are not sure If we
 need clocks and will look into it when we start working on power
 management.
 I would request you to accept this patch set (after modifications
 which you suggested) so that usb functionality doesn't break.
 I will send an incremental patch to use this frame length adjust patch
 via glue layer as soon as we introduce one. 

sure, the only problem with that, is that if you end up adding a glue
layer, your old DTS sources will likely stop wotrking, but we'll get to
that when we get to that.

-- 
balbi


signature.asc
Description: Digital signature