All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-09 20:40 ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi All,

This patch set has been a while in the making, so I'm very happy to present
the end result here, and I hope everyone likes it.

Before talking about merging this there are 2 things which I would like to
point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
mapped to the musb controller by poking some bits in the SRAM controller,
just like the EMAC patches which were send a while back I've chosen to use
syscon for this, actually 2 of the patches in this set come directly from the
SRAM mapping patchset for the EMAC.

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM
controller:
1) syscon was specifically designed for global system control registers like
this and is fine to use as long as there are no conflicts where 1 bit is of
interest to multiple drivers, and there is no such conflict here
2) Maxime's other arguments seem to boil down to it would be nice / prettier
to have a specific driver for this, without really proving a hard need for
such a driver. But writing such a driver is going to be a lot of work, and
we've a ton of other work to do, and as said there is no real need for a
separate driver, syscon works fine for this.
3) I actually believe that having a specific driver for this is a bad idea,
because that means inventing a whole new cross driver API for this, and
getting those right is, hard, a lot of work, and even then one is still likely
to get it wrong. We can avoid all this by going with the proven syscon solution.

Maxime, can we please have your ack for moving forward with this using syscon?
(see above for my arguments why)


b) If you look closely at the new drivers/usb/musb/sunxi.c file you will see
that there is some register address translation happening in the
sunxi_musb_readb() function and related functions. This is necessary because
the registermap of the sunxi musb implementation is different from the other
musb implementation and sunxi uses multi-platform kernels.

I've considered adding full dynamic register map support to musb but I've
chosen not to. The problem is that the way the musb code currently works is
that there are 4 different address spaces used within the musb code:

1) musb->regs, the base address of the controller used for general control
register access like the DEVCTL and POWER regs

2) The address space at the offset returned by musb_io.ep_offset, which
contains ep control registers, this may be a different offset per endpoint,
or indexed by the INDEX register

3) The address space at the offset returned by musb_io.fifo_offset, which
contains the endpoint fifo data register, this is a different offset per ep.

4) The address space at the offset returned by MUSB_BUSCTL_OFFSET macro
(which gets repaced by musb_io.busctl_offset in this patchset), this may be a
different offset per endpoint, or indexed by the INDEX register

Turning this into something using dynamic register mapping is quite hard, esp.
since some parts of the address range are per endpoint and the number of
endpoints varies from one implementation to the next.

Besides this there also is the issue that I lack hardware to test invasive
changes like this for all different musb variants. So I've chosen to do the
necessary address translation (which really is only necessary for the general
control registers) in a sunxi specific readb & friends implementation, avoiding
the need to make invasive chances elsewhere and thus hopefully avoiding any
regressions.

Note that some small core changes are still necessary, mostly to rationalize
the busctl register handling, and make it more generic as sunxi has indexed
busctl registers.


So with that all said lets talk about getting this merged upstream, assuming
that the code passes review :)

The first patch in the set adds a header with defines for the sun4i syscon
registers. Since this has already been acked by one of the MFD maintainers,
I suggest we simply merge this through the musb maintainer together with all
the other musb patches, as this introduces a new file without changing any
other files collisions are impossible.

The second patch makes some minimal changes to the phy-sun4i-usb driver,
I believe it is best to merge this through the musb maintainer too, so that
all buildtime deps go in through one tree. Kishon can you review this patch
please and let us know if it is ok to merge this through the musb tree?

Then we get 5 musb patches, 4 preparation patches and 1 adding the actual
sunxi musb support, which should go through the musb tree obviously.

So assuming everyone agrees this means that patches 1 - 7 should be merged
through Felipe's tree. Felipe, is that ok with you and can you review these
patches please?

That leaves us with patches 8 - 15 which are all sunxi dts patches and as such
should go upstream through Maxime's tree once patches 1 - 7 are queued up
for merging. Maxime can you give these a review so that I can address any
comments, so that they will be ready to go once patches 1 - 7 are in place ?

Thanks & Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-09 20:40 ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi All,

This patch set has been a while in the making, so I'm very happy to present
the end result here, and I hope everyone likes it.

Before talking about merging this there are 2 things which I would like to
point out:

a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
mapped to the musb controller by poking some bits in the SRAM controller,
just like the EMAC patches which were send a while back I've chosen to use
syscon for this, actually 2 of the patches in this set come directly from the
SRAM mapping patchset for the EMAC.

I know that Maxime is not 100% in favor of using syscon:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html

But I disagree with his arguments for writing a special driver for the SRAM
controller:
1) syscon was specifically designed for global system control registers like
this and is fine to use as long as there are no conflicts where 1 bit is of
interest to multiple drivers, and there is no such conflict here
2) Maxime's other arguments seem to boil down to it would be nice / prettier
to have a specific driver for this, without really proving a hard need for
such a driver. But writing such a driver is going to be a lot of work, and
we've a ton of other work to do, and as said there is no real need for a
separate driver, syscon works fine for this.
3) I actually believe that having a specific driver for this is a bad idea,
because that means inventing a whole new cross driver API for this, and
getting those right is, hard, a lot of work, and even then one is still likely
to get it wrong. We can avoid all this by going with the proven syscon solution.

Maxime, can we please have your ack for moving forward with this using syscon?
(see above for my arguments why)


b) If you look closely at the new drivers/usb/musb/sunxi.c file you will see
that there is some register address translation happening in the
sunxi_musb_readb() function and related functions. This is necessary because
the registermap of the sunxi musb implementation is different from the other
musb implementation and sunxi uses multi-platform kernels.

I've considered adding full dynamic register map support to musb but I've
chosen not to. The problem is that the way the musb code currently works is
that there are 4 different address spaces used within the musb code:

1) musb->regs, the base address of the controller used for general control
register access like the DEVCTL and POWER regs

2) The address space at the offset returned by musb_io.ep_offset, which
contains ep control registers, this may be a different offset per endpoint,
or indexed by the INDEX register

3) The address space at the offset returned by musb_io.fifo_offset, which
contains the endpoint fifo data register, this is a different offset per ep.

4) The address space at the offset returned by MUSB_BUSCTL_OFFSET macro
(which gets repaced by musb_io.busctl_offset in this patchset), this may be a
different offset per endpoint, or indexed by the INDEX register

Turning this into something using dynamic register mapping is quite hard, esp.
since some parts of the address range are per endpoint and the number of
endpoints varies from one implementation to the next.

Besides this there also is the issue that I lack hardware to test invasive
changes like this for all different musb variants. So I've chosen to do the
necessary address translation (which really is only necessary for the general
control registers) in a sunxi specific readb & friends implementation, avoiding
the need to make invasive chances elsewhere and thus hopefully avoiding any
regressions.

Note that some small core changes are still necessary, mostly to rationalize
the busctl register handling, and make it more generic as sunxi has indexed
busctl registers.


So with that all said lets talk about getting this merged upstream, assuming
that the code passes review :)

The first patch in the set adds a header with defines for the sun4i syscon
registers. Since this has already been acked by one of the MFD maintainers,
I suggest we simply merge this through the musb maintainer together with all
the other musb patches, as this introduces a new file without changing any
other files collisions are impossible.

The second patch makes some minimal changes to the phy-sun4i-usb driver,
I believe it is best to merge this through the musb maintainer too, so that
all buildtime deps go in through one tree. Kishon can you review this patch
please and let us know if it is ok to merge this through the musb tree?

Then we get 5 musb patches, 4 preparation patches and 1 adding the actual
sunxi musb support, which should go through the musb tree obviously.

So assuming everyone agrees this means that patches 1 - 7 should be merged
through Felipe's tree. Felipe, is that ok with you and can you review these
patches please?

That leaves us with patches 8 - 15 which are all sunxi dts patches and as such
should go upstream through Maxime's tree once patches 1 - 7 are queued up
for merging. Maxime can you give these a review so that I can address any
comments, so that they will be ready to go once patches 1 - 7 are in place ?

Thanks & Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 01/15] ARM: sunxi: Add register bit definitions for SRAM mapping syscon
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Jens Kuske, Hans de Goede

From: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Signed-off-by: Jens Kuske <jenskuske-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Acked-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 include/linux/mfd/syscon/sun4i-sc.h | 42 +++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 include/linux/mfd/syscon/sun4i-sc.h

diff --git a/include/linux/mfd/syscon/sun4i-sc.h b/include/linux/mfd/syscon/sun4i-sc.h
new file mode 100644
index 0000000..fb970d9
--- /dev/null
+++ b/include/linux/mfd/syscon/sun4i-sc.h
@@ -0,0 +1,42 @@
+/**
+ * sun4i-sc.h - Allwinner sun4i system control register bit definitions
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai  <wens-jdAy2FN1RRM@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_SUN4I_SC_H
+#define __LINUX_SUN4I_SC_H
+
+#include <linux/bitops.h>
+
+/* Registers */
+#define SUN4I_SC0	0x00
+#define SUN4I_SC1	0x04
+
+/* SRAM control register 0 bits */
+#define SUN4I_SC0_SRAM_C1_MAP_VE	0x7fffffff
+
+/* SRAM control register 1 bits */
+#define SUN4I_SC1_BIST_NDMA_CTRL_SEL	BIT(31)
+#define SUN4I_SC1_SRAM_C3_MAP_ISP	BIT(12)
+#define SUN4I_SC1_SRAM_C2_MAP_MASK	0x0300
+#define SUN4I_SC1_SRAM_C2_MAP_AE	0x0100
+#define SUN4I_SC1_SRAM_C2_MAP_CE	0x0200
+#define SUN4I_SC1_SRAM_C2_MAP_ACE	0x0300
+#define SUN4I_SC1_SRAM_A3_A4_MAP_MASK	0x0030
+#define SUN4I_SC1_SRAM_A3_A4_MAP_EMAC	0x0010
+#define SUN4I_SC1_SRAM_D_MAP_USB0	BIT(0)
+
+#endif /* __LINUX_SUN4I_SC_H */
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 01/15] ARM: sunxi: Add register bit definitions for SRAM mapping syscon
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chen-Yu Tsai <wens@csie.org>

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Jens Kuske <jenskuske@gmail.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 include/linux/mfd/syscon/sun4i-sc.h | 42 +++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 include/linux/mfd/syscon/sun4i-sc.h

diff --git a/include/linux/mfd/syscon/sun4i-sc.h b/include/linux/mfd/syscon/sun4i-sc.h
new file mode 100644
index 0000000..fb970d9
--- /dev/null
+++ b/include/linux/mfd/syscon/sun4i-sc.h
@@ -0,0 +1,42 @@
+/**
+ * sun4i-sc.h - Allwinner sun4i system control register bit definitions
+ *
+ * Copyright (C) 2014 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai  <wens@csie.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_SUN4I_SC_H
+#define __LINUX_SUN4I_SC_H
+
+#include <linux/bitops.h>
+
+/* Registers */
+#define SUN4I_SC0	0x00
+#define SUN4I_SC1	0x04
+
+/* SRAM control register 0 bits */
+#define SUN4I_SC0_SRAM_C1_MAP_VE	0x7fffffff
+
+/* SRAM control register 1 bits */
+#define SUN4I_SC1_BIST_NDMA_CTRL_SEL	BIT(31)
+#define SUN4I_SC1_SRAM_C3_MAP_ISP	BIT(12)
+#define SUN4I_SC1_SRAM_C2_MAP_MASK	0x0300
+#define SUN4I_SC1_SRAM_C2_MAP_AE	0x0100
+#define SUN4I_SC1_SRAM_C2_MAP_CE	0x0200
+#define SUN4I_SC1_SRAM_C2_MAP_ACE	0x0300
+#define SUN4I_SC1_SRAM_A3_A4_MAP_MASK	0x0030
+#define SUN4I_SC1_SRAM_A3_A4_MAP_EMAC	0x0010
+#define SUN4I_SC1_SRAM_D_MAP_USB0	BIT(0)
+
+#endif /* __LINUX_SUN4I_SC_H */
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

Add sun4i_usb_phy_update_iscr() helper function to allow the otg driver to
update the sun4i usb phy0 Interface Status and Control Register.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 drivers/phy/phy-sun4i-usb.c       | 13 +++++++++++++
 include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 include/linux/phy/phy-sun4i-usb.h

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index a2b08f3c..4742d5a 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -79,6 +79,19 @@ struct sun4i_usb_phy_data {
 #define to_sun4i_usb_phy_data(phy) \
 	container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
 
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+	u32 iscr;
+
+	iscr = readl(data->base + REG_ISCR);
+	iscr &= ~clr;
+	iscr |= set;
+	writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+
 static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 				int len)
 {
diff --git a/include/linux/phy/phy-sun4i-usb.h b/include/linux/phy/phy-sun4i-usb.h
new file mode 100644
index 0000000..f69e784
--- /dev/null
+++ b/include/linux/phy/phy-sun4i-usb.h
@@ -0,0 +1,26 @@
+/*
+ * Allwinner sun4i USB phy header
+ *
+ * Copyright (C) 2015 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PHY_SUN4I_USB_H
+#define __PHY_SUN4I_USB_H
+
+#include <linux/phy/phy.h>
+
+/**
+ * sun4i_usb_phy_update_iscr() - Update sun4i usb phy0 Interface Status and
+ * Control bits
+ * @phy: Reference to sun4i usb phy0
+ * @clr: bits to clear in the ISCR register
+ * @set: bits to set in the ISCR register
+ */
+void sun4i_usb_phy_update_iscr(struct phy *phy, u32 clr, u32 set);
+
+#endif
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Add sun4i_usb_phy_update_iscr() helper function to allow the otg driver to
update the sun4i usb phy0 Interface Status and Control Register.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/phy/phy-sun4i-usb.c       | 13 +++++++++++++
 include/linux/phy/phy-sun4i-usb.h | 26 ++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 include/linux/phy/phy-sun4i-usb.h

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index a2b08f3c..4742d5a 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -79,6 +79,19 @@ struct sun4i_usb_phy_data {
 #define to_sun4i_usb_phy_data(phy) \
 	container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
 
+void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
+{
+	struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
+	struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
+	u32 iscr;
+
+	iscr = readl(data->base + REG_ISCR);
+	iscr &= ~clr;
+	iscr |= set;
+	writel(iscr, data->base + REG_ISCR);
+}
+EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
+
 static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 				int len)
 {
diff --git a/include/linux/phy/phy-sun4i-usb.h b/include/linux/phy/phy-sun4i-usb.h
new file mode 100644
index 0000000..f69e784
--- /dev/null
+++ b/include/linux/phy/phy-sun4i-usb.h
@@ -0,0 +1,26 @@
+/*
+ * Allwinner sun4i USB phy header
+ *
+ * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PHY_SUN4I_USB_H
+#define __PHY_SUN4I_USB_H
+
+#include <linux/phy/phy.h>
+
+/**
+ * sun4i_usb_phy_update_iscr() - Update sun4i usb phy0 Interface Status and
+ * Control bits
+ * @phy: Reference to sun4i usb phy0
+ * @clr: bits to clear in the ISCR register
+ * @set: bits to set in the ISCR register
+ */
+void sun4i_usb_phy_update_iscr(struct phy *phy, u32 clr, u32 set);
+
+#endif
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 03/15] musb: Make musb_write_rxfun* and musb_write_rxhub* work like their tx versions
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

For some reason the musb_write_rxfun* and musb_write_rxhub* functions had
a different function prototype and some extra magic needed on the caller side
compared to their tx counterparts, this commit makes them work the same as
their tx counterparts.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 drivers/usb/musb/musb_core.c | 11 +++--------
 drivers/usb/musb/musb_core.h |  2 --
 drivers/usb/musb/musb_host.c | 12 ++++++------
 drivers/usb/musb/musb_regs.h | 31 ++++++++++++-------------------
 4 files changed, 21 insertions(+), 35 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index e6f4cbf..2c43b59 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1546,7 +1546,6 @@ static int musb_core_init(u16 musb_type, struct musb *musb)
 #endif
 
 		hw_ep->regs = musb->io.ep_offset(i, 0) + mbase;
-		hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
 		hw_ep->rx_reinit = 1;
 		hw_ep->tx_reinit = 1;
 
@@ -2332,7 +2331,6 @@ static void musb_restore_context(struct musb *musb)
 {
 	int i;
 	void __iomem *musb_base = musb->mregs;
-	void __iomem *ep_target_regs;
 	void __iomem *epio;
 	u8 power;
 
@@ -2400,14 +2398,11 @@ static void musb_restore_context(struct musb *musb)
 		musb_write_txhubport(musb_base, i,
 				musb->context.index_regs[i].txhubport);
 
-		ep_target_regs =
-			musb_read_target_reg_base(i, musb_base);
-
-		musb_write_rxfunaddr(ep_target_regs,
+		musb_write_rxfunaddr(musb_base, i,
 				musb->context.index_regs[i].rxfunaddr);
-		musb_write_rxhubaddr(ep_target_regs,
+		musb_write_rxhubaddr(musb_base, i,
 				musb->context.index_regs[i].rxhubaddr);
-		musb_write_rxhubport(ep_target_regs,
+		musb_write_rxhubport(musb_base, i,
 				musb->context.index_regs[i].rxhubport);
 	}
 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 5e65958..a31d709 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -240,8 +240,6 @@ struct musb_hw_ep {
 	void __iomem		*fifo_sync_va;
 #endif
 
-	void __iomem		*target_regs;
-
 	/* currently scheduled peripheral endpoint */
 	struct musb_qh		*in_qh;
 	struct musb_qh		*out_qh;
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 883a9ad..77006ee 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -555,8 +555,9 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err)
  * the busy/not-empty tests are basically paranoia.
  */
 static void
-musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
+musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
 {
+	struct musb_hw_ep *ep = musb->endpoints + epnum;
 	u16	csr;
 
 	/* NOTE:  we know the "rx" fifo reinit never triggers for ep0.
@@ -594,10 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-		musb_write_rxfunaddr(ep->target_regs, qh->addr_reg);
-		musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg);
-		musb_write_rxhubport(ep->target_regs, qh->h_port_reg);
-
+		musb_write_rxfunaddr(musb->mregs, epnum, qh->addr_reg);
+		musb_write_rxhubaddr(musb->mregs, epnum, qh->h_addr_reg);
+		musb_write_rxhubport(musb->mregs, epnum, qh->h_port_reg);
 	} else
 		musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -875,7 +875,7 @@ finish:
 		u16	csr;
 
 		if (hw_ep->rx_reinit) {
-			musb_rx_reinit(musb, qh, hw_ep);
+			musb_rx_reinit(musb, qh, epnum);
 
 			/* init new state: toggle and NYET, maybe DMA later */
 			if (usb_gettoggle(urb->dev, qh->epnum, 0))
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 11f0be0..edfc730 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -364,27 +364,25 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return musb_readw(mbase, MUSB_HWVERS);
 }
 
-static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-{
-	return (MUSB_BUSCTL_OFFSET(i, 0) + mbase);
-}
-
-static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR),
+			qh_addr_reg);
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_h_addr_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR),
+			qh_h_addr_reg);
 }
 
-static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT),
+			qh_h_port_reg);
 }
 
 static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
@@ -556,22 +554,17 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return MUSB_HWVERS_1900;
 }
 
-static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-{
-	return NULL;
-}
-
-static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_addr_req)
 {
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_h_addr_reg)
 {
 }
 
-static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
 		u8 qh_h_port_reg)
 {
 }
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 03/15] musb: Make musb_write_rxfun* and musb_write_rxhub* work like their tx versions
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

For some reason the musb_write_rxfun* and musb_write_rxhub* functions had
a different function prototype and some extra magic needed on the caller side
compared to their tx counterparts, this commit makes them work the same as
their tx counterparts.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb/musb_core.c | 11 +++--------
 drivers/usb/musb/musb_core.h |  2 --
 drivers/usb/musb/musb_host.c | 12 ++++++------
 drivers/usb/musb/musb_regs.h | 31 ++++++++++++-------------------
 4 files changed, 21 insertions(+), 35 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index e6f4cbf..2c43b59 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1546,7 +1546,6 @@ static int musb_core_init(u16 musb_type, struct musb *musb)
 #endif
 
 		hw_ep->regs = musb->io.ep_offset(i, 0) + mbase;
-		hw_ep->target_regs = musb_read_target_reg_base(i, mbase);
 		hw_ep->rx_reinit = 1;
 		hw_ep->tx_reinit = 1;
 
@@ -2332,7 +2331,6 @@ static void musb_restore_context(struct musb *musb)
 {
 	int i;
 	void __iomem *musb_base = musb->mregs;
-	void __iomem *ep_target_regs;
 	void __iomem *epio;
 	u8 power;
 
@@ -2400,14 +2398,11 @@ static void musb_restore_context(struct musb *musb)
 		musb_write_txhubport(musb_base, i,
 				musb->context.index_regs[i].txhubport);
 
-		ep_target_regs =
-			musb_read_target_reg_base(i, musb_base);
-
-		musb_write_rxfunaddr(ep_target_regs,
+		musb_write_rxfunaddr(musb_base, i,
 				musb->context.index_regs[i].rxfunaddr);
-		musb_write_rxhubaddr(ep_target_regs,
+		musb_write_rxhubaddr(musb_base, i,
 				musb->context.index_regs[i].rxhubaddr);
-		musb_write_rxhubport(ep_target_regs,
+		musb_write_rxhubport(musb_base, i,
 				musb->context.index_regs[i].rxhubport);
 	}
 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 5e65958..a31d709 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -240,8 +240,6 @@ struct musb_hw_ep {
 	void __iomem		*fifo_sync_va;
 #endif
 
-	void __iomem		*target_regs;
-
 	/* currently scheduled peripheral endpoint */
 	struct musb_qh		*in_qh;
 	struct musb_qh		*out_qh;
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 883a9ad..77006ee 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -555,8 +555,9 @@ musb_host_packet_rx(struct musb *musb, struct urb *urb, u8 epnum, u8 iso_err)
  * the busy/not-empty tests are basically paranoia.
  */
 static void
-musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
+musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
 {
+	struct musb_hw_ep *ep = musb->endpoints + epnum;
 	u16	csr;
 
 	/* NOTE:  we know the "rx" fifo reinit never triggers for ep0.
@@ -594,10 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-		musb_write_rxfunaddr(ep->target_regs, qh->addr_reg);
-		musb_write_rxhubaddr(ep->target_regs, qh->h_addr_reg);
-		musb_write_rxhubport(ep->target_regs, qh->h_port_reg);
-
+		musb_write_rxfunaddr(musb->mregs, epnum, qh->addr_reg);
+		musb_write_rxhubaddr(musb->mregs, epnum, qh->h_addr_reg);
+		musb_write_rxhubport(musb->mregs, epnum, qh->h_port_reg);
 	} else
 		musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -875,7 +875,7 @@ finish:
 		u16	csr;
 
 		if (hw_ep->rx_reinit) {
-			musb_rx_reinit(musb, qh, hw_ep);
+			musb_rx_reinit(musb, qh, epnum);
 
 			/* init new state: toggle and NYET, maybe DMA later */
 			if (usb_gettoggle(urb->dev, qh->epnum, 0))
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index 11f0be0..edfc730 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -364,27 +364,25 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return musb_readw(mbase, MUSB_HWVERS);
 }
 
-static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-{
-	return (MUSB_BUSCTL_OFFSET(i, 0) + mbase);
-}
-
-static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR),
+			qh_addr_reg);
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_h_addr_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR),
+			qh_h_addr_reg);
 }
 
-static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg);
+	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT),
+			qh_h_port_reg);
 }
 
 static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
@@ -556,22 +554,17 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return MUSB_HWVERS_1900;
 }
 
-static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-{
-	return NULL;
-}
-
-static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_addr_req)
 {
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
 		u8 qh_h_addr_reg)
 {
 }
 
-static inline void musb_write_rxhubport(void __iomem *ep_target_regs,
+static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
 		u8 qh_h_port_reg)
 {
 }
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 04/15] musb: Make busctl_offset an io-op rather then a define
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

The Allwinner (sunxi) implementation of the musb has its busctl registers
indexed by the MUSB_INDEX register rather then in a flat address space.

This commit turns MUSB_BUSCTL_OFFSET from a macro into an io-op which can
be overridden from the platform ops.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 drivers/usb/musb/musb_core.c | 34 +++++++++++++++---------
 drivers/usb/musb/musb_core.h |  5 +++-
 drivers/usb/musb/musb_host.c | 12 ++++-----
 drivers/usb/musb/musb_io.h   |  2 ++
 drivers/usb/musb/musb_regs.h | 63 ++++++++++++++++++++++++--------------------
 5 files changed, 68 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 2c43b59..b71d310 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -250,6 +250,11 @@ static u32 musb_indexed_ep_offset(u8 epnum, u16 offset)
 	return 0x10 + offset;
 }
 
+static u32 musb_default_busctl_offset(u8 epnum, u16 offset)
+{
+	return 0x80 + (0x08 * epnum) + offset;
+}
+
 static u8 musb_default_readb(const void __iomem *addr, unsigned offset)
 {
 	return __raw_readb(addr + offset);
@@ -2039,6 +2044,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	else
 		musb->io.fifo_offset = musb_default_fifo_offset;
 
+	if (musb->ops->busctl_offset)
+		musb->io.busctl_offset = musb->ops->busctl_offset;
+	else
+		musb->io.busctl_offset = musb_default_busctl_offset;
+
 	if (musb->ops->readb)
 		musb_readb = musb->ops->readb;
 	if (musb->ops->writeb)
@@ -2312,18 +2322,18 @@ static void musb_save_context(struct musb *musb)
 			musb_readb(epio, MUSB_RXINTERVAL);
 
 		musb->context.index_regs[i].txfunaddr =
-			musb_read_txfunaddr(musb_base, i);
+			musb_read_txfunaddr(musb, i);
 		musb->context.index_regs[i].txhubaddr =
-			musb_read_txhubaddr(musb_base, i);
+			musb_read_txhubaddr(musb, i);
 		musb->context.index_regs[i].txhubport =
-			musb_read_txhubport(musb_base, i);
+			musb_read_txhubport(musb, i);
 
 		musb->context.index_regs[i].rxfunaddr =
-			musb_read_rxfunaddr(musb_base, i);
+			musb_read_rxfunaddr(musb, i);
 		musb->context.index_regs[i].rxhubaddr =
-			musb_read_rxhubaddr(musb_base, i);
+			musb_read_rxhubaddr(musb, i);
 		musb->context.index_regs[i].rxhubport =
-			musb_read_rxhubport(musb_base, i);
+			musb_read_rxhubport(musb, i);
 	}
 }
 
@@ -2391,18 +2401,18 @@ static void musb_restore_context(struct musb *musb)
 		musb_writeb(epio, MUSB_RXINTERVAL,
 
 				musb->context.index_regs[i].rxinterval);
-		musb_write_txfunaddr(musb_base, i,
+		musb_write_txfunaddr(musb, i,
 				musb->context.index_regs[i].txfunaddr);
-		musb_write_txhubaddr(musb_base, i,
+		musb_write_txhubaddr(musb, i,
 				musb->context.index_regs[i].txhubaddr);
-		musb_write_txhubport(musb_base, i,
+		musb_write_txhubport(musb, i,
 				musb->context.index_regs[i].txhubport);
 
-		musb_write_rxfunaddr(musb_base, i,
+		musb_write_rxfunaddr(musb, i,
 				musb->context.index_regs[i].rxfunaddr);
-		musb_write_rxhubaddr(musb_base, i,
+		musb_write_rxhubaddr(musb, i,
 				musb->context.index_regs[i].rxhubaddr);
-		musb_write_rxhubport(musb_base, i,
+		musb_write_rxhubport(musb, i,
 				musb->context.index_regs[i].rxhubport);
 	}
 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index a31d709..ba8dd78 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -67,7 +67,6 @@ struct musb_ep;
 #include "musb_dma.h"
 
 #include "musb_io.h"
-#include "musb_regs.h"
 
 #include "musb_gadget.h"
 #include <linux/usb/hcd.h>
@@ -186,6 +185,7 @@ struct musb_platform_ops {
 	void	(*ep_select)(void __iomem *mbase, u8 epnum);
 	u16	fifo_mode;
 	u32	(*fifo_offset)(u8 epnum);
+	u32	(*busctl_offset)(u8 epnum, u16 offset);
 	u8	(*readb)(const void __iomem *addr, unsigned offset);
 	void	(*writeb)(void __iomem *addr, unsigned offset, u8 data);
 	u16	(*readw)(const void __iomem *addr, unsigned offset);
@@ -435,6 +435,9 @@ struct musb {
 #endif
 };
 
+/* This must be included after struct musb is defined */
+#include "musb_regs.h"
+
 static inline struct musb *gadget_to_musb(struct usb_gadget *g)
 {
 	return container_of(g, struct musb, g);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 77006ee..e2fabef 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -595,9 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-		musb_write_rxfunaddr(musb->mregs, epnum, qh->addr_reg);
-		musb_write_rxhubaddr(musb->mregs, epnum, qh->h_addr_reg);
-		musb_write_rxhubport(musb->mregs, epnum, qh->h_port_reg);
+		musb_write_rxfunaddr(musb, epnum, qh->addr_reg);
+		musb_write_rxhubaddr(musb, epnum, qh->h_addr_reg);
+		musb_write_rxhubport(musb, epnum, qh->h_port_reg);
 	} else
 		musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -801,9 +801,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 
 		/* target addr and (for multipoint) hub addr/port */
 		if (musb->is_multipoint) {
-			musb_write_txfunaddr(mbase, epnum, qh->addr_reg);
-			musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg);
-			musb_write_txhubport(mbase, epnum, qh->h_port_reg);
+			musb_write_txfunaddr(musb, epnum, qh->addr_reg);
+			musb_write_txhubaddr(musb, epnum, qh->h_addr_reg);
+			musb_write_txhubport(musb, epnum, qh->h_port_reg);
 /* FIXME if !epnum, do the same for RX ... */
 		} else
 			musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index 8a57a6f..17a80ae 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -47,6 +47,7 @@
  * @fifo_offset: platform specific function to get fifo offset
  * @read_fifo:	platform specific function to read fifo
  * @write_fifo:	platform specific function to write fifo
+ * @busctl_offset: platform specific function to get busctl offset
  */
 struct musb_io {
 	u32	quirks;
@@ -55,6 +56,7 @@ struct musb_io {
 	u32	(*fifo_offset)(u8 epnum);
 	void	(*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
 	void	(*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
+	u32	(*busctl_offset)(u8 epnum, u16 offset);
 };
 
 /* Do not add new entries here, add them the struct musb_io instead */
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index edfc730..cff5bcf 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -300,9 +300,6 @@
 #define MUSB_RXHUBADDR		0x06
 #define MUSB_RXHUBPORT		0x07
 
-#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
-	(0x80 + (8*(_epnum)) + (_offset))
-
 static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
 {
 	musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
@@ -364,76 +361,84 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return musb_readw(mbase, MUSB_HWVERS);
 }
 
-static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_rxfunaddr(struct musb *musb, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR),
-			qh_addr_reg);
+	musb_writeb(musb->mregs,
+		    musb->io.busctl_offset(epnum, MUSB_RXFUNCADDR),
+		    qh_addr_reg);
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_rxhubaddr(struct musb *musb, u8 epnum,
 		u8 qh_h_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_RXHUBADDR),
 			qh_h_addr_reg);
 }
 
-static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
+static inline void musb_write_rxhubport(struct musb *musb, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_RXHUBPORT),
 			qh_h_port_reg);
 }
 
-static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_txfunaddr(struct musb *musb, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
-			qh_addr_reg);
+	musb_writeb(musb->mregs,
+		    musb->io.busctl_offset(epnum, MUSB_TXFUNCADDR),
+		    qh_addr_reg);
 }
 
-static inline void  musb_write_txhubaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_txhubaddr(struct musb *musb, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_TXHUBADDR),
 			qh_addr_reg);
 }
 
-static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
+static inline void musb_write_txhubport(struct musb *musb, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_TXHUBPORT),
 			qh_h_port_reg);
 }
 
-static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_rxfunaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_RXFUNCADDR));
 }
 
-static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_rxhubaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_RXHUBADDR));
 }
 
-static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_rxhubport(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_RXHUBPORT));
 }
 
-static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txfunaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_TXFUNCADDR));
 }
 
-static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txhubaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_TXHUBADDR));
 }
 
-static inline u8  musb_read_txhubport(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txhubport(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_TXHUBPORT));
 }
 
 #else /* CONFIG_BLACKFIN */
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 04/15] musb: Make busctl_offset an io-op rather then a define
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

The Allwinner (sunxi) implementation of the musb has its busctl registers
indexed by the MUSB_INDEX register rather then in a flat address space.

This commit turns MUSB_BUSCTL_OFFSET from a macro into an io-op which can
be overridden from the platform ops.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb/musb_core.c | 34 +++++++++++++++---------
 drivers/usb/musb/musb_core.h |  5 +++-
 drivers/usb/musb/musb_host.c | 12 ++++-----
 drivers/usb/musb/musb_io.h   |  2 ++
 drivers/usb/musb/musb_regs.h | 63 ++++++++++++++++++++++++--------------------
 5 files changed, 68 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 2c43b59..b71d310 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -250,6 +250,11 @@ static u32 musb_indexed_ep_offset(u8 epnum, u16 offset)
 	return 0x10 + offset;
 }
 
+static u32 musb_default_busctl_offset(u8 epnum, u16 offset)
+{
+	return 0x80 + (0x08 * epnum) + offset;
+}
+
 static u8 musb_default_readb(const void __iomem *addr, unsigned offset)
 {
 	return __raw_readb(addr + offset);
@@ -2039,6 +2044,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	else
 		musb->io.fifo_offset = musb_default_fifo_offset;
 
+	if (musb->ops->busctl_offset)
+		musb->io.busctl_offset = musb->ops->busctl_offset;
+	else
+		musb->io.busctl_offset = musb_default_busctl_offset;
+
 	if (musb->ops->readb)
 		musb_readb = musb->ops->readb;
 	if (musb->ops->writeb)
@@ -2312,18 +2322,18 @@ static void musb_save_context(struct musb *musb)
 			musb_readb(epio, MUSB_RXINTERVAL);
 
 		musb->context.index_regs[i].txfunaddr =
-			musb_read_txfunaddr(musb_base, i);
+			musb_read_txfunaddr(musb, i);
 		musb->context.index_regs[i].txhubaddr =
-			musb_read_txhubaddr(musb_base, i);
+			musb_read_txhubaddr(musb, i);
 		musb->context.index_regs[i].txhubport =
-			musb_read_txhubport(musb_base, i);
+			musb_read_txhubport(musb, i);
 
 		musb->context.index_regs[i].rxfunaddr =
-			musb_read_rxfunaddr(musb_base, i);
+			musb_read_rxfunaddr(musb, i);
 		musb->context.index_regs[i].rxhubaddr =
-			musb_read_rxhubaddr(musb_base, i);
+			musb_read_rxhubaddr(musb, i);
 		musb->context.index_regs[i].rxhubport =
-			musb_read_rxhubport(musb_base, i);
+			musb_read_rxhubport(musb, i);
 	}
 }
 
@@ -2391,18 +2401,18 @@ static void musb_restore_context(struct musb *musb)
 		musb_writeb(epio, MUSB_RXINTERVAL,
 
 				musb->context.index_regs[i].rxinterval);
-		musb_write_txfunaddr(musb_base, i,
+		musb_write_txfunaddr(musb, i,
 				musb->context.index_regs[i].txfunaddr);
-		musb_write_txhubaddr(musb_base, i,
+		musb_write_txhubaddr(musb, i,
 				musb->context.index_regs[i].txhubaddr);
-		musb_write_txhubport(musb_base, i,
+		musb_write_txhubport(musb, i,
 				musb->context.index_regs[i].txhubport);
 
-		musb_write_rxfunaddr(musb_base, i,
+		musb_write_rxfunaddr(musb, i,
 				musb->context.index_regs[i].rxfunaddr);
-		musb_write_rxhubaddr(musb_base, i,
+		musb_write_rxhubaddr(musb, i,
 				musb->context.index_regs[i].rxhubaddr);
-		musb_write_rxhubport(musb_base, i,
+		musb_write_rxhubport(musb, i,
 				musb->context.index_regs[i].rxhubport);
 	}
 	musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index a31d709..ba8dd78 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -67,7 +67,6 @@ struct musb_ep;
 #include "musb_dma.h"
 
 #include "musb_io.h"
-#include "musb_regs.h"
 
 #include "musb_gadget.h"
 #include <linux/usb/hcd.h>
@@ -186,6 +185,7 @@ struct musb_platform_ops {
 	void	(*ep_select)(void __iomem *mbase, u8 epnum);
 	u16	fifo_mode;
 	u32	(*fifo_offset)(u8 epnum);
+	u32	(*busctl_offset)(u8 epnum, u16 offset);
 	u8	(*readb)(const void __iomem *addr, unsigned offset);
 	void	(*writeb)(void __iomem *addr, unsigned offset, u8 data);
 	u16	(*readw)(const void __iomem *addr, unsigned offset);
@@ -435,6 +435,9 @@ struct musb {
 #endif
 };
 
+/* This must be included after struct musb is defined */
+#include "musb_regs.h"
+
 static inline struct musb *gadget_to_musb(struct usb_gadget *g)
 {
 	return container_of(g, struct musb, g);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 77006ee..e2fabef 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -595,9 +595,9 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
 
 	/* target addr and (for multipoint) hub addr/port */
 	if (musb->is_multipoint) {
-		musb_write_rxfunaddr(musb->mregs, epnum, qh->addr_reg);
-		musb_write_rxhubaddr(musb->mregs, epnum, qh->h_addr_reg);
-		musb_write_rxhubport(musb->mregs, epnum, qh->h_port_reg);
+		musb_write_rxfunaddr(musb, epnum, qh->addr_reg);
+		musb_write_rxhubaddr(musb, epnum, qh->h_addr_reg);
+		musb_write_rxhubport(musb, epnum, qh->h_port_reg);
 	} else
 		musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg);
 
@@ -801,9 +801,9 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 
 		/* target addr and (for multipoint) hub addr/port */
 		if (musb->is_multipoint) {
-			musb_write_txfunaddr(mbase, epnum, qh->addr_reg);
-			musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg);
-			musb_write_txhubport(mbase, epnum, qh->h_port_reg);
+			musb_write_txfunaddr(musb, epnum, qh->addr_reg);
+			musb_write_txhubaddr(musb, epnum, qh->h_addr_reg);
+			musb_write_txhubport(musb, epnum, qh->h_port_reg);
 /* FIXME if !epnum, do the same for RX ... */
 		} else
 			musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index 8a57a6f..17a80ae 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -47,6 +47,7 @@
  * @fifo_offset: platform specific function to get fifo offset
  * @read_fifo:	platform specific function to read fifo
  * @write_fifo:	platform specific function to write fifo
+ * @busctl_offset: platform specific function to get busctl offset
  */
 struct musb_io {
 	u32	quirks;
@@ -55,6 +56,7 @@ struct musb_io {
 	u32	(*fifo_offset)(u8 epnum);
 	void	(*read_fifo)(struct musb_hw_ep *hw_ep, u16 len, u8 *buf);
 	void	(*write_fifo)(struct musb_hw_ep *hw_ep, u16 len, const u8 *buf);
+	u32	(*busctl_offset)(u8 epnum, u16 offset);
 };
 
 /* Do not add new entries here, add them the struct musb_io instead */
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index edfc730..cff5bcf 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -300,9 +300,6 @@
 #define MUSB_RXHUBADDR		0x06
 #define MUSB_RXHUBPORT		0x07
 
-#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
-	(0x80 + (8*(_epnum)) + (_offset))
-
 static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
 {
 	musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
@@ -364,76 +361,84 @@ static inline u16 musb_read_hwvers(void __iomem *mbase)
 	return musb_readw(mbase, MUSB_HWVERS);
 }
 
-static inline void musb_write_rxfunaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_rxfunaddr(struct musb *musb, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR),
-			qh_addr_reg);
+	musb_writeb(musb->mregs,
+		    musb->io.busctl_offset(epnum, MUSB_RXFUNCADDR),
+		    qh_addr_reg);
 }
 
-static inline void musb_write_rxhubaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_rxhubaddr(struct musb *musb, u8 epnum,
 		u8 qh_h_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_RXHUBADDR),
 			qh_h_addr_reg);
 }
 
-static inline void musb_write_rxhubport(void __iomem *mbase, u8 epnum,
+static inline void musb_write_rxhubport(struct musb *musb, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_RXHUBPORT),
 			qh_h_port_reg);
 }
 
-static inline void  musb_write_txfunaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_txfunaddr(struct musb *musb, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR),
-			qh_addr_reg);
+	musb_writeb(musb->mregs,
+		    musb->io.busctl_offset(epnum, MUSB_TXFUNCADDR),
+		    qh_addr_reg);
 }
 
-static inline void  musb_write_txhubaddr(void __iomem *mbase, u8 epnum,
+static inline void musb_write_txhubaddr(struct musb *musb, u8 epnum,
 		u8 qh_addr_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_TXHUBADDR),
 			qh_addr_reg);
 }
 
-static inline void  musb_write_txhubport(void __iomem *mbase, u8 epnum,
+static inline void musb_write_txhubport(struct musb *musb, u8 epnum,
 		u8 qh_h_port_reg)
 {
-	musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT),
+	musb_writeb(musb->mregs, musb->io.busctl_offset(epnum, MUSB_TXHUBPORT),
 			qh_h_port_reg);
 }
 
-static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_rxfunaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_RXFUNCADDR));
 }
 
-static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_rxhubaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_RXHUBADDR));
 }
 
-static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_rxhubport(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_RXHUBPORT));
 }
 
-static inline u8  musb_read_txfunaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txfunaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_TXFUNCADDR));
 }
 
-static inline u8  musb_read_txhubaddr(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txhubaddr(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_TXHUBADDR));
 }
 
-static inline u8  musb_read_txhubport(void __iomem *mbase, u8 epnum)
+static inline u8 musb_read_txhubport(struct musb *musb, u8 epnum)
 {
-	return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT));
+	return musb_readb(musb->mregs,
+			  musb->io.busctl_offset(epnum, MUSB_TXHUBPORT));
 }
 
 #else /* CONFIG_BLACKFIN */
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

The generic fifo functions already use non wrapped accesses in various
cases through the iowrite#_rep functions, and all platforms which override
the default musb_read[b|w] / _write[b|w] functions also provide their own
fifo access functions, so we can safely drop the unnecessary indirection
from the fifo access functions.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 drivers/usb/musb/musb_core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index b71d310..47c1a0a 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -313,7 +313,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len,
 				index += len & ~0x03;
 			}
 			if (len & 0x02) {
-				musb_writew(fifo, 0, *(u16 *)&src[index]);
+				__raw_writew(*(u16 *)&src[index], fifo);
 				index += 2;
 			}
 		} else {
@@ -323,7 +323,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len,
 			}
 		}
 		if (len & 0x01)
-			musb_writeb(fifo, 0, src[index]);
+			__raw_writeb(src[index], fifo);
 	} else  {
 		/* byte aligned */
 		iowrite8_rep(fifo, src, len);
@@ -355,7 +355,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 				index = len & ~0x03;
 			}
 			if (len & 0x02) {
-				*(u16 *)&dst[index] = musb_readw(fifo, 0);
+				*(u16 *)&dst[index] = __raw_readw(fifo);
 				index += 2;
 			}
 		} else {
@@ -365,7 +365,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 			}
 		}
 		if (len & 0x01)
-			dst[index] = musb_readb(fifo, 0);
+			dst[index] = __raw_readb(fifo);
 	} else  {
 		/* byte aligned */
 		ioread8_rep(fifo, dst, len);
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

The generic fifo functions already use non wrapped accesses in various
cases through the iowrite#_rep functions, and all platforms which override
the default musb_read[b|w] / _write[b|w] functions also provide their own
fifo access functions, so we can safely drop the unnecessary indirection
from the fifo access functions.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb/musb_core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index b71d310..47c1a0a 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -313,7 +313,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len,
 				index += len & ~0x03;
 			}
 			if (len & 0x02) {
-				musb_writew(fifo, 0, *(u16 *)&src[index]);
+				__raw_writew(*(u16 *)&src[index], fifo);
 				index += 2;
 			}
 		} else {
@@ -323,7 +323,7 @@ static void musb_default_write_fifo(struct musb_hw_ep *hw_ep, u16 len,
 			}
 		}
 		if (len & 0x01)
-			musb_writeb(fifo, 0, src[index]);
+			__raw_writeb(src[index], fifo);
 	} else  {
 		/* byte aligned */
 		iowrite8_rep(fifo, src, len);
@@ -355,7 +355,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 				index = len & ~0x03;
 			}
 			if (len & 0x02) {
-				*(u16 *)&dst[index] = musb_readw(fifo, 0);
+				*(u16 *)&dst[index] = __raw_readw(fifo);
 				index += 2;
 			}
 		} else {
@@ -365,7 +365,7 @@ static void musb_default_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 			}
 		}
 		if (len & 0x01)
-			dst[index] = musb_readb(fifo, 0);
+			dst[index] = __raw_readb(fifo);
 	} else  {
 		/* byte aligned */
 		ioread8_rep(fifo, dst, len);
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 06/15] musb: Fix platform code being unable to override ep access ops
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

musb-core was setting the ops to the default indexed or flat handlers after
checking for platform overrides. Reverse the order of this so that platform
overrides actually work.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 drivers/usb/musb/musb_core.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 47c1a0a..374d181 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2019,13 +2019,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	if (musb->ops->quirks)
 		musb->io.quirks = musb->ops->quirks;
 
-	/* At least tusb6010 has it's own offsets.. */
-	if (musb->ops->ep_offset)
-		musb->io.ep_offset = musb->ops->ep_offset;
-	if (musb->ops->ep_select)
-		musb->io.ep_select = musb->ops->ep_select;
-
-	/* ..and some devices use indexed offset or flat offset */
+	/* Set default ep access to indexed offset or flat offset ops */
 	if (musb->io.quirks & MUSB_INDEXED_EP) {
 		musb->io.ep_offset = musb_indexed_ep_offset;
 		musb->io.ep_select = musb_indexed_ep_select;
@@ -2033,6 +2027,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->io.ep_offset = musb_flat_ep_offset;
 		musb->io.ep_select = musb_flat_ep_select;
 	}
+	/* And override them with platform specific ops if specified. */
+	if (musb->ops->ep_offset)
+		musb->io.ep_offset = musb->ops->ep_offset;
+	if (musb->ops->ep_select)
+		musb->io.ep_select = musb->ops->ep_select;
 
 	if (musb->ops->fifo_mode)
 		fifo_mode = musb->ops->fifo_mode;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 06/15] musb: Fix platform code being unable to override ep access ops
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

musb-core was setting the ops to the default indexed or flat handlers after
checking for platform overrides. Reverse the order of this so that platform
overrides actually work.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb/musb_core.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 47c1a0a..374d181 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2019,13 +2019,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	if (musb->ops->quirks)
 		musb->io.quirks = musb->ops->quirks;
 
-	/* At least tusb6010 has it's own offsets.. */
-	if (musb->ops->ep_offset)
-		musb->io.ep_offset = musb->ops->ep_offset;
-	if (musb->ops->ep_select)
-		musb->io.ep_select = musb->ops->ep_select;
-
-	/* ..and some devices use indexed offset or flat offset */
+	/* Set default ep access to indexed offset or flat offset ops */
 	if (musb->io.quirks & MUSB_INDEXED_EP) {
 		musb->io.ep_offset = musb_indexed_ep_offset;
 		musb->io.ep_select = musb_indexed_ep_select;
@@ -2033,6 +2027,11 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->io.ep_offset = musb_flat_ep_offset;
 		musb->io.ep_select = musb_flat_ep_select;
 	}
+	/* And override them with platform specific ops if specified. */
+	if (musb->ops->ep_offset)
+		musb->io.ep_offset = musb->ops->ep_offset;
+	if (musb->ops->ep_select)
+		musb->io.ep_select = musb->ops->ep_select;
 
 	if (musb->ops->fifo_mode)
 		fifo_mode = musb->ops->fifo_mode;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 07/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

This is based on initial code to get the Allwinner sunxi musb controller
supported by Chen-Yu Tsai and Roman Byshko.

This adds support for the Allwinner sunxi musb controller in both host only
and otg mode. Peripheral only mode is not supported, as no boards use that.

This has been tested on a cubietruck (A20 SoC) and an UTOO P66 tablet
(A13 SoC) with a variety of devices in host mode and with the g_serial gadget
driver in peripheral mode, plugging otg / host cables in/out a lot of times
in all possible imaginable plug orders.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 .../bindings/usb/allwinner,sun4i-a10-musb.txt      |  27 +
 drivers/usb/musb/Kconfig                           |   9 +-
 drivers/usb/musb/Makefile                          |   1 +
 drivers/usb/musb/musb_core.h                       |   1 +
 drivers/usb/musb/musb_gadget.c                     |   6 +
 drivers/usb/musb/musb_virthub.c                    |   6 +
 drivers/usb/musb/sunxi.c                           | 788 +++++++++++++++++++++
 7 files changed, 837 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
 create mode 100644 drivers/usb/musb/sunxi.c

diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
new file mode 100644
index 0000000..22b6887
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
@@ -0,0 +1,27 @@
+Allwinner sun4i A10 musb DRC/OTG controller
+-------------------------------------------
+
+Required properties:
+ - compatible      : "allwinner,sun4i-a10-musb"
+ - reg             : mmio address range of the musb controller
+ - clocks          : clock specifier for the musb controller ahb gate clock
+ - interrupts      : interrupt to which the musb controller is connected
+ - interrupt-names : must be "mc"
+ - phys            : phy specifier for the otg phy
+ - phy-names       : must be "usb"
+ - syscons         : syscon specifier
+ - dr_mode         : Dual-Role mode must be "host" or "otg"
+
+Example:
+
+	usb_otg: usb@01c13000 {
+		compatible = "allwinner,sun4i-a10-musb";
+		reg = <0x01c13000 0x0400>;
+		clocks = <&ahb_gates 0>;
+		interrupts = <38>;
+		interrupt-names = "mc";
+		phys = <&usbphy 0>;
+		phy-names = "usb";
+		syscons = <&syscon>;
+		status = "disabled";
+	};
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 14e1628..8180a3a 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -5,7 +5,7 @@
 
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
-	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
+	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, AW, ...)'
 	depends on (USB || USB_GADGET)
 	help
 	  Say Y here if your system has a dual role high speed USB
@@ -20,6 +20,8 @@ config USB_MUSB_HDRC
 	  Analog Devices parts using this IP include Blackfin BF54x,
 	  BF525 and BF527.
 
+	  Allwinner SoCs using this IP include A10, A13, A20, ...
+
 	  If you do not know what this is, please say N.
 
 	  To compile this driver as a module, choose M here; the
@@ -60,6 +62,11 @@ endchoice
 
 comment "Platform Glue Layer"
 
+config USB_MUSB_SUNXI
+	tristate "Allwinner (sunxi)"
+	depends on ARCH_SUNXI
+	select GENERIC_PHY
+
 config USB_MUSB_DAVINCI
 	tristate "DaVinci"
 	depends on ARCH_DAVINCI_DMx
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index ba49501..f95befe 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
 obj-$(CONFIG_USB_MUSB_BLACKFIN)			+= blackfin.o
 obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
 obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
+obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
 
 
 obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index ba8dd78..444b936 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -166,6 +166,7 @@ struct musb_io;
  */
 struct musb_platform_ops {
 
+#define MUSB_SUN4I		BIT(7)
 #define MUSB_DMA_UX500		BIT(6)
 #define MUSB_DMA_CPPI41		BIT(5)
 #define MUSB_DMA_CPPI		BIT(4)
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index b2d9040..7d13eb9 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -2041,6 +2041,12 @@ void musb_g_disconnect(struct musb *musb)
 		spin_lock(&musb->lock);
 	}
 
+	/* On sunxi ep0 FADDR must be 0 when (re)entering peripheral mode */
+	if (musb->io.quirks & MUSB_SUN4I) {
+		musb_ep_select(musb->mregs, 0);
+		musb_writeb(musb->mregs, MUSB_FADDR, 0);
+	}
+
 	switch (musb->xceiv->otg->state) {
 	default:
 		dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n",
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index 294e159..3c87fd7 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -224,6 +224,12 @@ void musb_root_disconnect(struct musb *musb)
 	usb_hcd_poll_rh_status(musb->hcd);
 	musb->is_active = 0;
 
+	/* On sunxi ep0 FADDR must be 0 when (re)entering peripheral mode */
+	if (musb->io.quirks & MUSB_SUN4I) {
+		musb_ep_select(musb->mregs, 0);
+		musb_writeb(musb->mregs, MUSB_FADDR, 0);
+	}
+
 	switch (musb->xceiv->otg->state) {
 	case OTG_STATE_A_SUSPEND:
 		if (otg->host->b_hnp_enable) {
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
new file mode 100644
index 0000000..a566040
--- /dev/null
+++ b/drivers/usb/musb/sunxi.c
@@ -0,0 +1,788 @@
+/*
+ * Allwinner sun4i MUSB Glue Layer
+ *
+ * Copyright (C) 2015 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/sun4i-sc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy-sun4i-usb.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/usb/musb.h>
+#include <linux/usb/of.h>
+#include <linux/usb/usb_phy_generic.h>
+#include <linux/workqueue.h>
+#include "musb_core.h"
+
+/*
+ * Note do not raise the debounce time, we must report Vusb high within 100ms
+ * of a session being requested otherwise we get Vbus errors
+ */
+#define SUNXI_MUSB_DEBOUNCE_TIME		msecs_to_jiffies(50)
+#define SUNXI_MUSB_POLL_TIME			msecs_to_jiffies(250)
+
+/*
+ * Register offsets, note sunxi musb has a different layout then most
+ * musb implementations, we translate the layout in musb_readb & friends.
+ */
+#define SUNXI_MUSB_POWER			0x0040
+#define SUNXI_MUSB_DEVCTL			0x0041
+#define SUNXI_MUSB_INDEX			0x0042
+#define SUNXI_MUSB_VEND0			0x0043
+#define SUNXI_MUSB_INTRTX			0x0044
+#define SUNXI_MUSB_INTRRX			0x0046
+#define SUNXI_MUSB_INTRTXE			0x0048
+#define SUNXI_MUSB_INTRRXE			0x004a
+#define SUNXI_MUSB_INTRUSB			0x004c
+#define SUNXI_MUSB_INTRUSBE			0x0050
+#define SUNXI_MUSB_FRAME			0x0054
+#define SUNXI_MUSB_TXFIFOSZ			0x0090
+#define SUNXI_MUSB_TXFIFOADD			0x0092
+#define SUNXI_MUSB_RXFIFOSZ			0x0094
+#define SUNXI_MUSB_RXFIFOADD			0x0096
+#define SUNXI_MUSB_FADDR			0x0098
+#define SUNXI_MUSB_TXFUNCADDR			0x0098
+#define SUNXI_MUSB_TXHUBADDR			0x009a
+#define SUNXI_MUSB_TXHUBPORT			0x009b
+#define SUNXI_MUSB_RXFUNCADDR			0x009c
+#define SUNXI_MUSB_RXHUBADDR			0x009e
+#define SUNXI_MUSB_RXHUBPORT			0x009f
+#define SUNXI_MUSB_CONFIGDATA			0x00c0
+
+/* VEND0 bits */
+#define  SUNXI_MUSB_VEND0_PIO_MODE		0
+
+/* ISCR, Interface Status and Control bits */
+#define  SUNXI_ISCR_ID_PULLUP_EN		(1 << 17)
+#define  SUNXI_ISCR_DPDM_PULLUP_EN		(1 << 16)
+/* sunxi has the phy id/vbus pins not connected, so we use the force bits */
+#define  SUNXI_ISCR_FORCE_ID_MASK		(3 << 14)
+#define  SUNXI_ISCR_FORCE_ID_LOW		(2 << 14)
+#define  SUNXI_ISCR_FORCE_ID_HIGH		(3 << 14)
+#define  SUNXI_ISCR_FORCE_VBUS_MASK	(3 << 12)
+#define  SUNXI_ISCR_FORCE_VBUS_LOW		(2 << 12)
+#define  SUNXI_ISCR_FORCE_VBUS_HIGH	(3 << 12)
+
+/* Our read/write methods need access and do not get passed in a musb ref :| */
+struct musb *sunxi_musb;
+
+struct sunxi_glue {
+	struct device		*dev;
+	struct platform_device	*musb;
+	struct regmap		*sc;
+	struct clk		*clk;
+	struct phy		*phy;
+	struct platform_device	*usb_phy;
+	struct usb_phy		*xceiv;
+	struct gpio_desc	*id_det_gpio;
+	struct gpio_desc	*vbus_det_gpio;
+	int			id_det_irq;
+	int			vbus_det_irq;
+	u8			id_det;
+	u8			vbus_det;
+	u8			vbus_on;
+	u8			enabled;
+	struct delayed_work	detect;
+};
+
+static void sunxi_musb_force_id(struct musb *musb, u32 val)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	if (val)
+		val = SUNXI_ISCR_FORCE_ID_HIGH;
+	else
+		val = SUNXI_ISCR_FORCE_ID_LOW;
+
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
+}
+
+static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	if (val)
+		val = SUNXI_ISCR_FORCE_VBUS_HIGH;
+	else
+		val = SUNXI_ISCR_FORCE_VBUS_LOW;
+
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
+}
+
+/* Called with musb locked */
+static void sunxi_musb_set_vbus(struct musb *musb, int is_on)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	if (is_on) {
+		/* Turn on Vbus only if we don't have an ext. Vbus */
+		if (!glue->vbus_on && !glue->vbus_det) {
+			phy_power_on(glue->phy);
+			glue->vbus_on = 1;
+		}
+	} else {
+		if (glue->vbus_on) {
+			phy_power_off(glue->phy);
+			glue->vbus_on = 0;
+		}
+	}
+}
+
+static void sunxi_musb_id_vbus_det_scan(struct work_struct *work)
+{
+	struct sunxi_glue *glue =
+		container_of(work, struct sunxi_glue, detect.work);
+	struct musb *musb = dev_get_drvdata(&glue->musb->dev);
+	u8 id_det, vbus_det, devctl, set_vbus = 0, rescan = 0;
+	unsigned long delay, flags;
+
+	id_det = gpiod_get_value_cansleep(glue->id_det_gpio);
+	vbus_det = gpiod_get_value_cansleep(glue->vbus_det_gpio);
+
+	spin_lock_irqsave(&musb->lock, flags);
+
+	if (!glue->enabled) {
+		spin_unlock_irqrestore(&musb->lock, flags);
+		return;
+	}
+
+	if (vbus_det != glue->vbus_det) {
+		sunxi_musb_force_vbus(musb, vbus_det);
+		glue->vbus_det = vbus_det;
+	}
+
+	if (id_det != glue->id_det) {
+		sunxi_musb_force_id(musb, id_det);
+		devctl = readb(musb->mregs + SUNXI_MUSB_DEVCTL);
+		if (id_det == 0) {
+			sunxi_musb_set_vbus(musb, 1);
+			set_vbus = 1;
+			musb->xceiv->otg->default_a = 1;
+			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+			MUSB_HST_MODE(musb);
+			devctl |= MUSB_DEVCTL_SESSION;
+		} else {
+			sunxi_musb_set_vbus(musb, 0);
+			/*
+			 * Vbus typically slowly discharges, sometimes this
+			 * causes the Vbus gpio to not trigger an edge irq
+			 * on Vbus off, so force a rescan.
+			 */
+			rescan = 1;
+			musb->xceiv->otg->default_a = 0;
+			musb->xceiv->otg->state = OTG_STATE_B_IDLE;
+			MUSB_DEV_MODE(musb);
+			devctl &= ~MUSB_DEVCTL_SESSION;
+		}
+		writeb(devctl, musb->mregs + SUNXI_MUSB_DEVCTL);
+		glue->id_det = id_det;
+	}
+
+	/* If one of the pins does not support irqs, we must poll */
+	if (glue->id_det_irq < 0 || glue->vbus_det_irq < 0 || rescan) {
+		delay = set_vbus ? SUNXI_MUSB_DEBOUNCE_TIME :
+				   SUNXI_MUSB_POLL_TIME;
+		queue_delayed_work(system_wq, &glue->detect, delay);
+	}
+
+	spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static irqreturn_t sunxi_musb_id_vbus_det_irq(int irq, void *dev_id)
+{
+	struct sunxi_glue *glue = dev_id;
+
+	/* vbus or id changed, let the pins settle and then scan them */
+	queue_delayed_work(system_wq, &glue->detect, SUNXI_MUSB_DEBOUNCE_TIME);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
+{
+	struct musb     *musb = __hci;
+	unsigned long   flags;
+
+	spin_lock_irqsave(&musb->lock, flags);
+
+	musb->int_usb = readb(musb->mregs + SUNXI_MUSB_INTRUSB);
+	if (musb->int_usb)
+		writeb(musb->int_usb, musb->mregs + SUNXI_MUSB_INTRUSB);
+
+	/*
+	 * sunxi musb often signals babble on low / full speed device
+	 * disconnect, without ever raising MUSB_INTR_DISCONNECT, since
+	 * normally babble never happens treat it as disconnect.
+	 */
+	if ((musb->int_usb & MUSB_INTR_BABBLE) && is_host_active(musb)) {
+		musb->int_usb &= ~MUSB_INTR_BABBLE;
+		musb->int_usb |= MUSB_INTR_DISCONNECT;
+	}
+
+	musb->int_tx = readw(musb->mregs + SUNXI_MUSB_INTRTX);
+	if (musb->int_tx)
+		writew(musb->int_tx, musb->mregs + SUNXI_MUSB_INTRTX);
+
+	musb->int_rx = readw(musb->mregs + SUNXI_MUSB_INTRRX);
+	if (musb->int_rx)
+		writew(musb->int_rx, musb->mregs + SUNXI_MUSB_INTRRX);
+
+	musb_interrupt(musb);
+
+	spin_unlock_irqrestore(&musb->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int sunxi_musb_init(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+	int ret;
+
+	sunxi_musb = musb;
+	musb->phy = glue->phy;
+	musb->xceiv = glue->xceiv;
+
+	ret = regmap_update_bits(glue->sc, SUN4I_SC1,
+				 SUN4I_SC1_SRAM_D_MAP_USB0, 1);
+	if (ret)
+		return ret;
+
+	ret = phy_init(glue->phy);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(glue->clk);
+	if (ret) {
+		phy_exit(glue->phy);
+		return ret;
+	}
+
+	musb->isr = sunxi_musb_interrupt;
+
+	sun4i_usb_phy_update_iscr(glue->phy, 0, SUNXI_ISCR_DPDM_PULLUP_EN);
+	sun4i_usb_phy_update_iscr(glue->phy, 0, SUNXI_ISCR_ID_PULLUP_EN);
+
+	switch (musb->port_mode) {
+	case MUSB_PORT_MODE_HOST:
+		sunxi_musb_force_id(musb, 0);
+		sunxi_musb_force_vbus(musb, 1);
+		sunxi_musb_set_vbus(musb, 1);
+		break;
+	case MUSB_PORT_MODE_DUAL_ROLE:
+		sunxi_musb_force_id(musb, 1);
+		sunxi_musb_force_vbus(musb, 0);
+		glue->id_det = 1;
+		glue->vbus_det = 0;
+		break;
+	}
+
+	/* Stop the musb-core from doing runtime pm (not supported on sunxi) */
+	pm_runtime_get(musb->controller);
+
+	return 0;
+}
+
+static int sunxi_musb_exit(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	pm_runtime_put(musb->controller);
+
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_DPDM_PULLUP_EN, 0);
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_ID_PULLUP_EN, 0);
+
+	cancel_delayed_work_sync(&glue->detect);
+	clk_disable_unprepare(glue->clk);
+	if (glue->vbus_on)
+		phy_power_off(glue->phy);
+	phy_exit(glue->phy);
+
+	return 0;
+}
+
+/* Called with musb locked */
+static void sunxi_musb_enable(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+	int ret;
+
+	/* musb_core does not call us in a balanced manner */
+	if (glue->enabled)
+		return;
+
+	glue->enabled = 1;
+
+	writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0);
+
+	if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
+		return;
+
+	if (glue->id_det_irq >= 0) {
+		ret = devm_request_irq(glue->dev, glue->id_det_irq,
+				sunxi_musb_id_vbus_det_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"musb-id-det", glue);
+		if (ret) {
+			dev_err(glue->dev,
+				"Error requesting id-det-irq: %d\n", ret);
+			glue->id_det_irq = -1;
+		}
+	}
+
+	if (glue->vbus_det_irq >= 0) {
+		ret = devm_request_irq(glue->dev, glue->vbus_det_irq,
+				sunxi_musb_id_vbus_det_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"musb-vbus-det", glue);
+		if (ret) {
+			dev_err(glue->dev,
+				"Error requesting vbus-det-irq: %d\n", ret);
+			glue->vbus_det_irq = -1;
+		}
+	}
+
+	/* Scan current status / start scanning */
+	queue_delayed_work(system_wq, &glue->detect, 0);
+}
+
+/* Called with musb locked */
+static void sunxi_musb_disable(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	/* musb_core does not call us in a balanced manner */
+	if (glue->enabled == 0)
+		return;
+
+	glue->enabled = 0;
+
+	if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
+		return;
+
+	if (glue->id_det_irq >= 0)
+		free_irq(glue->id_det_irq, glue);
+
+	if (glue->vbus_det_irq >= 0)
+		free_irq(glue->vbus_det_irq, glue);
+}
+
+/*
+ * sunxi musb register layout
+ * 0x00 - 0x17	fifo regs, 1 long per fifo
+ * 0x40	- 0x57	generic control regs (power - frame)
+ * 0x80 - 0x8f	ep control regs (addressed through hw_ep->regs, indexed)
+ * 0x90 - 0x97	fifo control regs (indexed)
+ * 0x98 - 0x9f	multipoint / busctl regs (indexed)
+ * 0xc0		configdata reg
+ */
+
+static u32 sunxi_musb_fifo_offset(u8 epnum)
+{
+	return (epnum * 4);
+}
+
+static u32 sunxi_musb_ep_offset(u8 epnum, u16 offset)
+{
+	WARN_ONCE(offset != 0,
+		  "sunxi_musb_ep_offset called with non 0 offset\n");
+
+	return 0x80; /* indexed, so ignore epnum */
+}
+
+static u32 sunxi_musb_busctl_offset(u8 epnum, u16 offset)
+{
+	return SUNXI_MUSB_TXFUNCADDR + offset;
+}
+
+static u8 sunxi_musb_readb(const void __iomem *addr, unsigned offset)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_FADDR:
+			return readb(addr + SUNXI_MUSB_FADDR);
+		case MUSB_POWER:
+			return readb(addr + SUNXI_MUSB_POWER);
+		case MUSB_INTRUSB:
+			return readb(addr + SUNXI_MUSB_INTRUSB);
+		case MUSB_INTRUSBE:
+			return readb(addr + SUNXI_MUSB_INTRUSBE);
+		case MUSB_INDEX:
+			return readb(addr + SUNXI_MUSB_INDEX);
+		case MUSB_TESTMODE:
+			return 0; /* No testmode on sunxi */
+		case MUSB_DEVCTL:
+			return readb(addr + SUNXI_MUSB_DEVCTL);
+		case MUSB_TXFIFOSZ:
+			return readb(addr + SUNXI_MUSB_TXFIFOSZ);
+		case MUSB_RXFIFOSZ:
+			return readb(addr + SUNXI_MUSB_RXFIFOSZ);
+		case MUSB_CONFIGDATA + 0x10: /* See musb_read_configdata() */
+			return readb(addr + SUNXI_MUSB_CONFIGDATA);
+		/* Offset for these is fixed by sunxi_musb_busctl_offset() */
+		case SUNXI_MUSB_TXFUNCADDR:
+		case SUNXI_MUSB_TXHUBADDR:
+		case SUNXI_MUSB_TXHUBPORT:
+		case SUNXI_MUSB_RXFUNCADDR:
+		case SUNXI_MUSB_RXHUBADDR:
+		case SUNXI_MUSB_RXHUBPORT:
+			/* multipoint / busctl reg access */
+			return readb(addr + offset);
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown readb offset %u\n", offset);
+			return 0;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		/* sunxi has a 2 byte hole before the txtype register */
+		if (offset >= MUSB_TXTYPE)
+			offset += 2;
+		return readb(addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown readb at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+	return 0;
+}
+
+static void sunxi_musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_FADDR:
+			return writeb(data, addr + SUNXI_MUSB_FADDR);
+		case MUSB_POWER:
+			return writeb(data, addr + SUNXI_MUSB_POWER);
+		case MUSB_INTRUSB:
+			return writeb(data, addr + SUNXI_MUSB_INTRUSB);
+		case MUSB_INTRUSBE:
+			return writeb(data, addr + SUNXI_MUSB_INTRUSBE);
+		case MUSB_INDEX:
+			return writeb(data, addr + SUNXI_MUSB_INDEX);
+		case MUSB_TESTMODE:
+			if (data)
+				dev_warn(sunxi_musb->controller->parent,
+					"sunxi-musb does not have testmode\n");
+			return;
+		case MUSB_DEVCTL:
+			return writeb(data, addr + SUNXI_MUSB_DEVCTL);
+		case MUSB_TXFIFOSZ:
+			return writeb(data, addr + SUNXI_MUSB_TXFIFOSZ);
+		case MUSB_RXFIFOSZ:
+			return writeb(data, addr + SUNXI_MUSB_RXFIFOSZ);
+		/* Offset for these is fixed by sunxi_musb_busctl_offset() */
+		case SUNXI_MUSB_TXFUNCADDR:
+		case SUNXI_MUSB_TXHUBADDR:
+		case SUNXI_MUSB_TXHUBPORT:
+		case SUNXI_MUSB_RXFUNCADDR:
+		case SUNXI_MUSB_RXHUBADDR:
+		case SUNXI_MUSB_RXHUBPORT:
+			/* multipoint / busctl reg access */
+			return writeb(data, addr + offset);
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown writeb offset %u\n", offset);
+			return;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		if (offset >= MUSB_TXTYPE)
+			offset += 2;
+		return writeb(data, addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown writeb at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+}
+
+static u16 sunxi_musb_readw(const void __iomem *addr, unsigned offset)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_INTRTX:
+			return readw(addr + SUNXI_MUSB_INTRTX);
+		case MUSB_INTRRX:
+			return readw(addr + SUNXI_MUSB_INTRRX);
+		case MUSB_INTRTXE:
+			return readw(addr + SUNXI_MUSB_INTRTXE);
+		case MUSB_INTRRXE:
+			return readw(addr + SUNXI_MUSB_INTRRXE);
+		case MUSB_FRAME:
+			return readw(addr + SUNXI_MUSB_FRAME);
+		case MUSB_TXFIFOADD:
+			return readw(addr + SUNXI_MUSB_TXFIFOADD);
+		case MUSB_RXFIFOADD:
+			return readw(addr + SUNXI_MUSB_RXFIFOADD);
+		case MUSB_HWVERS:
+			return 0; /* sunxi musb version is not known */
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown readw offset %u\n", offset);
+			return 0;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		return readw(addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown readw at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+	return 0;
+}
+
+static void sunxi_musb_writew(void __iomem *addr, unsigned offset, u16 data)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_INTRTX:
+			return writew(data, addr + SUNXI_MUSB_INTRTX);
+		case MUSB_INTRRX:
+			return writew(data, addr + SUNXI_MUSB_INTRRX);
+		case MUSB_INTRTXE:
+			return writew(data, addr + SUNXI_MUSB_INTRTXE);
+		case MUSB_INTRRXE:
+			return writew(data, addr + SUNXI_MUSB_INTRRXE);
+		case MUSB_FRAME:
+			return writew(data, addr + SUNXI_MUSB_FRAME);
+		case MUSB_TXFIFOADD:
+			return writew(data, addr + SUNXI_MUSB_TXFIFOADD);
+		case MUSB_RXFIFOADD:
+			return writew(data, addr + SUNXI_MUSB_RXFIFOADD);
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown writew offset %u\n", offset);
+			return;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		return writew(data, addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown writew at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+}
+
+static const struct musb_platform_ops sunxi_musb_ops = {
+	.quirks		= MUSB_INDEXED_EP | MUSB_SUN4I,
+	.init		= sunxi_musb_init,
+	.exit		= sunxi_musb_exit,
+	.enable		= sunxi_musb_enable,
+	.disable	= sunxi_musb_disable,
+	.fifo_offset	= sunxi_musb_fifo_offset,
+	.ep_offset	= sunxi_musb_ep_offset,
+	.busctl_offset	= sunxi_musb_busctl_offset,
+	.readb		= sunxi_musb_readb,
+	.writeb		= sunxi_musb_writeb,
+	.readw		= sunxi_musb_readw,
+	.writew		= sunxi_musb_writew,
+	.set_vbus	= sunxi_musb_set_vbus,
+};
+
+/* Allwinner OTG supports up to 5 endpoints */
+#define SUNXI_MUSB_MAX_EP_NUM	6
+#define SUNXI_MUSB_RAM_BITS	11
+
+static struct musb_fifo_cfg sunxi_musb_mode_cfg[] = {
+	MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(5, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512),
+};
+
+static struct musb_hdrc_config sunxi_musb_hdrc_config = {
+	.fifo_cfg       = sunxi_musb_mode_cfg,
+	.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg),
+	.multipoint	= true,
+	.dyn_fifo	= true,
+	.soft_con       = true,
+	.num_eps	= SUNXI_MUSB_MAX_EP_NUM,
+	.ram_bits	= SUNXI_MUSB_RAM_BITS,
+	.dma		= 0,
+};
+
+static int sunxi_musb_probe(struct platform_device *pdev)
+{
+	struct musb_hdrc_platform_data	pdata;
+	struct platform_device_info	pinfo;
+	struct sunxi_glue		*glue;
+	struct device_node		*np = pdev->dev.of_node;
+	int ret;
+
+	if (!np) {
+		dev_err(&pdev->dev, "Error no device tree node found\n");
+		return -EINVAL;
+	}
+
+	memset(&pdata, 0, sizeof(pdata));
+	switch (of_usb_get_dr_mode(np)) {
+	case USB_DR_MODE_HOST:
+		pdata.mode = MUSB_PORT_MODE_HOST;
+		break;
+	case USB_DR_MODE_PERIPHERAL:
+		dev_err(&pdev->dev,
+			"Error peripheral only mode is not supported\n");
+		return -EINVAL;
+	case USB_DR_MODE_OTG:
+		pdata.mode = MUSB_PORT_MODE_DUAL_ROLE;
+		break;
+	default:
+		dev_err(&pdev->dev, "No 'dr_mode' property found\n");
+		return -EINVAL;
+	}
+	pdata.platform_ops	= &sunxi_musb_ops;
+	pdata.config		= &sunxi_musb_hdrc_config;
+
+	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
+	if (!glue)
+		return -ENOMEM;
+
+	glue->dev = &pdev->dev;
+	INIT_DELAYED_WORK(&glue->detect, sunxi_musb_id_vbus_det_scan);
+
+	glue->sc = syscon_regmap_lookup_by_phandle(np, "syscons");
+	if (IS_ERR(glue->sc)) {
+		dev_err(&pdev->dev, "Error getting syscon %ld\n",
+			PTR_ERR(glue->sc));
+		return PTR_ERR(glue->sc);
+	}
+
+	glue->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(glue->clk)) {
+		dev_err(&pdev->dev, "Error getting clock: %ld\n",
+			PTR_ERR(glue->clk));
+		return PTR_ERR(glue->clk);
+	}
+
+	if (pdata.mode == MUSB_PORT_MODE_DUAL_ROLE) {
+		glue->id_det_gpio =
+			devm_gpiod_get(&pdev->dev, "id_det", GPIOD_IN);
+		if (IS_ERR(glue->id_det_gpio)) {
+			dev_err(&pdev->dev, "Error getting id_det gpio\n");
+			return PTR_ERR(glue->id_det_gpio);
+		}
+
+		glue->vbus_det_gpio =
+			devm_gpiod_get(&pdev->dev, "vbus_det", GPIOD_IN);
+		if (IS_ERR(glue->vbus_det_gpio)) {
+			dev_err(&pdev->dev, "Error getting vbus_det gpio\n");
+			return PTR_ERR(glue->vbus_det_gpio);
+		}
+
+		glue->id_det_irq = gpiod_to_irq(glue->id_det_gpio);
+		glue->vbus_det_irq = gpiod_to_irq(glue->vbus_det_gpio);
+	}
+
+	glue->phy = devm_phy_get(&pdev->dev, "usb");
+	if (IS_ERR(glue->phy)) {
+		if (PTR_ERR(glue->phy) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_err(&pdev->dev, "Error getting phy %ld\n",
+			PTR_ERR(glue->phy));
+		return PTR_ERR(glue->phy);
+	}
+
+	glue->usb_phy = usb_phy_generic_register();
+	if (IS_ERR(glue->usb_phy)) {
+		dev_err(&pdev->dev, "Error registering usb-phy %ld\n",
+			PTR_ERR(glue->usb_phy));
+		return PTR_ERR(glue->usb_phy);
+	}
+
+	glue->xceiv = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+	if (IS_ERR(glue->xceiv)) {
+		ret = PTR_ERR(glue->xceiv);
+		dev_err(&pdev->dev, "Error getting usb-phy %d\n", ret);
+		goto err_unregister_usb_phy;
+	}
+
+	platform_set_drvdata(pdev, glue);
+
+	memset(&pinfo, 0, sizeof(pinfo));
+	pinfo.name	 = "musb-hdrc";
+	pinfo.id	= PLATFORM_DEVID_AUTO;
+	pinfo.parent	= &pdev->dev;
+	pinfo.res	= pdev->resource;
+	pinfo.num_res	= pdev->num_resources;
+	pinfo.data	= &pdata;
+	pinfo.size_data = sizeof(pdata);
+
+	glue->musb = platform_device_register_full(&pinfo);
+	if (IS_ERR(glue->musb)) {
+		ret = PTR_ERR(glue->musb);
+		dev_err(&pdev->dev, "Error registering musb dev: %d\n", ret);
+		goto err_unregister_usb_phy;
+	}
+
+	return 0;
+
+err_unregister_usb_phy:
+	usb_phy_generic_unregister(glue->usb_phy);
+	return ret;
+}
+
+static int sunxi_musb_remove(struct platform_device *pdev)
+{
+	struct sunxi_glue *glue = platform_get_drvdata(pdev);
+	struct platform_device *usb_phy = glue->usb_phy;
+
+	platform_device_unregister(glue->musb); /* Frees glue ! */
+	usb_phy_generic_unregister(usb_phy);
+
+	return 0;
+}
+
+static const struct of_device_id sunxi_musb_match[] = {
+	{ .compatible = "allwinner,sun4i-a10-musb", },
+	{}
+};
+
+static struct platform_driver sunxi_musb_driver = {
+	.probe = sunxi_musb_probe,
+	.remove = sunxi_musb_remove,
+	.driver = {
+		.name = "musb-sunxi",
+		.of_match_table = sunxi_musb_match,
+	},
+};
+module_platform_driver(sunxi_musb_driver);
+
+MODULE_DESCRIPTION("Allwinner sunxi MUSB Glue Layer");
+MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 07/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

This is based on initial code to get the Allwinner sunxi musb controller
supported by Chen-Yu Tsai and Roman Byshko.

This adds support for the Allwinner sunxi musb controller in both host only
and otg mode. Peripheral only mode is not supported, as no boards use that.

This has been tested on a cubietruck (A20 SoC) and an UTOO P66 tablet
(A13 SoC) with a variety of devices in host mode and with the g_serial gadget
driver in peripheral mode, plugging otg / host cables in/out a lot of times
in all possible imaginable plug orders.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../bindings/usb/allwinner,sun4i-a10-musb.txt      |  27 +
 drivers/usb/musb/Kconfig                           |   9 +-
 drivers/usb/musb/Makefile                          |   1 +
 drivers/usb/musb/musb_core.h                       |   1 +
 drivers/usb/musb/musb_gadget.c                     |   6 +
 drivers/usb/musb/musb_virthub.c                    |   6 +
 drivers/usb/musb/sunxi.c                           | 788 +++++++++++++++++++++
 7 files changed, 837 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
 create mode 100644 drivers/usb/musb/sunxi.c

diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
new file mode 100644
index 0000000..22b6887
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
@@ -0,0 +1,27 @@
+Allwinner sun4i A10 musb DRC/OTG controller
+-------------------------------------------
+
+Required properties:
+ - compatible      : "allwinner,sun4i-a10-musb"
+ - reg             : mmio address range of the musb controller
+ - clocks          : clock specifier for the musb controller ahb gate clock
+ - interrupts      : interrupt to which the musb controller is connected
+ - interrupt-names : must be "mc"
+ - phys            : phy specifier for the otg phy
+ - phy-names       : must be "usb"
+ - syscons         : syscon specifier
+ - dr_mode         : Dual-Role mode must be "host" or "otg"
+
+Example:
+
+	usb_otg: usb at 01c13000 {
+		compatible = "allwinner,sun4i-a10-musb";
+		reg = <0x01c13000 0x0400>;
+		clocks = <&ahb_gates 0>;
+		interrupts = <38>;
+		interrupt-names = "mc";
+		phys = <&usbphy 0>;
+		phy-names = "usb";
+		syscons = <&syscon>;
+		status = "disabled";
+	};
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 14e1628..8180a3a 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -5,7 +5,7 @@
 
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
-	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
+	tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, AW, ...)'
 	depends on (USB || USB_GADGET)
 	help
 	  Say Y here if your system has a dual role high speed USB
@@ -20,6 +20,8 @@ config USB_MUSB_HDRC
 	  Analog Devices parts using this IP include Blackfin BF54x,
 	  BF525 and BF527.
 
+	  Allwinner SoCs using this IP include A10, A13, A20, ...
+
 	  If you do not know what this is, please say N.
 
 	  To compile this driver as a module, choose M here; the
@@ -60,6 +62,11 @@ endchoice
 
 comment "Platform Glue Layer"
 
+config USB_MUSB_SUNXI
+	tristate "Allwinner (sunxi)"
+	depends on ARCH_SUNXI
+	select GENERIC_PHY
+
 config USB_MUSB_DAVINCI
 	tristate "DaVinci"
 	depends on ARCH_DAVINCI_DMx
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index ba49501..f95befe 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX)			+= da8xx.o
 obj-$(CONFIG_USB_MUSB_BLACKFIN)			+= blackfin.o
 obj-$(CONFIG_USB_MUSB_UX500)			+= ux500.o
 obj-$(CONFIG_USB_MUSB_JZ4740)			+= jz4740.o
+obj-$(CONFIG_USB_MUSB_SUNXI)			+= sunxi.o
 
 
 obj-$(CONFIG_USB_MUSB_AM335X_CHILD)		+= musb_am335x.o
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index ba8dd78..444b936 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -166,6 +166,7 @@ struct musb_io;
  */
 struct musb_platform_ops {
 
+#define MUSB_SUN4I		BIT(7)
 #define MUSB_DMA_UX500		BIT(6)
 #define MUSB_DMA_CPPI41		BIT(5)
 #define MUSB_DMA_CPPI		BIT(4)
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index b2d9040..7d13eb9 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -2041,6 +2041,12 @@ void musb_g_disconnect(struct musb *musb)
 		spin_lock(&musb->lock);
 	}
 
+	/* On sunxi ep0 FADDR must be 0 when (re)entering peripheral mode */
+	if (musb->io.quirks & MUSB_SUN4I) {
+		musb_ep_select(musb->mregs, 0);
+		musb_writeb(musb->mregs, MUSB_FADDR, 0);
+	}
+
 	switch (musb->xceiv->otg->state) {
 	default:
 		dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n",
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c
index 294e159..3c87fd7 100644
--- a/drivers/usb/musb/musb_virthub.c
+++ b/drivers/usb/musb/musb_virthub.c
@@ -224,6 +224,12 @@ void musb_root_disconnect(struct musb *musb)
 	usb_hcd_poll_rh_status(musb->hcd);
 	musb->is_active = 0;
 
+	/* On sunxi ep0 FADDR must be 0 when (re)entering peripheral mode */
+	if (musb->io.quirks & MUSB_SUN4I) {
+		musb_ep_select(musb->mregs, 0);
+		musb_writeb(musb->mregs, MUSB_FADDR, 0);
+	}
+
 	switch (musb->xceiv->otg->state) {
 	case OTG_STATE_A_SUSPEND:
 		if (otg->host->b_hnp_enable) {
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
new file mode 100644
index 0000000..a566040
--- /dev/null
+++ b/drivers/usb/musb/sunxi.c
@@ -0,0 +1,788 @@
+/*
+ * Allwinner sun4i MUSB Glue Layer
+ *
+ * Copyright (C) 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/sun4i-sc.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy-sun4i-usb.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/usb/musb.h>
+#include <linux/usb/of.h>
+#include <linux/usb/usb_phy_generic.h>
+#include <linux/workqueue.h>
+#include "musb_core.h"
+
+/*
+ * Note do not raise the debounce time, we must report Vusb high within 100ms
+ * of a session being requested otherwise we get Vbus errors
+ */
+#define SUNXI_MUSB_DEBOUNCE_TIME		msecs_to_jiffies(50)
+#define SUNXI_MUSB_POLL_TIME			msecs_to_jiffies(250)
+
+/*
+ * Register offsets, note sunxi musb has a different layout then most
+ * musb implementations, we translate the layout in musb_readb & friends.
+ */
+#define SUNXI_MUSB_POWER			0x0040
+#define SUNXI_MUSB_DEVCTL			0x0041
+#define SUNXI_MUSB_INDEX			0x0042
+#define SUNXI_MUSB_VEND0			0x0043
+#define SUNXI_MUSB_INTRTX			0x0044
+#define SUNXI_MUSB_INTRRX			0x0046
+#define SUNXI_MUSB_INTRTXE			0x0048
+#define SUNXI_MUSB_INTRRXE			0x004a
+#define SUNXI_MUSB_INTRUSB			0x004c
+#define SUNXI_MUSB_INTRUSBE			0x0050
+#define SUNXI_MUSB_FRAME			0x0054
+#define SUNXI_MUSB_TXFIFOSZ			0x0090
+#define SUNXI_MUSB_TXFIFOADD			0x0092
+#define SUNXI_MUSB_RXFIFOSZ			0x0094
+#define SUNXI_MUSB_RXFIFOADD			0x0096
+#define SUNXI_MUSB_FADDR			0x0098
+#define SUNXI_MUSB_TXFUNCADDR			0x0098
+#define SUNXI_MUSB_TXHUBADDR			0x009a
+#define SUNXI_MUSB_TXHUBPORT			0x009b
+#define SUNXI_MUSB_RXFUNCADDR			0x009c
+#define SUNXI_MUSB_RXHUBADDR			0x009e
+#define SUNXI_MUSB_RXHUBPORT			0x009f
+#define SUNXI_MUSB_CONFIGDATA			0x00c0
+
+/* VEND0 bits */
+#define  SUNXI_MUSB_VEND0_PIO_MODE		0
+
+/* ISCR, Interface Status and Control bits */
+#define  SUNXI_ISCR_ID_PULLUP_EN		(1 << 17)
+#define  SUNXI_ISCR_DPDM_PULLUP_EN		(1 << 16)
+/* sunxi has the phy id/vbus pins not connected, so we use the force bits */
+#define  SUNXI_ISCR_FORCE_ID_MASK		(3 << 14)
+#define  SUNXI_ISCR_FORCE_ID_LOW		(2 << 14)
+#define  SUNXI_ISCR_FORCE_ID_HIGH		(3 << 14)
+#define  SUNXI_ISCR_FORCE_VBUS_MASK	(3 << 12)
+#define  SUNXI_ISCR_FORCE_VBUS_LOW		(2 << 12)
+#define  SUNXI_ISCR_FORCE_VBUS_HIGH	(3 << 12)
+
+/* Our read/write methods need access and do not get passed in a musb ref :| */
+struct musb *sunxi_musb;
+
+struct sunxi_glue {
+	struct device		*dev;
+	struct platform_device	*musb;
+	struct regmap		*sc;
+	struct clk		*clk;
+	struct phy		*phy;
+	struct platform_device	*usb_phy;
+	struct usb_phy		*xceiv;
+	struct gpio_desc	*id_det_gpio;
+	struct gpio_desc	*vbus_det_gpio;
+	int			id_det_irq;
+	int			vbus_det_irq;
+	u8			id_det;
+	u8			vbus_det;
+	u8			vbus_on;
+	u8			enabled;
+	struct delayed_work	detect;
+};
+
+static void sunxi_musb_force_id(struct musb *musb, u32 val)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	if (val)
+		val = SUNXI_ISCR_FORCE_ID_HIGH;
+	else
+		val = SUNXI_ISCR_FORCE_ID_LOW;
+
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
+}
+
+static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	if (val)
+		val = SUNXI_ISCR_FORCE_VBUS_HIGH;
+	else
+		val = SUNXI_ISCR_FORCE_VBUS_LOW;
+
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
+}
+
+/* Called with musb locked */
+static void sunxi_musb_set_vbus(struct musb *musb, int is_on)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	if (is_on) {
+		/* Turn on Vbus only if we don't have an ext. Vbus */
+		if (!glue->vbus_on && !glue->vbus_det) {
+			phy_power_on(glue->phy);
+			glue->vbus_on = 1;
+		}
+	} else {
+		if (glue->vbus_on) {
+			phy_power_off(glue->phy);
+			glue->vbus_on = 0;
+		}
+	}
+}
+
+static void sunxi_musb_id_vbus_det_scan(struct work_struct *work)
+{
+	struct sunxi_glue *glue =
+		container_of(work, struct sunxi_glue, detect.work);
+	struct musb *musb = dev_get_drvdata(&glue->musb->dev);
+	u8 id_det, vbus_det, devctl, set_vbus = 0, rescan = 0;
+	unsigned long delay, flags;
+
+	id_det = gpiod_get_value_cansleep(glue->id_det_gpio);
+	vbus_det = gpiod_get_value_cansleep(glue->vbus_det_gpio);
+
+	spin_lock_irqsave(&musb->lock, flags);
+
+	if (!glue->enabled) {
+		spin_unlock_irqrestore(&musb->lock, flags);
+		return;
+	}
+
+	if (vbus_det != glue->vbus_det) {
+		sunxi_musb_force_vbus(musb, vbus_det);
+		glue->vbus_det = vbus_det;
+	}
+
+	if (id_det != glue->id_det) {
+		sunxi_musb_force_id(musb, id_det);
+		devctl = readb(musb->mregs + SUNXI_MUSB_DEVCTL);
+		if (id_det == 0) {
+			sunxi_musb_set_vbus(musb, 1);
+			set_vbus = 1;
+			musb->xceiv->otg->default_a = 1;
+			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+			MUSB_HST_MODE(musb);
+			devctl |= MUSB_DEVCTL_SESSION;
+		} else {
+			sunxi_musb_set_vbus(musb, 0);
+			/*
+			 * Vbus typically slowly discharges, sometimes this
+			 * causes the Vbus gpio to not trigger an edge irq
+			 * on Vbus off, so force a rescan.
+			 */
+			rescan = 1;
+			musb->xceiv->otg->default_a = 0;
+			musb->xceiv->otg->state = OTG_STATE_B_IDLE;
+			MUSB_DEV_MODE(musb);
+			devctl &= ~MUSB_DEVCTL_SESSION;
+		}
+		writeb(devctl, musb->mregs + SUNXI_MUSB_DEVCTL);
+		glue->id_det = id_det;
+	}
+
+	/* If one of the pins does not support irqs, we must poll */
+	if (glue->id_det_irq < 0 || glue->vbus_det_irq < 0 || rescan) {
+		delay = set_vbus ? SUNXI_MUSB_DEBOUNCE_TIME :
+				   SUNXI_MUSB_POLL_TIME;
+		queue_delayed_work(system_wq, &glue->detect, delay);
+	}
+
+	spin_unlock_irqrestore(&musb->lock, flags);
+}
+
+static irqreturn_t sunxi_musb_id_vbus_det_irq(int irq, void *dev_id)
+{
+	struct sunxi_glue *glue = dev_id;
+
+	/* vbus or id changed, let the pins settle and then scan them */
+	queue_delayed_work(system_wq, &glue->detect, SUNXI_MUSB_DEBOUNCE_TIME);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
+{
+	struct musb     *musb = __hci;
+	unsigned long   flags;
+
+	spin_lock_irqsave(&musb->lock, flags);
+
+	musb->int_usb = readb(musb->mregs + SUNXI_MUSB_INTRUSB);
+	if (musb->int_usb)
+		writeb(musb->int_usb, musb->mregs + SUNXI_MUSB_INTRUSB);
+
+	/*
+	 * sunxi musb often signals babble on low / full speed device
+	 * disconnect, without ever raising MUSB_INTR_DISCONNECT, since
+	 * normally babble never happens treat it as disconnect.
+	 */
+	if ((musb->int_usb & MUSB_INTR_BABBLE) && is_host_active(musb)) {
+		musb->int_usb &= ~MUSB_INTR_BABBLE;
+		musb->int_usb |= MUSB_INTR_DISCONNECT;
+	}
+
+	musb->int_tx = readw(musb->mregs + SUNXI_MUSB_INTRTX);
+	if (musb->int_tx)
+		writew(musb->int_tx, musb->mregs + SUNXI_MUSB_INTRTX);
+
+	musb->int_rx = readw(musb->mregs + SUNXI_MUSB_INTRRX);
+	if (musb->int_rx)
+		writew(musb->int_rx, musb->mregs + SUNXI_MUSB_INTRRX);
+
+	musb_interrupt(musb);
+
+	spin_unlock_irqrestore(&musb->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int sunxi_musb_init(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+	int ret;
+
+	sunxi_musb = musb;
+	musb->phy = glue->phy;
+	musb->xceiv = glue->xceiv;
+
+	ret = regmap_update_bits(glue->sc, SUN4I_SC1,
+				 SUN4I_SC1_SRAM_D_MAP_USB0, 1);
+	if (ret)
+		return ret;
+
+	ret = phy_init(glue->phy);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(glue->clk);
+	if (ret) {
+		phy_exit(glue->phy);
+		return ret;
+	}
+
+	musb->isr = sunxi_musb_interrupt;
+
+	sun4i_usb_phy_update_iscr(glue->phy, 0, SUNXI_ISCR_DPDM_PULLUP_EN);
+	sun4i_usb_phy_update_iscr(glue->phy, 0, SUNXI_ISCR_ID_PULLUP_EN);
+
+	switch (musb->port_mode) {
+	case MUSB_PORT_MODE_HOST:
+		sunxi_musb_force_id(musb, 0);
+		sunxi_musb_force_vbus(musb, 1);
+		sunxi_musb_set_vbus(musb, 1);
+		break;
+	case MUSB_PORT_MODE_DUAL_ROLE:
+		sunxi_musb_force_id(musb, 1);
+		sunxi_musb_force_vbus(musb, 0);
+		glue->id_det = 1;
+		glue->vbus_det = 0;
+		break;
+	}
+
+	/* Stop the musb-core from doing runtime pm (not supported on sunxi) */
+	pm_runtime_get(musb->controller);
+
+	return 0;
+}
+
+static int sunxi_musb_exit(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	pm_runtime_put(musb->controller);
+
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_DPDM_PULLUP_EN, 0);
+	sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_ID_PULLUP_EN, 0);
+
+	cancel_delayed_work_sync(&glue->detect);
+	clk_disable_unprepare(glue->clk);
+	if (glue->vbus_on)
+		phy_power_off(glue->phy);
+	phy_exit(glue->phy);
+
+	return 0;
+}
+
+/* Called with musb locked */
+static void sunxi_musb_enable(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+	int ret;
+
+	/* musb_core does not call us in a balanced manner */
+	if (glue->enabled)
+		return;
+
+	glue->enabled = 1;
+
+	writeb(SUNXI_MUSB_VEND0_PIO_MODE, musb->mregs + SUNXI_MUSB_VEND0);
+
+	if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
+		return;
+
+	if (glue->id_det_irq >= 0) {
+		ret = devm_request_irq(glue->dev, glue->id_det_irq,
+				sunxi_musb_id_vbus_det_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"musb-id-det", glue);
+		if (ret) {
+			dev_err(glue->dev,
+				"Error requesting id-det-irq: %d\n", ret);
+			glue->id_det_irq = -1;
+		}
+	}
+
+	if (glue->vbus_det_irq >= 0) {
+		ret = devm_request_irq(glue->dev, glue->vbus_det_irq,
+				sunxi_musb_id_vbus_det_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				"musb-vbus-det", glue);
+		if (ret) {
+			dev_err(glue->dev,
+				"Error requesting vbus-det-irq: %d\n", ret);
+			glue->vbus_det_irq = -1;
+		}
+	}
+
+	/* Scan current status / start scanning */
+	queue_delayed_work(system_wq, &glue->detect, 0);
+}
+
+/* Called with musb locked */
+static void sunxi_musb_disable(struct musb *musb)
+{
+	struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
+
+	/* musb_core does not call us in a balanced manner */
+	if (glue->enabled == 0)
+		return;
+
+	glue->enabled = 0;
+
+	if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
+		return;
+
+	if (glue->id_det_irq >= 0)
+		free_irq(glue->id_det_irq, glue);
+
+	if (glue->vbus_det_irq >= 0)
+		free_irq(glue->vbus_det_irq, glue);
+}
+
+/*
+ * sunxi musb register layout
+ * 0x00 - 0x17	fifo regs, 1 long per fifo
+ * 0x40	- 0x57	generic control regs (power - frame)
+ * 0x80 - 0x8f	ep control regs (addressed through hw_ep->regs, indexed)
+ * 0x90 - 0x97	fifo control regs (indexed)
+ * 0x98 - 0x9f	multipoint / busctl regs (indexed)
+ * 0xc0		configdata reg
+ */
+
+static u32 sunxi_musb_fifo_offset(u8 epnum)
+{
+	return (epnum * 4);
+}
+
+static u32 sunxi_musb_ep_offset(u8 epnum, u16 offset)
+{
+	WARN_ONCE(offset != 0,
+		  "sunxi_musb_ep_offset called with non 0 offset\n");
+
+	return 0x80; /* indexed, so ignore epnum */
+}
+
+static u32 sunxi_musb_busctl_offset(u8 epnum, u16 offset)
+{
+	return SUNXI_MUSB_TXFUNCADDR + offset;
+}
+
+static u8 sunxi_musb_readb(const void __iomem *addr, unsigned offset)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_FADDR:
+			return readb(addr + SUNXI_MUSB_FADDR);
+		case MUSB_POWER:
+			return readb(addr + SUNXI_MUSB_POWER);
+		case MUSB_INTRUSB:
+			return readb(addr + SUNXI_MUSB_INTRUSB);
+		case MUSB_INTRUSBE:
+			return readb(addr + SUNXI_MUSB_INTRUSBE);
+		case MUSB_INDEX:
+			return readb(addr + SUNXI_MUSB_INDEX);
+		case MUSB_TESTMODE:
+			return 0; /* No testmode on sunxi */
+		case MUSB_DEVCTL:
+			return readb(addr + SUNXI_MUSB_DEVCTL);
+		case MUSB_TXFIFOSZ:
+			return readb(addr + SUNXI_MUSB_TXFIFOSZ);
+		case MUSB_RXFIFOSZ:
+			return readb(addr + SUNXI_MUSB_RXFIFOSZ);
+		case MUSB_CONFIGDATA + 0x10: /* See musb_read_configdata() */
+			return readb(addr + SUNXI_MUSB_CONFIGDATA);
+		/* Offset for these is fixed by sunxi_musb_busctl_offset() */
+		case SUNXI_MUSB_TXFUNCADDR:
+		case SUNXI_MUSB_TXHUBADDR:
+		case SUNXI_MUSB_TXHUBPORT:
+		case SUNXI_MUSB_RXFUNCADDR:
+		case SUNXI_MUSB_RXHUBADDR:
+		case SUNXI_MUSB_RXHUBPORT:
+			/* multipoint / busctl reg access */
+			return readb(addr + offset);
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown readb offset %u\n", offset);
+			return 0;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		/* sunxi has a 2 byte hole before the txtype register */
+		if (offset >= MUSB_TXTYPE)
+			offset += 2;
+		return readb(addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown readb at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+	return 0;
+}
+
+static void sunxi_musb_writeb(void __iomem *addr, unsigned offset, u8 data)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_FADDR:
+			return writeb(data, addr + SUNXI_MUSB_FADDR);
+		case MUSB_POWER:
+			return writeb(data, addr + SUNXI_MUSB_POWER);
+		case MUSB_INTRUSB:
+			return writeb(data, addr + SUNXI_MUSB_INTRUSB);
+		case MUSB_INTRUSBE:
+			return writeb(data, addr + SUNXI_MUSB_INTRUSBE);
+		case MUSB_INDEX:
+			return writeb(data, addr + SUNXI_MUSB_INDEX);
+		case MUSB_TESTMODE:
+			if (data)
+				dev_warn(sunxi_musb->controller->parent,
+					"sunxi-musb does not have testmode\n");
+			return;
+		case MUSB_DEVCTL:
+			return writeb(data, addr + SUNXI_MUSB_DEVCTL);
+		case MUSB_TXFIFOSZ:
+			return writeb(data, addr + SUNXI_MUSB_TXFIFOSZ);
+		case MUSB_RXFIFOSZ:
+			return writeb(data, addr + SUNXI_MUSB_RXFIFOSZ);
+		/* Offset for these is fixed by sunxi_musb_busctl_offset() */
+		case SUNXI_MUSB_TXFUNCADDR:
+		case SUNXI_MUSB_TXHUBADDR:
+		case SUNXI_MUSB_TXHUBPORT:
+		case SUNXI_MUSB_RXFUNCADDR:
+		case SUNXI_MUSB_RXHUBADDR:
+		case SUNXI_MUSB_RXHUBPORT:
+			/* multipoint / busctl reg access */
+			return writeb(data, addr + offset);
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown writeb offset %u\n", offset);
+			return;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		if (offset >= MUSB_TXTYPE)
+			offset += 2;
+		return writeb(data, addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown writeb at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+}
+
+static u16 sunxi_musb_readw(const void __iomem *addr, unsigned offset)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_INTRTX:
+			return readw(addr + SUNXI_MUSB_INTRTX);
+		case MUSB_INTRRX:
+			return readw(addr + SUNXI_MUSB_INTRRX);
+		case MUSB_INTRTXE:
+			return readw(addr + SUNXI_MUSB_INTRTXE);
+		case MUSB_INTRRXE:
+			return readw(addr + SUNXI_MUSB_INTRRXE);
+		case MUSB_FRAME:
+			return readw(addr + SUNXI_MUSB_FRAME);
+		case MUSB_TXFIFOADD:
+			return readw(addr + SUNXI_MUSB_TXFIFOADD);
+		case MUSB_RXFIFOADD:
+			return readw(addr + SUNXI_MUSB_RXFIFOADD);
+		case MUSB_HWVERS:
+			return 0; /* sunxi musb version is not known */
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown readw offset %u\n", offset);
+			return 0;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		return readw(addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown readw at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+	return 0;
+}
+
+static void sunxi_musb_writew(void __iomem *addr, unsigned offset, u16 data)
+{
+	if (addr == sunxi_musb->mregs) {
+		/* generic control or fifo control reg access */
+		switch (offset) {
+		case MUSB_INTRTX:
+			return writew(data, addr + SUNXI_MUSB_INTRTX);
+		case MUSB_INTRRX:
+			return writew(data, addr + SUNXI_MUSB_INTRRX);
+		case MUSB_INTRTXE:
+			return writew(data, addr + SUNXI_MUSB_INTRTXE);
+		case MUSB_INTRRXE:
+			return writew(data, addr + SUNXI_MUSB_INTRRXE);
+		case MUSB_FRAME:
+			return writew(data, addr + SUNXI_MUSB_FRAME);
+		case MUSB_TXFIFOADD:
+			return writew(data, addr + SUNXI_MUSB_TXFIFOADD);
+		case MUSB_RXFIFOADD:
+			return writew(data, addr + SUNXI_MUSB_RXFIFOADD);
+		default:
+			dev_err(sunxi_musb->controller->parent,
+				"Error unknown writew offset %u\n", offset);
+			return;
+		}
+	} else if (addr == (sunxi_musb->mregs + 0x80)) {
+		/* ep control reg access */
+		return writew(data, addr + offset);
+	}
+
+	dev_err(sunxi_musb->controller->parent,
+		"Error unknown writew at 0x%x bytes offset\n",
+		(int)(addr - sunxi_musb->mregs));
+}
+
+static const struct musb_platform_ops sunxi_musb_ops = {
+	.quirks		= MUSB_INDEXED_EP | MUSB_SUN4I,
+	.init		= sunxi_musb_init,
+	.exit		= sunxi_musb_exit,
+	.enable		= sunxi_musb_enable,
+	.disable	= sunxi_musb_disable,
+	.fifo_offset	= sunxi_musb_fifo_offset,
+	.ep_offset	= sunxi_musb_ep_offset,
+	.busctl_offset	= sunxi_musb_busctl_offset,
+	.readb		= sunxi_musb_readb,
+	.writeb		= sunxi_musb_writeb,
+	.readw		= sunxi_musb_readw,
+	.writew		= sunxi_musb_writew,
+	.set_vbus	= sunxi_musb_set_vbus,
+};
+
+/* Allwinner OTG supports up to 5 endpoints */
+#define SUNXI_MUSB_MAX_EP_NUM	6
+#define SUNXI_MUSB_RAM_BITS	11
+
+static struct musb_fifo_cfg sunxi_musb_mode_cfg[] = {
+	MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512),
+	MUSB_EP_FIFO_SINGLE(5, FIFO_TX, 512),
+	MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512),
+};
+
+static struct musb_hdrc_config sunxi_musb_hdrc_config = {
+	.fifo_cfg       = sunxi_musb_mode_cfg,
+	.fifo_cfg_size  = ARRAY_SIZE(sunxi_musb_mode_cfg),
+	.multipoint	= true,
+	.dyn_fifo	= true,
+	.soft_con       = true,
+	.num_eps	= SUNXI_MUSB_MAX_EP_NUM,
+	.ram_bits	= SUNXI_MUSB_RAM_BITS,
+	.dma		= 0,
+};
+
+static int sunxi_musb_probe(struct platform_device *pdev)
+{
+	struct musb_hdrc_platform_data	pdata;
+	struct platform_device_info	pinfo;
+	struct sunxi_glue		*glue;
+	struct device_node		*np = pdev->dev.of_node;
+	int ret;
+
+	if (!np) {
+		dev_err(&pdev->dev, "Error no device tree node found\n");
+		return -EINVAL;
+	}
+
+	memset(&pdata, 0, sizeof(pdata));
+	switch (of_usb_get_dr_mode(np)) {
+	case USB_DR_MODE_HOST:
+		pdata.mode = MUSB_PORT_MODE_HOST;
+		break;
+	case USB_DR_MODE_PERIPHERAL:
+		dev_err(&pdev->dev,
+			"Error peripheral only mode is not supported\n");
+		return -EINVAL;
+	case USB_DR_MODE_OTG:
+		pdata.mode = MUSB_PORT_MODE_DUAL_ROLE;
+		break;
+	default:
+		dev_err(&pdev->dev, "No 'dr_mode' property found\n");
+		return -EINVAL;
+	}
+	pdata.platform_ops	= &sunxi_musb_ops;
+	pdata.config		= &sunxi_musb_hdrc_config;
+
+	glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
+	if (!glue)
+		return -ENOMEM;
+
+	glue->dev = &pdev->dev;
+	INIT_DELAYED_WORK(&glue->detect, sunxi_musb_id_vbus_det_scan);
+
+	glue->sc = syscon_regmap_lookup_by_phandle(np, "syscons");
+	if (IS_ERR(glue->sc)) {
+		dev_err(&pdev->dev, "Error getting syscon %ld\n",
+			PTR_ERR(glue->sc));
+		return PTR_ERR(glue->sc);
+	}
+
+	glue->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(glue->clk)) {
+		dev_err(&pdev->dev, "Error getting clock: %ld\n",
+			PTR_ERR(glue->clk));
+		return PTR_ERR(glue->clk);
+	}
+
+	if (pdata.mode == MUSB_PORT_MODE_DUAL_ROLE) {
+		glue->id_det_gpio =
+			devm_gpiod_get(&pdev->dev, "id_det", GPIOD_IN);
+		if (IS_ERR(glue->id_det_gpio)) {
+			dev_err(&pdev->dev, "Error getting id_det gpio\n");
+			return PTR_ERR(glue->id_det_gpio);
+		}
+
+		glue->vbus_det_gpio =
+			devm_gpiod_get(&pdev->dev, "vbus_det", GPIOD_IN);
+		if (IS_ERR(glue->vbus_det_gpio)) {
+			dev_err(&pdev->dev, "Error getting vbus_det gpio\n");
+			return PTR_ERR(glue->vbus_det_gpio);
+		}
+
+		glue->id_det_irq = gpiod_to_irq(glue->id_det_gpio);
+		glue->vbus_det_irq = gpiod_to_irq(glue->vbus_det_gpio);
+	}
+
+	glue->phy = devm_phy_get(&pdev->dev, "usb");
+	if (IS_ERR(glue->phy)) {
+		if (PTR_ERR(glue->phy) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_err(&pdev->dev, "Error getting phy %ld\n",
+			PTR_ERR(glue->phy));
+		return PTR_ERR(glue->phy);
+	}
+
+	glue->usb_phy = usb_phy_generic_register();
+	if (IS_ERR(glue->usb_phy)) {
+		dev_err(&pdev->dev, "Error registering usb-phy %ld\n",
+			PTR_ERR(glue->usb_phy));
+		return PTR_ERR(glue->usb_phy);
+	}
+
+	glue->xceiv = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+	if (IS_ERR(glue->xceiv)) {
+		ret = PTR_ERR(glue->xceiv);
+		dev_err(&pdev->dev, "Error getting usb-phy %d\n", ret);
+		goto err_unregister_usb_phy;
+	}
+
+	platform_set_drvdata(pdev, glue);
+
+	memset(&pinfo, 0, sizeof(pinfo));
+	pinfo.name	 = "musb-hdrc";
+	pinfo.id	= PLATFORM_DEVID_AUTO;
+	pinfo.parent	= &pdev->dev;
+	pinfo.res	= pdev->resource;
+	pinfo.num_res	= pdev->num_resources;
+	pinfo.data	= &pdata;
+	pinfo.size_data = sizeof(pdata);
+
+	glue->musb = platform_device_register_full(&pinfo);
+	if (IS_ERR(glue->musb)) {
+		ret = PTR_ERR(glue->musb);
+		dev_err(&pdev->dev, "Error registering musb dev: %d\n", ret);
+		goto err_unregister_usb_phy;
+	}
+
+	return 0;
+
+err_unregister_usb_phy:
+	usb_phy_generic_unregister(glue->usb_phy);
+	return ret;
+}
+
+static int sunxi_musb_remove(struct platform_device *pdev)
+{
+	struct sunxi_glue *glue = platform_get_drvdata(pdev);
+	struct platform_device *usb_phy = glue->usb_phy;
+
+	platform_device_unregister(glue->musb); /* Frees glue ! */
+	usb_phy_generic_unregister(usb_phy);
+
+	return 0;
+}
+
+static const struct of_device_id sunxi_musb_match[] = {
+	{ .compatible = "allwinner,sun4i-a10-musb", },
+	{}
+};
+
+static struct platform_driver sunxi_musb_driver = {
+	.probe = sunxi_musb_probe,
+	.remove = sunxi_musb_remove,
+	.driver = {
+		.name = "musb-sunxi",
+		.of_match_table = sunxi_musb_match,
+	},
+};
+module_platform_driver(sunxi_musb_driver);
+
+MODULE_DESCRIPTION("Allwinner sunxi MUSB Glue Layer");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 08/15] ARM: dts: sunxi: Add syscon node for controlling SRAM mapping
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Jens Kuske, Hans de Goede

From: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>

Allwinner SoCs have a system controller module that controls whether
SRAM blocks are mapped to the CPU memory or specific peripherals.

Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
[jenskuske-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org: duplicate syscon node to sun4i and sun5i]
Signed-off-by: Jens Kuske <jenskuske-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun4i-a10.dtsi | 5 +++++
 arch/arm/boot/dts/sun5i.dtsi     | 5 +++++
 arch/arm/boot/dts/sun7i-a20.dtsi | 5 +++++
 3 files changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index c66352b..2f792b6 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -457,6 +457,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon@01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		dma: dma-controller@01c02000 {
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 244d896..97b4eb1 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -298,6 +298,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon@01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		dma: dma-controller@01c02000 {
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 8df77f5..fb56a1d 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -528,6 +528,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon@01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		nmi_intc: interrupt-controller@01c00030 {
 			compatible = "allwinner,sun7i-a20-sc-nmi";
 			interrupt-controller;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 08/15] ARM: dts: sunxi: Add syscon node for controlling SRAM mapping
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Chen-Yu Tsai <wens@csie.org>

Allwinner SoCs have a system controller module that controls whether
SRAM blocks are mapped to the CPU memory or specific peripherals.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
[jenskuske at gmail.com: duplicate syscon node to sun4i and sun5i]
Signed-off-by: Jens Kuske <jenskuske@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi | 5 +++++
 arch/arm/boot/dts/sun5i.dtsi     | 5 +++++
 arch/arm/boot/dts/sun7i-a20.dtsi | 5 +++++
 3 files changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index c66352b..2f792b6 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -457,6 +457,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon at 01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		dma: dma-controller at 01c02000 {
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 244d896..97b4eb1 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -298,6 +298,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon at 01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		dma: dma-controller at 01c02000 {
 			compatible = "allwinner,sun4i-a10-dma";
 			reg = <0x01c02000 0x1000>;
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 8df77f5..fb56a1d 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -528,6 +528,11 @@
 		#size-cells = <1>;
 		ranges;
 
+		syscon: syscon at 01c00000 {
+			compatible = "allwinner,sun4i-a10-syscon", "syscon";
+			reg = <0x01c00000 0x8>;
+		};
+
 		nmi_intc: interrupt-controller at 01c00030 {
 			compatible = "allwinner,sun7i-a20-sc-nmi";
 			interrupt-controller;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

Add a node for the otg/drc usb controller to sun4i-a10.dtsi.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
 drivers/usb/musb/Kconfig         |  1 +
 2 files changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 2f792b6..e550415 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -574,6 +574,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb@01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy@01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun4i-a10-usb-phy";
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 8180a3a..fab8e9a 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -65,6 +65,7 @@ comment "Platform Glue Layer"
 config USB_MUSB_SUNXI
 	tristate "Allwinner (sunxi)"
 	depends on ARCH_SUNXI
+	depends on NOP_USB_XCEIV
 	select GENERIC_PHY
 
 config USB_MUSB_DAVINCI
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Add a node for the otg/drc usb controller to sun4i-a10.dtsi.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
 drivers/usb/musb/Kconfig         |  1 +
 2 files changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 2f792b6..e550415 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -574,6 +574,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb at 01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy at 01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun4i-a10-usb-phy";
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 8180a3a..fab8e9a 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -65,6 +65,7 @@ comment "Platform Glue Layer"
 config USB_MUSB_SUNXI
 	tristate "Allwinner (sunxi)"
 	depends on ARCH_SUNXI
+	depends on NOP_USB_XCEIV
 	select GENERIC_PHY
 
 config USB_MUSB_DAVINCI
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 10/15] ARM: dts: sun5i: Add USB Dual Role Controller
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

Add a node for the otg/drc usb controller to sun5i-a1*.dtsi.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun5i.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 97b4eb1..cf730d4 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -384,6 +384,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb@01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy@01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun5i-a13-usb-phy";
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 10/15] ARM: dts: sun5i: Add USB Dual Role Controller
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Add a node for the otg/drc usb controller to sun5i-a1*.dtsi.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun5i.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 97b4eb1..cf730d4 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -384,6 +384,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb at 01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <38>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy at 01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun5i-a13-usb-phy";
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 11/15] ARM: dts: sun7i: Add USB Dual Role Controller
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

From: Roman Byshko <rbyshko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Add a node for the otg/drc usb controller to sun7i-a20.dtsi

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun7i-a20.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index fb56a1d..1d0b9ac 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -653,6 +653,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb@01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <0 38 4>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy@01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun7i-a20-usb-phy";
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 11/15] ARM: dts: sun7i: Add USB Dual Role Controller
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Roman Byshko <rbyshko@gmail.com>

Add a node for the otg/drc usb controller to sun7i-a20.dtsi

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index fb56a1d..1d0b9ac 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -653,6 +653,18 @@
 			status = "disabled";
 		};
 
+		usb_otg: usb at 01c13000 {
+			compatible = "allwinner,sun4i-a10-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ahb_gates 0>;
+			interrupts = <0 38 4>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			syscons = <&syscon>;
+			status = "disabled";
+		};
+
 		usbphy: phy at 01c13400 {
 			#phy-cells = <1>;
 			compatible = "allwinner,sun7i-a20-usb-phy";
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
index 97fca89..034396c 100644
--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -111,6 +111,26 @@
 	status = "okay";
 };
 
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };
@@ -121,7 +141,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
index 97fca89..034396c 100644
--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -111,6 +111,26 @@
 	status = "okay";
 };
 
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };
@@ -121,7 +141,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 13/15] ARM: dts: sun5i: Enable USB DRC on UTOO P66
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

Enable the OTG controller on the UTOO P66 tablet.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun5i-a13-utoo-p66.dts | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
index d1d4d30..8b44874 100644
--- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
+++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
@@ -160,6 +160,20 @@
 		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
 	};
 
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
+		allwinner,pins = "PG2";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
 	i2c_lcd_pins: i2c_lcd_pin@0 {
 		allwinner,pins = "PG10", "PG12";
 		allwinner,function = "gpio_out";
@@ -218,6 +232,15 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+	vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
 	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_ldo3>;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 13/15] ARM: dts: sun5i: Enable USB DRC on UTOO P66
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the OTG controller on the UTOO P66 tablet.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun5i-a13-utoo-p66.dts | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
index d1d4d30..8b44874 100644
--- a/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
+++ b/arch/arm/boot/dts/sun5i-a13-utoo-p66.dts
@@ -160,6 +160,20 @@
 		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
 	};
 
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PG2";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
 	i2c_lcd_pins: i2c_lcd_pin at 0 {
 		allwinner,pins = "PG10", "PG12";
 		allwinner,function = "gpio_out";
@@ -218,6 +232,15 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+	vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
 	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_ldo3>;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 14/15] ARM: dts: sun7i: Enable USB DRC on Cubietruck
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

From: Roman Byshko <rbyshko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Enable the otg/drc usb controller on the cubietruck.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8111b0c..ac8ff33 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -227,6 +227,20 @@
 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
+		allwinner,pins = "PH19";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+		allwinner,pins = "PH22";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
 };
 
 &pwm {
@@ -288,6 +302,16 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		    &usb0_vbus_detect_pin>;
+	dr_mode = "otg";
+	id_det-gpios = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */
+	vbus_det-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
+	status = "okay";
+};
+
 &usbphy {
 	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 14/15] ARM: dts: sun7i: Enable USB DRC on Cubietruck
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

From: Roman Byshko <rbyshko@gmail.com>

Enable the otg/drc usb controller on the cubietruck.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
index 8111b0c..ac8ff33 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
@@ -227,6 +227,20 @@
 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH19";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH22";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
 };
 
 &pwm {
@@ -288,6 +302,16 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		    &usb0_vbus_detect_pin>;
+	dr_mode = "otg";
+	id_det-gpios = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */
+	vbus_det-gpios = <&pio 7 22 GPIO_ACTIVE_HIGH>; /* PH22 */
+	status = "okay";
+};
+
 &usbphy {
 	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 15/15] ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 20:40     ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard
  Cc: Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Hans de Goede

Enable the otg/drc usb controller on the A20-OLinuxIno-Lime.

Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts | 29 ++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
index 68efd2f..b3fda82 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
@@ -146,6 +146,20 @@
 		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
 };
 
 &reg_ahci_5v {
@@ -154,6 +168,10 @@
 	status = "okay";
 };
 
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -168,7 +186,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* [PATCH 15/15] ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime
@ 2015-03-09 20:40     ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-09 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the otg/drc usb controller on the A20-OLinuxIno-Lime.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts | 29 ++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
index 68efd2f..b3fda82 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
@@ -146,6 +146,20 @@
 		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
 };
 
 &reg_ahci_5v {
@@ -154,6 +168,10 @@
 	status = "okay";
 };
 
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -168,7 +186,18 @@
 	status = "okay";
 };
 
+&usb_otg {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin
+		     &usb0_vbus_detect_pin>;
+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.3.1

^ permalink raw reply related	[flat|nested] 88+ messages in thread

* Re: [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-09 21:44     ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-09 21:44 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Monday 09 March 2015 21:40:13 Hans de Goede wrote:
> Hi All,
> 
> This patch set has been a while in the making, so I'm very happy to present
> the end result here, and I hope everyone likes it.

Awesome work!

> Before talking about merging this there are 2 things which I would like to
> point out:
> 
> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
> mapped to the musb controller by poking some bits in the SRAM controller,
> just like the EMAC patches which were send a while back I've chosen to use
> syscon for this, actually 2 of the patches in this set come directly from the
> SRAM mapping patchset for the EMAC.
> 
> I know that Maxime is not 100% in favor of using syscon:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
> 
> But I disagree with his arguments for writing a special driver for the SRAM
> controller:
> 1) syscon was specifically designed for global system control registers like
> this and is fine to use as long as there are no conflicts where 1 bit is of
> interest to multiple drivers, and there is no such conflict here
> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
> to have a specific driver for this, without really proving a hard need for
> such a driver. But writing such a driver is going to be a lot of work, and
> we've a ton of other work to do, and as said there is no real need for a
> separate driver, syscon works fine for this.
> 3) I actually believe that having a specific driver for this is a bad idea,
> because that means inventing a whole new cross driver API for this, and
> getting those right is, hard, a lot of work, and even then one is still likely
> to get it wrong. We can avoid all this by going with the proven syscon solution.
> 
> Maxime, can we please have your ack for moving forward with this using syscon?
> (see above for my arguments why)

I'd like to understand here why we can't use the existing SRAM DT binding
instead of the syscon binding.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-09 21:44     ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-09 21:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 09 March 2015 21:40:13 Hans de Goede wrote:
> Hi All,
> 
> This patch set has been a while in the making, so I'm very happy to present
> the end result here, and I hope everyone likes it.

Awesome work!

> Before talking about merging this there are 2 things which I would like to
> point out:
> 
> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
> mapped to the musb controller by poking some bits in the SRAM controller,
> just like the EMAC patches which were send a while back I've chosen to use
> syscon for this, actually 2 of the patches in this set come directly from the
> SRAM mapping patchset for the EMAC.
> 
> I know that Maxime is not 100% in favor of using syscon:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
> 
> But I disagree with his arguments for writing a special driver for the SRAM
> controller:
> 1) syscon was specifically designed for global system control registers like
> this and is fine to use as long as there are no conflicts where 1 bit is of
> interest to multiple drivers, and there is no such conflict here
> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
> to have a specific driver for this, without really proving a hard need for
> such a driver. But writing such a driver is going to be a lot of work, and
> we've a ton of other work to do, and as said there is no real need for a
> separate driver, syscon works fine for this.
> 3) I actually believe that having a specific driver for this is a bad idea,
> because that means inventing a whole new cross driver API for this, and
> getting those right is, hard, a lot of work, and even then one is still likely
> to get it wrong. We can avoid all this by going with the proven syscon solution.
> 
> Maxime, can we please have your ack for moving forward with this using syscon?
> (see above for my arguments why)

I'd like to understand here why we can't use the existing SRAM DT binding
instead of the syscon binding.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-09 20:40     ` Hans de Goede
@ 2015-03-09 21:47         ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-09 21:47 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
> +{
> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> +       u32 iscr;
> +
> +       iscr = readl(data->base + REG_ISCR);
> +       iscr &= ~clr;
> +       iscr |= set;
> +       writel(iscr, data->base + REG_ISCR);
> +}
> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
> +
> 

I would generally consider this a bad design. What is the purpose of
calling sun4i_usb_phy_update_iscr() and why can't there be a high-level
PHY API for this?

The only other phy driver with exports like this is the OMAP driver,
and that has caused problems in the past.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-09 21:47         ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-09 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
> +{
> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> +       u32 iscr;
> +
> +       iscr = readl(data->base + REG_ISCR);
> +       iscr &= ~clr;
> +       iscr |= set;
> +       writel(iscr, data->base + REG_ISCR);
> +}
> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
> +
> 

I would generally consider this a bad design. What is the purpose of
calling sun4i_usb_phy_update_iscr() and why can't there be a high-level
PHY API for this?

The only other phy driver with exports like this is the OMAP driver,
and that has caused problems in the past.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
  2015-03-09 20:40     ` Hans de Goede
@ 2015-03-09 21:50         ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-09 21:50 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
> The generic fifo functions already use non wrapped accesses in various
> cases through the iowrite#_rep functions, and all platforms which override
> the default musb_read[b|w] / _write[b|w] functions also provide their own
> fifo access functions, so we can safely drop the unnecessary indirection
> from the fifo access functions.
> 
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> 

The patch looks reasonably, but the description seem misleading.
I believe the real reason why it's ok to use __raw_writew for the
FIFO is that a FIFO by definition is using CPU endian access for
copying byte streams from memory, which is unlike any other MMIO
register that requires fixed-endian accessors.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
@ 2015-03-09 21:50         ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-09 21:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
> The generic fifo functions already use non wrapped accesses in various
> cases through the iowrite#_rep functions, and all platforms which override
> the default musb_read[b|w] / _write[b|w] functions also provide their own
> fifo access functions, so we can safely drop the unnecessary indirection
> from the fifo access functions.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> 

The patch looks reasonably, but the description seem misleading.
I believe the real reason why it's ok to use __raw_writew for the
FIFO is that a FIFO by definition is using CPU endian access for
copying byte streams from memory, which is unlike any other MMIO
register that requires fixed-endian accessors.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller
  2015-03-09 20:40     ` Hans de Goede
@ 2015-03-09 23:31         ` Julian Calaby
  -1 siblings, 0 replies; 88+ messages in thread
From: Julian Calaby @ 2015-03-09 23:31 UTC (permalink / raw)
  To: linux-sunxi
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	Mailing List, Arm, devicetree, Hans de Goede

Hi Hans,

On Tue, Mar 10, 2015 at 7:40 AM, Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> Add a node for the otg/drc usb controller to sun4i-a10.dtsi.
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
>  drivers/usb/musb/Kconfig         |  1 +
>  2 files changed, 13 insertions(+)
>
> diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> index 8180a3a..fab8e9a 100644
> --- a/drivers/usb/musb/Kconfig
> +++ b/drivers/usb/musb/Kconfig
> @@ -65,6 +65,7 @@ comment "Platform Glue Layer"
>  config USB_MUSB_SUNXI
>         tristate "Allwinner (sunxi)"
>         depends on ARCH_SUNXI
> +       depends on NOP_USB_XCEIV

Shouldn't this be in a different patch?

Thanks,

-- 
Julian Calaby

Email: julian.calaby-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Profile: http://www.google.com/profiles/julian.calaby/

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [linux-sunxi] [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller
@ 2015-03-09 23:31         ` Julian Calaby
  0 siblings, 0 replies; 88+ messages in thread
From: Julian Calaby @ 2015-03-09 23:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hans,

On Tue, Mar 10, 2015 at 7:40 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Add a node for the otg/drc usb controller to sun4i-a10.dtsi.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
>  drivers/usb/musb/Kconfig         |  1 +
>  2 files changed, 13 insertions(+)
>
> diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
> index 8180a3a..fab8e9a 100644
> --- a/drivers/usb/musb/Kconfig
> +++ b/drivers/usb/musb/Kconfig
> @@ -65,6 +65,7 @@ comment "Platform Glue Layer"
>  config USB_MUSB_SUNXI
>         tristate "Allwinner (sunxi)"
>         depends on ARCH_SUNXI
> +       depends on NOP_USB_XCEIV

Shouldn't this be in a different patch?

Thanks,

-- 
Julian Calaby

Email: julian.calaby at gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-09 21:44     ` Arnd Bergmann
@ 2015-03-10  1:46       ` Chen-Yu Tsai
  -1 siblings, 0 replies; 88+ messages in thread
From: Chen-Yu Tsai @ 2015-03-10  1:46 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Hans de Goede, Felipe Balbi, Kishon Vijay Abraham I,
	Maxime Ripard, Chen-Yu Tsai, Roman Byshko, linux-usb,
	linux-arm-kernel, devicetree, linux-sunxi

Hi Arnd,

On Tue, Mar 10, 2015 at 5:44 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Monday 09 March 2015 21:40:13 Hans de Goede wrote:
>> Hi All,
>>
>> This patch set has been a while in the making, so I'm very happy to present
>> the end result here, and I hope everyone likes it.
>
> Awesome work!
>
>> Before talking about merging this there are 2 things which I would like to
>> point out:
>>
>> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
>> mapped to the musb controller by poking some bits in the SRAM controller,
>> just like the EMAC patches which were send a while back I've chosen to use
>> syscon for this, actually 2 of the patches in this set come directly from the
>> SRAM mapping patchset for the EMAC.
>>
>> I know that Maxime is not 100% in favor of using syscon:
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
>>
>> But I disagree with his arguments for writing a special driver for the SRAM
>> controller:
>> 1) syscon was specifically designed for global system control registers like
>> this and is fine to use as long as there are no conflicts where 1 bit is of
>> interest to multiple drivers, and there is no such conflict here
>> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
>> to have a specific driver for this, without really proving a hard need for
>> such a driver. But writing such a driver is going to be a lot of work, and
>> we've a ton of other work to do, and as said there is no real need for a
>> separate driver, syscon works fine for this.
>> 3) I actually believe that having a specific driver for this is a bad idea,
>> because that means inventing a whole new cross driver API for this, and
>> getting those right is, hard, a lot of work, and even then one is still likely
>> to get it wrong. We can avoid all this by going with the proven syscon solution.
>>
>> Maxime, can we please have your ack for moving forward with this using syscon?
>> (see above for my arguments why)
>
> I'd like to understand here why we can't use the existing SRAM DT binding
> instead of the syscon binding.

I believe you are talking about "mmio-sram"?

The syscon here represents a switch, to toggle whether a block of SRAM is
mapped into the CPU memory space, or to a specific devices private address
space. It is not the actual SRAM.

The SRAM DT binding is orthogonal to this, if not irrelevant when the block
is mapped privately, as it is no longer visible from the DT's PoV.

Coincidentally, on the A23 this is no longer needed. The SRAM for the FIFO
is wholly owned by MUSB and not available to the CPU.


ChenYu

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-10  1:46       ` Chen-Yu Tsai
  0 siblings, 0 replies; 88+ messages in thread
From: Chen-Yu Tsai @ 2015-03-10  1:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Tue, Mar 10, 2015 at 5:44 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday 09 March 2015 21:40:13 Hans de Goede wrote:
>> Hi All,
>>
>> This patch set has been a while in the making, so I'm very happy to present
>> the end result here, and I hope everyone likes it.
>
> Awesome work!
>
>> Before talking about merging this there are 2 things which I would like to
>> point out:
>>
>> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
>> mapped to the musb controller by poking some bits in the SRAM controller,
>> just like the EMAC patches which were send a while back I've chosen to use
>> syscon for this, actually 2 of the patches in this set come directly from the
>> SRAM mapping patchset for the EMAC.
>>
>> I know that Maxime is not 100% in favor of using syscon:
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
>>
>> But I disagree with his arguments for writing a special driver for the SRAM
>> controller:
>> 1) syscon was specifically designed for global system control registers like
>> this and is fine to use as long as there are no conflicts where 1 bit is of
>> interest to multiple drivers, and there is no such conflict here
>> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
>> to have a specific driver for this, without really proving a hard need for
>> such a driver. But writing such a driver is going to be a lot of work, and
>> we've a ton of other work to do, and as said there is no real need for a
>> separate driver, syscon works fine for this.
>> 3) I actually believe that having a specific driver for this is a bad idea,
>> because that means inventing a whole new cross driver API for this, and
>> getting those right is, hard, a lot of work, and even then one is still likely
>> to get it wrong. We can avoid all this by going with the proven syscon solution.
>>
>> Maxime, can we please have your ack for moving forward with this using syscon?
>> (see above for my arguments why)
>
> I'd like to understand here why we can't use the existing SRAM DT binding
> instead of the syscon binding.

I believe you are talking about "mmio-sram"?

The syscon here represents a switch, to toggle whether a block of SRAM is
mapped into the CPU memory space, or to a specific devices private address
space. It is not the actual SRAM.

The SRAM DT binding is orthogonal to this, if not irrelevant when the block
is mapped privately, as it is no longer visible from the DT's PoV.

Coincidentally, on the A23 this is no longer needed. The SRAM for the FIFO
is wholly owned by MUSB and not available to the CPU.


ChenYu

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-10  1:46       ` Chen-Yu Tsai
@ 2015-03-10  7:38           ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  7:38 UTC (permalink / raw)
  To: Chen-Yu Tsai, Arnd Bergmann
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Roman Byshko, linux-usb, linux-arm-kernel, devicetree,
	linux-sunxi

Hi,

On 10-03-15 02:46, Chen-Yu Tsai wrote:
> Hi Arnd,
>
> On Tue, Mar 10, 2015 at 5:44 AM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> On Monday 09 March 2015 21:40:13 Hans de Goede wrote:
>>> Hi All,
>>>
>>> This patch set has been a while in the making, so I'm very happy to present
>>> the end result here, and I hope everyone likes it.
>>
>> Awesome work!
>>
>>> Before talking about merging this there are 2 things which I would like to
>>> point out:
>>>
>>> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
>>> mapped to the musb controller by poking some bits in the SRAM controller,
>>> just like the EMAC patches which were send a while back I've chosen to use
>>> syscon for this, actually 2 of the patches in this set come directly from the
>>> SRAM mapping patchset for the EMAC.
>>>
>>> I know that Maxime is not 100% in favor of using syscon:
>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
>>>
>>> But I disagree with his arguments for writing a special driver for the SRAM
>>> controller:
>>> 1) syscon was specifically designed for global system control registers like
>>> this and is fine to use as long as there are no conflicts where 1 bit is of
>>> interest to multiple drivers, and there is no such conflict here
>>> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
>>> to have a specific driver for this, without really proving a hard need for
>>> such a driver. But writing such a driver is going to be a lot of work, and
>>> we've a ton of other work to do, and as said there is no real need for a
>>> separate driver, syscon works fine for this.
>>> 3) I actually believe that having a specific driver for this is a bad idea,
>>> because that means inventing a whole new cross driver API for this, and
>>> getting those right is, hard, a lot of work, and even then one is still likely
>>> to get it wrong. We can avoid all this by going with the proven syscon solution.
>>>
>>> Maxime, can we please have your ack for moving forward with this using syscon?
>>> (see above for my arguments why)
>>
>> I'd like to understand here why we can't use the existing SRAM DT binding
>> instead of the syscon binding.
>
> I believe you are talking about "mmio-sram"?
>
> The syscon here represents a switch, to toggle whether a block of SRAM is
> mapped into the CPU memory space, or to a specific devices private address
> space. It is not the actual SRAM.
>
> The SRAM DT binding is orthogonal to this, if not irrelevant when the block
> is mapped privately, as it is no longer visible from the DT's PoV.
>
> Coincidentally, on the A23 this is no longer needed. The SRAM for the FIFO
> is wholly owned by MUSB and not available to the CPU.

What ChenYu said :)

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-10  7:38           ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  7:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 10-03-15 02:46, Chen-Yu Tsai wrote:
> Hi Arnd,
>
> On Tue, Mar 10, 2015 at 5:44 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Monday 09 March 2015 21:40:13 Hans de Goede wrote:
>>> Hi All,
>>>
>>> This patch set has been a while in the making, so I'm very happy to present
>>> the end result here, and I hope everyone likes it.
>>
>> Awesome work!
>>
>>> Before talking about merging this there are 2 things which I would like to
>>> point out:
>>>
>>> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
>>> mapped to the musb controller by poking some bits in the SRAM controller,
>>> just like the EMAC patches which were send a while back I've chosen to use
>>> syscon for this, actually 2 of the patches in this set come directly from the
>>> SRAM mapping patchset for the EMAC.
>>>
>>> I know that Maxime is not 100% in favor of using syscon:
>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
>>>
>>> But I disagree with his arguments for writing a special driver for the SRAM
>>> controller:
>>> 1) syscon was specifically designed for global system control registers like
>>> this and is fine to use as long as there are no conflicts where 1 bit is of
>>> interest to multiple drivers, and there is no such conflict here
>>> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
>>> to have a specific driver for this, without really proving a hard need for
>>> such a driver. But writing such a driver is going to be a lot of work, and
>>> we've a ton of other work to do, and as said there is no real need for a
>>> separate driver, syscon works fine for this.
>>> 3) I actually believe that having a specific driver for this is a bad idea,
>>> because that means inventing a whole new cross driver API for this, and
>>> getting those right is, hard, a lot of work, and even then one is still likely
>>> to get it wrong. We can avoid all this by going with the proven syscon solution.
>>>
>>> Maxime, can we please have your ack for moving forward with this using syscon?
>>> (see above for my arguments why)
>>
>> I'd like to understand here why we can't use the existing SRAM DT binding
>> instead of the syscon binding.
>
> I believe you are talking about "mmio-sram"?
>
> The syscon here represents a switch, to toggle whether a block of SRAM is
> mapped into the CPU memory space, or to a specific devices private address
> space. It is not the actual SRAM.
>
> The SRAM DT binding is orthogonal to this, if not irrelevant when the block
> is mapped privately, as it is no longer visible from the DT's PoV.
>
> Coincidentally, on the A23 this is no longer needed. The SRAM for the FIFO
> is wholly owned by MUSB and not available to the CPU.

What ChenYu said :)

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
  2015-03-09 21:50         ` Arnd Bergmann
@ 2015-03-10  7:43           ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  7:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 09-03-15 22:50, Arnd Bergmann wrote:
> On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
>> The generic fifo functions already use non wrapped accesses in various
>> cases through the iowrite#_rep functions, and all platforms which override
>> the default musb_read[b|w] / _write[b|w] functions also provide their own
>> fifo access functions, so we can safely drop the unnecessary indirection
>> from the fifo access functions.
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>
>
> The patch looks reasonably, but the description seem misleading.
> I believe the real reason why it's ok to use __raw_writew for the
> FIFO is that a FIFO by definition is using CPU endian access for
> copying byte streams from memory, which is unlike any other MMIO
> register that requires fixed-endian accessors.

I'm not sure that that is the case here, this fifo allows reading
4 bytes at a time using 32 bit word access, so endianness may come
into play. This patch is safe however since all existing users of
the generic fifo_read / write helpers which this patch touches, are
also using the generic musb_read[b|w] / _write[b|w] functions which
are just __raw_foo wrappers, so there is no functional change, which
is what the commit message tries to say.

Note that sunxi needs this function because of the register address
translation the sunxi_musb_readb / writeb wrappers are doing which
does not know how to deal with fifo data, and besides that it should
make the generic read / write fifo helpers somewhat faster by removing
an indirect function call.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
@ 2015-03-10  7:43           ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  7:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 09-03-15 22:50, Arnd Bergmann wrote:
> On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
>> The generic fifo functions already use non wrapped accesses in various
>> cases through the iowrite#_rep functions, and all platforms which override
>> the default musb_read[b|w] / _write[b|w] functions also provide their own
>> fifo access functions, so we can safely drop the unnecessary indirection
>> from the fifo access functions.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>
>
> The patch looks reasonably, but the description seem misleading.
> I believe the real reason why it's ok to use __raw_writew for the
> FIFO is that a FIFO by definition is using CPU endian access for
> copying byte streams from memory, which is unlike any other MMIO
> register that requires fixed-endian accessors.

I'm not sure that that is the case here, this fifo allows reading
4 bytes at a time using 32 bit word access, so endianness may come
into play. This patch is safe however since all existing users of
the generic fifo_read / write helpers which this patch touches, are
also using the generic musb_read[b|w] / _write[b|w] functions which
are just __raw_foo wrappers, so there is no functional change, which
is what the commit message tries to say.

Note that sunxi needs this function because of the register address
translation the sunxi_musb_readb / writeb wrappers are doing which
does not know how to deal with fifo data, and besides that it should
make the generic read / write fifo helpers somewhat faster by removing
an indirect function call.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-09 21:47         ` Arnd Bergmann
@ 2015-03-10  8:04           ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  8:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 09-03-15 22:47, Arnd Bergmann wrote:
> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>> +{
>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>> +       u32 iscr;
>> +
>> +       iscr = readl(data->base + REG_ISCR);
>> +       iscr &= ~clr;
>> +       iscr |= set;
>> +       writel(iscr, data->base + REG_ISCR);
>> +}
>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>> +
>>
>
> I would generally consider this a bad design. What is the purpose of
> calling sun4i_usb_phy_update_iscr()

There are 2 different use cases for this one is to enable the dataline
pull-ups at driver init and disable them at driver exit, this could /
should probably be moved to the phy_init / phy_exit code for the usb0 phy
removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided
to not use the dedicated id-detect and vusb-sense pins of the phy they are
using (these pins are not routed to the outside).

Instead id-detect and vusb-sense are done through any $random gpio pins
(including non irq capable pins on some designs requiring polling).

But the musb-core still needs to know the status of the id and vbus pins,
and gets this from the usb0-phy iscr register, which reflects the status of
the not connected dedicated pins of the phy. The reason this can still
work at all is because the iscr register allows the user to override
whatever the not connected phy pins are seeing and forcing a value to
report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)
{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_ID_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_ID_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_VBUS_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_VBUS_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
}

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on
your second point.

 > and why can't there be a high-level
> PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val);
int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route
I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

If people believe this is too sunxi specific (I believe it is, but as said I'm
fine with doing this either way). I'll respin this patch to remove the too
generic sun4i_usb_phy_update_iscr function, and instead add these 2:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-10  8:04           ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  8:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 09-03-15 22:47, Arnd Bergmann wrote:
> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>> +{
>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>> +       u32 iscr;
>> +
>> +       iscr = readl(data->base + REG_ISCR);
>> +       iscr &= ~clr;
>> +       iscr |= set;
>> +       writel(iscr, data->base + REG_ISCR);
>> +}
>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>> +
>>
>
> I would generally consider this a bad design. What is the purpose of
> calling sun4i_usb_phy_update_iscr()

There are 2 different use cases for this one is to enable the dataline
pull-ups at driver init and disable them at driver exit, this could /
should probably be moved to the phy_init / phy_exit code for the usb0 phy
removing the need to do this from within the sunxi musb glue.

The second use-case is more tricky, for some reasons Allwinner has decided
to not use the dedicated id-detect and vusb-sense pins of the phy they are
using (these pins are not routed to the outside).

Instead id-detect and vusb-sense are done through any $random gpio pins
(including non irq capable pins on some designs requiring polling).

But the musb-core still needs to know the status of the id and vbus pins,
and gets this from the usb0-phy iscr register, which reflects the status of
the not connected dedicated pins of the phy. The reason this can still
work at all is because the iscr register allows the user to override
whatever the not connected phy pins are seeing and forcing a value to
report to the musb core as id and vbus status.

This is done by these 2 functions in the musb sunxi glue:

static void sunxi_musb_force_id(struct musb *musb, u32 val)
{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_ID_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_ID_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
}

static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
{
         struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);

         if (val)
                 val = SUNXI_ISCR_FORCE_VBUS_HIGH;
         else
                 val = SUNXI_ISCR_FORCE_VBUS_LOW;

         sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
}

I will happily admit that these 2 functions are a better API between the sunxi musb
glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
approach as I wanted to keep the API as small as possible, but having 2 functions like
the one above, which actually reflect what is happening would indeed be better.

Note that the polling of the pins cannot (easily) be moved into the phy driver for various
reasons:

1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
pins at all.
2) the musb set_vbus callback needs access to the pins
3) When id changes some musb core state changes are necessary.

I'll respin the patch set to do things this way as soon as we've agreement on
your second point.

 > and why can't there be a high-level
> PHY API for this?

The current generic phy API seems to not have any bus specific methods, I know that
in the long run people want to get rid of struct usb_phy, so maybe we should consider
adding bus specific methods to the generic phy API for things like otg.

If we decide to add bus specific methods, then the question becomes if having

int phy_usb_set_id_detect(struct phy *phy, bool val);
int phy_usb_set_vbus_detect(struct phy *phy, bool val);

Functions in the generic phy API is a good idea, or if this is too sunxi specific,
I'm fine with doing this either way. If we want to go the generic phy route
I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
1 doing the sunxi implementation.

If people believe this is too sunxi specific (I believe it is, but as said I'm
fine with doing this either way). I'll respin this patch to remove the too
generic sun4i_usb_phy_update_iscr function, and instead add these 2:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-10  1:46       ` Chen-Yu Tsai
@ 2015-03-10  8:31           ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10  8:31 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Hans de Goede, Felipe Balbi, Kishon Vijay Abraham I,
	Maxime Ripard, Roman Byshko, linux-usb, linux-arm-kernel,
	devicetree, linux-sunxi

On Tuesday 10 March 2015 09:46:24 Chen-Yu Tsai wrote:
> I believe you are talking about "mmio-sram"?

Yes.
 
> The syscon here represents a switch, to toggle whether a block of SRAM is
> mapped into the CPU memory space, or to a specific devices private address
> space. It is not the actual SRAM.
> 
> The SRAM DT binding is orthogonal to this, if not irrelevant when the block
> is mapped privately, as it is no longer visible from the DT's PoV.

Ok, got it. I missed this part when reading the introduction. syscon seems
fine to me then.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-10  8:31           ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10  8:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 March 2015 09:46:24 Chen-Yu Tsai wrote:
> I believe you are talking about "mmio-sram"?

Yes.
 
> The syscon here represents a switch, to toggle whether a block of SRAM is
> mapped into the CPU memory space, or to a specific devices private address
> space. It is not the actual SRAM.
> 
> The SRAM DT binding is orthogonal to this, if not irrelevant when the block
> is mapped privately, as it is no longer visible from the DT's PoV.

Ok, got it. I missed this part when reading the introduction. syscon seems
fine to me then.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
  2015-03-10  7:43           ` Hans de Goede
@ 2015-03-10  8:50               ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10  8:50 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
> On 09-03-15 22:50, Arnd Bergmann wrote:
> > On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
> >> The generic fifo functions already use non wrapped accesses in various
> >> cases through the iowrite#_rep functions, and all platforms which override
> >> the default musb_read[b|w] / _write[b|w] functions also provide their own
> >> fifo access functions, so we can safely drop the unnecessary indirection
> >> from the fifo access functions.
> >>
> >> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> >>
> >
> > The patch looks reasonably, but the description seem misleading.
> > I believe the real reason why it's ok to use __raw_writew for the
> > FIFO is that a FIFO by definition is using CPU endian access for
> > copying byte streams from memory, which is unlike any other MMIO
> > register that requires fixed-endian accessors.
> 
> I'm not sure that that is the case here, this fifo allows reading
> 4 bytes at a time using 32 bit word access, so endianness may come
> into play. This patch is safe however since all existing users of
> the generic fifo_read / write helpers which this patch touches, are
> also using the generic musb_read[b|w] / _write[b|w] functions which
> are just __raw_foo wrappers, so there is no functional change, which
> is what the commit message tries to say.

This probably means that the generic musb helpers are not safe to use
on big-endian ARM systems (but may work on MIPS). The only one currently
not using the generic helpers is blackfin, which is fixed to little
endian.
 
> Note that sunxi needs this function because of the register address
> translation the sunxi_musb_readb / writeb wrappers are doing which
> does not know how to deal with fifo data, and besides that it should
> make the generic read / write fifo helpers somewhat faster by removing
> an indirect function call.

Your sunxi_musb_readw/writew functions however also are endian-safe
and seem to get this part right, unlike all other platforms that use
the generic __raw_*() accessors. With this patch applied, it should
actually work fine, and it would work on other platforms as well
if we change all __raw_*() calls outside of musb_default_write_fifo()
and musb_default_read_fifo() to use *_relaxed() instead.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
@ 2015-03-10  8:50               ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10  8:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
> On 09-03-15 22:50, Arnd Bergmann wrote:
> > On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
> >> The generic fifo functions already use non wrapped accesses in various
> >> cases through the iowrite#_rep functions, and all platforms which override
> >> the default musb_read[b|w] / _write[b|w] functions also provide their own
> >> fifo access functions, so we can safely drop the unnecessary indirection
> >> from the fifo access functions.
> >>
> >> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>
> >
> > The patch looks reasonably, but the description seem misleading.
> > I believe the real reason why it's ok to use __raw_writew for the
> > FIFO is that a FIFO by definition is using CPU endian access for
> > copying byte streams from memory, which is unlike any other MMIO
> > register that requires fixed-endian accessors.
> 
> I'm not sure that that is the case here, this fifo allows reading
> 4 bytes at a time using 32 bit word access, so endianness may come
> into play. This patch is safe however since all existing users of
> the generic fifo_read / write helpers which this patch touches, are
> also using the generic musb_read[b|w] / _write[b|w] functions which
> are just __raw_foo wrappers, so there is no functional change, which
> is what the commit message tries to say.

This probably means that the generic musb helpers are not safe to use
on big-endian ARM systems (but may work on MIPS). The only one currently
not using the generic helpers is blackfin, which is fixed to little
endian.
 
> Note that sunxi needs this function because of the register address
> translation the sunxi_musb_readb / writeb wrappers are doing which
> does not know how to deal with fifo data, and besides that it should
> make the generic read / write fifo helpers somewhat faster by removing
> an indirect function call.

Your sunxi_musb_readw/writew functions however also are endian-safe
and seem to get this part right, unlike all other platforms that use
the generic __raw_*() accessors. With this patch applied, it should
actually work fine, and it would work on other platforms as well
if we change all __raw_*() calls outside of musb_default_write_fifo()
and musb_default_read_fifo() to use *_relaxed() instead.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
  2015-03-10  8:50               ` Arnd Bergmann
@ 2015-03-10  8:56                 ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  8:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 10-03-15 09:50, Arnd Bergmann wrote:
> On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
>> On 09-03-15 22:50, Arnd Bergmann wrote:
>>> On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
>>>> The generic fifo functions already use non wrapped accesses in various
>>>> cases through the iowrite#_rep functions, and all platforms which override
>>>> the default musb_read[b|w] / _write[b|w] functions also provide their own
>>>> fifo access functions, so we can safely drop the unnecessary indirection
>>>> from the fifo access functions.
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>>>
>>>
>>> The patch looks reasonably, but the description seem misleading.
>>> I believe the real reason why it's ok to use __raw_writew for the
>>> FIFO is that a FIFO by definition is using CPU endian access for
>>> copying byte streams from memory, which is unlike any other MMIO
>>> register that requires fixed-endian accessors.
>>
>> I'm not sure that that is the case here, this fifo allows reading
>> 4 bytes at a time using 32 bit word access, so endianness may come
>> into play. This patch is safe however since all existing users of
>> the generic fifo_read / write helpers which this patch touches, are
>> also using the generic musb_read[b|w] / _write[b|w] functions which
>> are just __raw_foo wrappers, so there is no functional change, which
>> is what the commit message tries to say.
>
> This probably means that the generic musb helpers are not safe to use
> on big-endian ARM systems (but may work on MIPS). The only one currently
> not using the generic helpers is blackfin, which is fixed to little
> endian.
>
>> Note that sunxi needs this function because of the register address
>> translation the sunxi_musb_readb / writeb wrappers are doing which
>> does not know how to deal with fifo data, and besides that it should
>> make the generic read / write fifo helpers somewhat faster by removing
>> an indirect function call.
>
> Your sunxi_musb_readw/writew functions however also are endian-safe
> and seem to get this part right, unlike all other platforms that use
> the generic __raw_*() accessors. With this patch applied, it should
> actually work fine, and it would work on other platforms as well
> if we change all __raw_*() calls outside of musb_default_write_fifo()
> and musb_default_read_fifo() to use *_relaxed() instead.

I think that that change falls outside of the scope of this patchset.

I agree that it would be probably a good idea to get rid of the
__raw_foo usage in musb, which is why I've used the non __raw
versions in the sunxi glue, but as said I believe this falls outside
of the scope of this patchset. All my preparation patches for adding
sunxi support carefully do not make any functional changes, as I
do not want to cause regressions on hardware which I cannot test.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
@ 2015-03-10  8:56                 ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 10-03-15 09:50, Arnd Bergmann wrote:
> On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
>> On 09-03-15 22:50, Arnd Bergmann wrote:
>>> On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
>>>> The generic fifo functions already use non wrapped accesses in various
>>>> cases through the iowrite#_rep functions, and all platforms which override
>>>> the default musb_read[b|w] / _write[b|w] functions also provide their own
>>>> fifo access functions, so we can safely drop the unnecessary indirection
>>>> from the fifo access functions.
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>>>>
>>>
>>> The patch looks reasonably, but the description seem misleading.
>>> I believe the real reason why it's ok to use __raw_writew for the
>>> FIFO is that a FIFO by definition is using CPU endian access for
>>> copying byte streams from memory, which is unlike any other MMIO
>>> register that requires fixed-endian accessors.
>>
>> I'm not sure that that is the case here, this fifo allows reading
>> 4 bytes at a time using 32 bit word access, so endianness may come
>> into play. This patch is safe however since all existing users of
>> the generic fifo_read / write helpers which this patch touches, are
>> also using the generic musb_read[b|w] / _write[b|w] functions which
>> are just __raw_foo wrappers, so there is no functional change, which
>> is what the commit message tries to say.
>
> This probably means that the generic musb helpers are not safe to use
> on big-endian ARM systems (but may work on MIPS). The only one currently
> not using the generic helpers is blackfin, which is fixed to little
> endian.
>
>> Note that sunxi needs this function because of the register address
>> translation the sunxi_musb_readb / writeb wrappers are doing which
>> does not know how to deal with fifo data, and besides that it should
>> make the generic read / write fifo helpers somewhat faster by removing
>> an indirect function call.
>
> Your sunxi_musb_readw/writew functions however also are endian-safe
> and seem to get this part right, unlike all other platforms that use
> the generic __raw_*() accessors. With this patch applied, it should
> actually work fine, and it would work on other platforms as well
> if we change all __raw_*() calls outside of musb_default_write_fifo()
> and musb_default_read_fifo() to use *_relaxed() instead.

I think that that change falls outside of the scope of this patchset.

I agree that it would be probably a good idea to get rid of the
__raw_foo usage in musb, which is why I've used the non __raw
versions in the sunxi glue, but as said I believe this falls outside
of the scope of this patchset. All my preparation patches for adding
sunxi support carefully do not make any functional changes, as I
do not want to cause regressions on hardware which I cannot test.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-10  8:04           ` Hans de Goede
@ 2015-03-10  8:57               ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10  8:57 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
> Hi,
> 
> On 09-03-15 22:47, Arnd Bergmann wrote:
> > On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
> >> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
> >> +{
> >> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> >> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> >> +       u32 iscr;
> >> +
> >> +       iscr = readl(data->base + REG_ISCR);
> >> +       iscr &= ~clr;
> >> +       iscr |= set;
> >> +       writel(iscr, data->base + REG_ISCR);
> >> +}
> >> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
> >> +
> >>
> >
> > I would generally consider this a bad design. What is the purpose of
> > calling sun4i_usb_phy_update_iscr()
> 
> There are 2 different use cases for this one is to enable the dataline
> pull-ups at driver init and disable them at driver exit, this could /
> should probably be moved to the phy_init / phy_exit code for the usb0 phy
> removing the need to do this from within the sunxi musb glue.
> 
> The second use-case is more tricky, for some reasons Allwinner has decided
> to not use the dedicated id-detect and vusb-sense pins of the phy they are
> using (these pins are not routed to the outside).
> 
> Instead id-detect and vusb-sense are done through any $random gpio pins
> (including non irq capable pins on some designs requiring polling).
> 
> But the musb-core still needs to know the status of the id and vbus pins,
> and gets this from the usb0-phy iscr register, which reflects the status of
> the not connected dedicated pins of the phy. The reason this can still
> work at all is because the iscr register allows the user to override
> whatever the not connected phy pins are seeing and forcing a value to
> report to the musb core as id and vbus status.
> 
> This is done by these 2 functions in the musb sunxi glue:
> 
> static void sunxi_musb_force_id(struct musb *musb, u32 val)
> {
>          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
> 
>          if (val)
>                  val = SUNXI_ISCR_FORCE_ID_HIGH;
>          else
>                  val = SUNXI_ISCR_FORCE_ID_LOW;
> 
>          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
> }
> 
> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
> {
>          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
> 
>          if (val)
>                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>          else
>                  val = SUNXI_ISCR_FORCE_VBUS_LOW;
> 
>          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
> }
> 
> I will happily admit that these 2 functions are a better API between the sunxi musb
> glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
> approach as I wanted to keep the API as small as possible, but having 2 functions like
> the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

> Note that the polling of the pins cannot (easily) be moved into the phy driver for various
> reasons:
> 
> 1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
> pins at all.
> 2) the musb set_vbus callback needs access to the pins
> 3) When id changes some musb core state changes are necessary.
> 
> I'll respin the patch set to do things this way as soon as we've agreement on
> your second point.
> 
>  > and why can't there be a high-level
> > PHY API for this?
> 
> The current generic phy API seems to not have any bus specific methods, I know that
> in the long run people want to get rid of struct usb_phy, so maybe we should consider
> adding bus specific methods to the generic phy API for things like otg.
> 
> If we decide to add bus specific methods, then the question becomes if having
> 
> int phy_usb_set_id_detect(struct phy *phy, bool val);
> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
> 
> Functions in the generic phy API is a good idea, or if this is too sunxi specific,
> I'm fine with doing this either way. If we want to go the generic phy route
> I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
> 1 doing the sunxi implementation.
> 
> If people believe this is too sunxi specific (I believe it is, but as said I'm
> fine with doing this either way). I'll respin this patch to remove the too
> generic sun4i_usb_phy_update_iscr function, and instead add these 2:
> 
> void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
> void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Thanks for your detailed explanations. I think this is something for
Kishon to decide, based on where he wants to take the phy API in the
long run. I'm fine with it either way, and it seems easy enough to
change between those two interfaces if we make up our minds about it
later.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-10  8:57               ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10  8:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
> Hi,
> 
> On 09-03-15 22:47, Arnd Bergmann wrote:
> > On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
> >> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
> >> +{
> >> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> >> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> >> +       u32 iscr;
> >> +
> >> +       iscr = readl(data->base + REG_ISCR);
> >> +       iscr &= ~clr;
> >> +       iscr |= set;
> >> +       writel(iscr, data->base + REG_ISCR);
> >> +}
> >> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
> >> +
> >>
> >
> > I would generally consider this a bad design. What is the purpose of
> > calling sun4i_usb_phy_update_iscr()
> 
> There are 2 different use cases for this one is to enable the dataline
> pull-ups at driver init and disable them at driver exit, this could /
> should probably be moved to the phy_init / phy_exit code for the usb0 phy
> removing the need to do this from within the sunxi musb glue.
> 
> The second use-case is more tricky, for some reasons Allwinner has decided
> to not use the dedicated id-detect and vusb-sense pins of the phy they are
> using (these pins are not routed to the outside).
> 
> Instead id-detect and vusb-sense are done through any $random gpio pins
> (including non irq capable pins on some designs requiring polling).
> 
> But the musb-core still needs to know the status of the id and vbus pins,
> and gets this from the usb0-phy iscr register, which reflects the status of
> the not connected dedicated pins of the phy. The reason this can still
> work at all is because the iscr register allows the user to override
> whatever the not connected phy pins are seeing and forcing a value to
> report to the musb core as id and vbus status.
> 
> This is done by these 2 functions in the musb sunxi glue:
> 
> static void sunxi_musb_force_id(struct musb *musb, u32 val)
> {
>          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
> 
>          if (val)
>                  val = SUNXI_ISCR_FORCE_ID_HIGH;
>          else
>                  val = SUNXI_ISCR_FORCE_ID_LOW;
> 
>          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
> }
> 
> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
> {
>          struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
> 
>          if (val)
>                  val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>          else
>                  val = SUNXI_ISCR_FORCE_VBUS_LOW;
> 
>          sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
> }
> 
> I will happily admit that these 2 functions are a better API between the sunxi musb
> glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
> approach as I wanted to keep the API as small as possible, but having 2 functions like
> the one above, which actually reflect what is happening would indeed be better.

Ok, that would definitely improve things.

> Note that the polling of the pins cannot (easily) be moved into the phy driver for various
> reasons:
> 
> 1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
> pins at all.
> 2) the musb set_vbus callback needs access to the pins
> 3) When id changes some musb core state changes are necessary.
> 
> I'll respin the patch set to do things this way as soon as we've agreement on
> your second point.
> 
>  > and why can't there be a high-level
> > PHY API for this?
> 
> The current generic phy API seems to not have any bus specific methods, I know that
> in the long run people want to get rid of struct usb_phy, so maybe we should consider
> adding bus specific methods to the generic phy API for things like otg.
> 
> If we decide to add bus specific methods, then the question becomes if having
> 
> int phy_usb_set_id_detect(struct phy *phy, bool val);
> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
> 
> Functions in the generic phy API is a good idea, or if this is too sunxi specific,
> I'm fine with doing this either way. If we want to go the generic phy route
> I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
> 1 doing the sunxi implementation.
> 
> If people believe this is too sunxi specific (I believe it is, but as said I'm
> fine with doing this either way). I'll respin this patch to remove the too
> generic sun4i_usb_phy_update_iscr function, and instead add these 2:
> 
> void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
> void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

Thanks for your detailed explanations. I think this is something for
Kishon to decide, based on where he wants to take the phy API in the
long run. I'm fine with it either way, and it seems easy enough to
change between those two interfaces if we make up our minds about it
later.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller
  2015-03-09 23:31         ` [linux-sunxi] " Julian Calaby
@ 2015-03-10  9:10             ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  9:10 UTC (permalink / raw)
  To: Julian Calaby, linux-sunxi
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	Mailing List, Arm, devicetree

Hi,

On 10-03-15 00:31, Julian Calaby wrote:
> Hi Hans,
>
> On Tue, Mar 10, 2015 at 7:40 AM, Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>> Add a node for the otg/drc usb controller to sun4i-a10.dtsi.
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>>   arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
>>   drivers/usb/musb/Kconfig         |  1 +
>>   2 files changed, 13 insertions(+)
>>
>> diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
>> index 8180a3a..fab8e9a 100644
>> --- a/drivers/usb/musb/Kconfig
>> +++ b/drivers/usb/musb/Kconfig
>> @@ -65,6 +65,7 @@ comment "Platform Glue Layer"
>>   config USB_MUSB_SUNXI
>>          tristate "Allwinner (sunxi)"
>>          depends on ARCH_SUNXI
>> +       depends on NOP_USB_XCEIV
>
> Shouldn't this be in a different patch?

Yes, this was a later fixup commit which got squashed into the wrong patch,
thanks for catching this.

This has been fixed in my personal tree, and will be in v2 of this set:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [linux-sunxi] [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller
@ 2015-03-10  9:10             ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10  9:10 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 10-03-15 00:31, Julian Calaby wrote:
> Hi Hans,
>
> On Tue, Mar 10, 2015 at 7:40 AM, Hans de Goede <hdegoede@redhat.com> wrote:
>> Add a node for the otg/drc usb controller to sun4i-a10.dtsi.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   arch/arm/boot/dts/sun4i-a10.dtsi | 12 ++++++++++++
>>   drivers/usb/musb/Kconfig         |  1 +
>>   2 files changed, 13 insertions(+)
>>
>> diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
>> index 8180a3a..fab8e9a 100644
>> --- a/drivers/usb/musb/Kconfig
>> +++ b/drivers/usb/musb/Kconfig
>> @@ -65,6 +65,7 @@ comment "Platform Glue Layer"
>>   config USB_MUSB_SUNXI
>>          tristate "Allwinner (sunxi)"
>>          depends on ARCH_SUNXI
>> +       depends on NOP_USB_XCEIV
>
> Shouldn't this be in a different patch?

Yes, this was a later fixup commit which got squashed into the wrong patch,
thanks for catching this.

This has been fixed in my personal tree, and will be in v2 of this set:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-10  8:57               ` Arnd Bergmann
@ 2015-03-10 10:13                 ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 10:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 10-03-15 09:57, Arnd Bergmann wrote:
> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>> Hi,
>>
>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>> +{
>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>> +       u32 iscr;
>>>> +
>>>> +       iscr = readl(data->base + REG_ISCR);
>>>> +       iscr &= ~clr;
>>>> +       iscr |= set;
>>>> +       writel(iscr, data->base + REG_ISCR);
>>>> +}
>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>> +
>>>>
>>>
>>> I would generally consider this a bad design. What is the purpose of
>>> calling sun4i_usb_phy_update_iscr()
>>
>> There are 2 different use cases for this one is to enable the dataline
>> pull-ups at driver init and disable them at driver exit, this could /
>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>> removing the need to do this from within the sunxi musb glue.
>>
>> The second use-case is more tricky, for some reasons Allwinner has decided
>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>> using (these pins are not routed to the outside).
>>
>> Instead id-detect and vusb-sense are done through any $random gpio pins
>> (including non irq capable pins on some designs requiring polling).
>>
>> But the musb-core still needs to know the status of the id and vbus pins,
>> and gets this from the usb0-phy iscr register, which reflects the status of
>> the not connected dedicated pins of the phy. The reason this can still
>> work at all is because the iscr register allows the user to override
>> whatever the not connected phy pins are seeing and forcing a value to
>> report to the musb core as id and vbus status.
>>
>> This is done by these 2 functions in the musb sunxi glue:
>>
>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>> {
>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>
>>           if (val)
>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>           else
>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>
>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
>> }
>>
>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>> {
>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>
>>           if (val)
>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>           else
>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>
>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
>> }
>>
>> I will happily admit that these 2 functions are a better API between the sunxi musb
>> glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
>> approach as I wanted to keep the API as small as possible, but having 2 functions like
>> the one above, which actually reflect what is happening would indeed be better.
>
> Ok, that would definitely improve things.
>
>> Note that the polling of the pins cannot (easily) be moved into the phy driver for various
>> reasons:
>>
>> 1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
>> pins at all.
>> 2) the musb set_vbus callback needs access to the pins
>> 3) When id changes some musb core state changes are necessary.
>>
>> I'll respin the patch set to do things this way as soon as we've agreement on
>> your second point.
>>
>>   > and why can't there be a high-level
>>> PHY API for this?
>>
>> The current generic phy API seems to not have any bus specific methods, I know that
>> in the long run people want to get rid of struct usb_phy, so maybe we should consider
>> adding bus specific methods to the generic phy API for things like otg.
>>
>> If we decide to add bus specific methods, then the question becomes if having
>>
>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>
>> Functions in the generic phy API is a good idea, or if this is too sunxi specific,
>> I'm fine with doing this either way. If we want to go the generic phy route
>> I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
>> 1 doing the sunxi implementation.
>>
>> If people believe this is too sunxi specific (I believe it is, but as said I'm
>> fine with doing this either way). I'll respin this patch to remove the too
>> generic sun4i_usb_phy_update_iscr function, and instead add these 2:
>>
>> void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
>> void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);
>
> Thanks for your detailed explanations. I think this is something for
> Kishon to decide, based on where he wants to take the phy API in the
> long run. I'm fine with it either way, and it seems easy enough to
> change between those two interfaces if we make up our minds about it
> later.

Ok, so I've fixed things in my personal tree to use 2 sun4i private functions for
now:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

You can find this change here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

I'll wait a bit to see if there are more review comments and then
I'll send a v2 of the set.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-10 10:13                 ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 10-03-15 09:57, Arnd Bergmann wrote:
> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>> Hi,
>>
>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>> +{
>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>> +       u32 iscr;
>>>> +
>>>> +       iscr = readl(data->base + REG_ISCR);
>>>> +       iscr &= ~clr;
>>>> +       iscr |= set;
>>>> +       writel(iscr, data->base + REG_ISCR);
>>>> +}
>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>> +
>>>>
>>>
>>> I would generally consider this a bad design. What is the purpose of
>>> calling sun4i_usb_phy_update_iscr()
>>
>> There are 2 different use cases for this one is to enable the dataline
>> pull-ups at driver init and disable them at driver exit, this could /
>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>> removing the need to do this from within the sunxi musb glue.
>>
>> The second use-case is more tricky, for some reasons Allwinner has decided
>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>> using (these pins are not routed to the outside).
>>
>> Instead id-detect and vusb-sense are done through any $random gpio pins
>> (including non irq capable pins on some designs requiring polling).
>>
>> But the musb-core still needs to know the status of the id and vbus pins,
>> and gets this from the usb0-phy iscr register, which reflects the status of
>> the not connected dedicated pins of the phy. The reason this can still
>> work at all is because the iscr register allows the user to override
>> whatever the not connected phy pins are seeing and forcing a value to
>> report to the musb core as id and vbus status.
>>
>> This is done by these 2 functions in the musb sunxi glue:
>>
>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>> {
>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>
>>           if (val)
>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>           else
>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>
>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
>> }
>>
>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>> {
>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>
>>           if (val)
>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>           else
>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>
>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK, val);
>> }
>>
>> I will happily admit that these 2 functions are a better API between the sunxi musb
>> glue and the sunxi usb phy driver. I started with the minimal sun4i_usb_phy_update_iscr
>> approach as I wanted to keep the API as small as possible, but having 2 functions like
>> the one above, which actually reflect what is happening would indeed be better.
>
> Ok, that would definitely improve things.
>
>> Note that the polling of the pins cannot (easily) be moved into the phy driver for various
>> reasons:
>>
>> 1) It depends on dr_mode, the otg may be used in host only mode in which case there are no
>> pins at all.
>> 2) the musb set_vbus callback needs access to the pins
>> 3) When id changes some musb core state changes are necessary.
>>
>> I'll respin the patch set to do things this way as soon as we've agreement on
>> your second point.
>>
>>   > and why can't there be a high-level
>>> PHY API for this?
>>
>> The current generic phy API seems to not have any bus specific methods, I know that
>> in the long run people want to get rid of struct usb_phy, so maybe we should consider
>> adding bus specific methods to the generic phy API for things like otg.
>>
>> If we decide to add bus specific methods, then the question becomes if having
>>
>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>
>> Functions in the generic phy API is a good idea, or if this is too sunxi specific,
>> I'm fine with doing this either way. If we want to go the generic phy route
>> I'll split this in 2 patches, one adding these 2 generic functions & phy-ops, and
>> 1 doing the sunxi implementation.
>>
>> If people believe this is too sunxi specific (I believe it is, but as said I'm
>> fine with doing this either way). I'll respin this patch to remove the too
>> generic sun4i_usb_phy_update_iscr function, and instead add these 2:
>>
>> void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
>> void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);
>
> Thanks for your detailed explanations. I think this is something for
> Kishon to decide, based on where he wants to take the phy API in the
> long run. I'm fine with it either way, and it seems easy enough to
> change between those two interfaces if we make up our minds about it
> later.

Ok, so I've fixed things in my personal tree to use 2 sun4i private functions for
now:

void sun4i_usb_phy_set_id_detect(struct phy *phy, bool val);
void sun4i_usb_phy_set_vbus_detect(struct phy *phy, bool val);

You can find this change here:
https://github.com/jwrdegoede/linux-sunxi/commits/sunxi-wip

I'll wait a bit to see if there are more review comments and then
I'll send a v2 of the set.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-10 10:13                 ` Hans de Goede
@ 2015-03-10 10:53                     ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-10 10:53 UTC (permalink / raw)
  To: Hans de Goede, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
> Hi,
>
> On 10-03-15 09:57, Arnd Bergmann wrote:
>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>> Hi,
>>>
>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>> +{
>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>> +       u32 iscr;
>>>>> +
>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>> +       iscr &= ~clr;
>>>>> +       iscr |= set;
>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>> +}
>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>> +
>>>>>
>>>>
>>>> I would generally consider this a bad design. What is the purpose of
>>>> calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would
start creating problems when a different PHY is connected with the
controller.
>>>
>>> There are 2 different use cases for this one is to enable the dataline
>>> pull-ups at driver init and disable them at driver exit, this could /
>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>> removing the need to do this from within the sunxi musb glue.
>>>
>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>> using (these pins are not routed to the outside).
>>>
>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>> (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework
to report the status to controller driver no?
>>>
>>> But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?
>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>> the not connected dedicated pins of the phy. The reason this can still
>>> work at all is because the iscr register allows the user to override
>>> whatever the not connected phy pins are seeing and forcing a value to
>>> report to the musb core as id and vbus status.
>>>
>>> This is done by these 2 functions in the musb sunxi glue:
>>>
>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>> {
>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>
>>>           if (val)
>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>           else
>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>
>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
interrupt handler?
>>> }
>>>
>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>> {
>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>
>>>           if (val)
>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>           else
>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>
>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>> val);
>>> }
>>>
>>> I will happily admit that these 2 functions are a better API between the
>>> sunxi musb
>>> glue and the sunxi usb phy driver. I started with the minimal
>>> sun4i_usb_phy_update_iscr
>>> approach as I wanted to keep the API as small as possible, but having 2
>>> functions like
>>> the one above, which actually reflect what is happening would indeed be better.
>>
>> Ok, that would definitely improve things.
>>
>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>> driver for various
>>> reasons:
>>>
>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>> case there are no
>>> pins at all.
>>> 2) the musb set_vbus callback needs access to the pins
>>> 3) When id changes some musb core state changes are necessary.
>>>
>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>> your second point.
>>>
>>>   > and why can't there be a high-level
>>>> PHY API for this?
>>>
>>> The current generic phy API seems to not have any bus specific methods, I
>>> know that
>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>> consider
>>> adding bus specific methods to the generic phy API for things like otg.
>>>
>>> If we decide to add bus specific methods, then the question becomes if having
>>>
>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>
>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>> specific,
>>> I'm fine with doing this either way. If we want to go the generic phy route
>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>> phy-ops, and
>>> 1 doing the sunxi implementation.

Please don't do that. We don't want to be bloating phy framework with platform
specific hooks.

Cheers
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-10 10:53                     ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-10 10:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
> Hi,
>
> On 10-03-15 09:57, Arnd Bergmann wrote:
>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>> Hi,
>>>
>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>> +{
>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>> +       u32 iscr;
>>>>> +
>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>> +       iscr &= ~clr;
>>>>> +       iscr |= set;
>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>> +}
>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>> +
>>>>>
>>>>
>>>> I would generally consider this a bad design. What is the purpose of
>>>> calling sun4i_usb_phy_update_iscr()

right. That would bind the PHY driver and the controller driver and would
start creating problems when a different PHY is connected with the
controller.
>>>
>>> There are 2 different use cases for this one is to enable the dataline
>>> pull-ups at driver init and disable them at driver exit, this could /
>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>> removing the need to do this from within the sunxi musb glue.
>>>
>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>> using (these pins are not routed to the outside).
>>>
>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>> (including non irq capable pins on some designs requiring polling).

The polling can still be done in PHY driver and can use the extcon framework
to report the status to controller driver no?
>>>
>>> But the musb-core still needs to know the status of the id and vbus pins,

musb-core or the musb-glue (musb/sunxi.c in this case)?
>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>> the not connected dedicated pins of the phy. The reason this can still
>>> work at all is because the iscr register allows the user to override
>>> whatever the not connected phy pins are seeing and forcing a value to
>>> report to the musb core as id and vbus status.
>>>
>>> This is done by these 2 functions in the musb sunxi glue:
>>>
>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>> {
>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>
>>>           if (val)
>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>           else
>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>
>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);

What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
interrupt handler?
>>> }
>>>
>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>> {
>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>
>>>           if (val)
>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>           else
>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>
>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>> val);
>>> }
>>>
>>> I will happily admit that these 2 functions are a better API between the
>>> sunxi musb
>>> glue and the sunxi usb phy driver. I started with the minimal
>>> sun4i_usb_phy_update_iscr
>>> approach as I wanted to keep the API as small as possible, but having 2
>>> functions like
>>> the one above, which actually reflect what is happening would indeed be better.
>>
>> Ok, that would definitely improve things.
>>
>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>> driver for various
>>> reasons:
>>>
>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>> case there are no
>>> pins at all.
>>> 2) the musb set_vbus callback needs access to the pins
>>> 3) When id changes some musb core state changes are necessary.
>>>
>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>> your second point.
>>>
>>>   > and why can't there be a high-level
>>>> PHY API for this?
>>>
>>> The current generic phy API seems to not have any bus specific methods, I
>>> know that
>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>> consider
>>> adding bus specific methods to the generic phy API for things like otg.
>>>
>>> If we decide to add bus specific methods, then the question becomes if having
>>>
>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>
>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>> specific,
>>> I'm fine with doing this either way. If we want to go the generic phy route
>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>> phy-ops, and
>>> 1 doing the sunxi implementation.

Please don't do that. We don't want to be bloating phy framework with platform
specific hooks.

Cheers
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-10 10:53                     ` Kishon Vijay Abraham I
@ 2015-03-10 11:03                         ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 11:03 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>> +{
>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>> +       u32 iscr;
>>>>>> +
>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>> +       iscr &= ~clr;
>>>>>> +       iscr |= set;
>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>> +
>>>>>>
>>>>>
>>>>> I would generally consider this a bad design. What is the purpose of
>>>>> calling sun4i_usb_phy_update_iscr()
>
> right. That would bind the PHY driver and the controller driver and would
> start creating problems when a different PHY is connected with the
> controller.
>>>>
>>>> There are 2 different use cases for this one is to enable the dataline
>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>> removing the need to do this from within the sunxi musb glue.
>>>>
>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>> using (these pins are not routed to the outside).
>>>>
>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>> (including non irq capable pins on some designs requiring polling).
>
> The polling can still be done in PHY driver and can use the extcon framework
> to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy,
e.g. we only need to poll when we're in otg mode rather then host-only
or peripheral-only mode, and the mode gets set by the musb driver not phy
the phy driver. The sunxi musb implementation uses an integrated phy, so it
is just much easier and more logical to have all control / polling happening
from a single module rather then from 2 different modules.

>>>>
>>>> But the musb-core still needs to know the status of the id and vbus pins,
>
> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>> the not connected dedicated pins of the phy. The reason this can still
>>>> work at all is because the iscr register allows the user to override
>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>> report to the musb core as id and vbus status.
>>>>
>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>
>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>> {
>>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>>
>>>>           if (val)
>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>           else
>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>
>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
>
> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
> interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb
responds to this, by e.g. starting a session, or when vbus does not get high
after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
pins which are used to monitor the id and vbus status.


>>>> }
>>>>
>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>> {
>>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>>
>>>>           if (val)
>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>           else
>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>
>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>> val);
>>>> }
>>>>
>>>> I will happily admit that these 2 functions are a better API between the
>>>> sunxi musb
>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>> sun4i_usb_phy_update_iscr
>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>> functions like
>>>> the one above, which actually reflect what is happening would indeed be better.
>>>
>>> Ok, that would definitely improve things.
>>>
>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>> driver for various
>>>> reasons:
>>>>
>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>> case there are no
>>>> pins at all.
>>>> 2) the musb set_vbus callback needs access to the pins
>>>> 3) When id changes some musb core state changes are necessary.
>>>>
>>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>>> your second point.
>>>>
>>>>   > and why can't there be a high-level
>>>>> PHY API for this?
>>>>
>>>> The current generic phy API seems to not have any bus specific methods, I
>>>> know that
>>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>>> consider
>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>
>>>> If we decide to add bus specific methods, then the question becomes if having
>>>>
>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>
>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>> specific,
>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>> phy-ops, and
>>>> 1 doing the sunxi implementation.
>
> Please don't do that. We don't want to be bloating phy framework with platform
> specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions
here is best given that we're dealing with an otg controller + phy both if which
are integrated in the same SoC, so we will never seen one used without the other
or vice versa.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-10 11:03                         ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>> +{
>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>> +       u32 iscr;
>>>>>> +
>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>> +       iscr &= ~clr;
>>>>>> +       iscr |= set;
>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>> +}
>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>> +
>>>>>>
>>>>>
>>>>> I would generally consider this a bad design. What is the purpose of
>>>>> calling sun4i_usb_phy_update_iscr()
>
> right. That would bind the PHY driver and the controller driver and would
> start creating problems when a different PHY is connected with the
> controller.
>>>>
>>>> There are 2 different use cases for this one is to enable the dataline
>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>> removing the need to do this from within the sunxi musb glue.
>>>>
>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>> using (these pins are not routed to the outside).
>>>>
>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>> (including non irq capable pins on some designs requiring polling).
>
> The polling can still be done in PHY driver and can use the extcon framework
> to report the status to controller driver no?

Technically the polling can be moved to the phy driver yes, but it is not easy,
e.g. we only need to poll when we're in otg mode rather then host-only
or peripheral-only mode, and the mode gets set by the musb driver not phy
the phy driver. The sunxi musb implementation uses an integrated phy, so it
is just much easier and more logical to have all control / polling happening
from a single module rather then from 2 different modules.

>>>>
>>>> But the musb-core still needs to know the status of the id and vbus pins,
>
> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>> the not connected dedicated pins of the phy. The reason this can still
>>>> work at all is because the iscr register allows the user to override
>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>> report to the musb core as id and vbus status.
>>>>
>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>
>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>> {
>>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>>
>>>>           if (val)
>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>           else
>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>
>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK, val);
>
> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
> interrupt handler?

No this changes the vbus and id status as seen by the musb core, and the musb
responds to this, by e.g. starting a session, or when vbus does not get high
after a session request by reporting a vbus-error interrupt.

The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
pins which are used to monitor the id and vbus status.


>>>> }
>>>>
>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>> {
>>>>           struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent);
>>>>
>>>>           if (val)
>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>           else
>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>
>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>> val);
>>>> }
>>>>
>>>> I will happily admit that these 2 functions are a better API between the
>>>> sunxi musb
>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>> sun4i_usb_phy_update_iscr
>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>> functions like
>>>> the one above, which actually reflect what is happening would indeed be better.
>>>
>>> Ok, that would definitely improve things.
>>>
>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>> driver for various
>>>> reasons:
>>>>
>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>> case there are no
>>>> pins at all.
>>>> 2) the musb set_vbus callback needs access to the pins
>>>> 3) When id changes some musb core state changes are necessary.
>>>>
>>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>>> your second point.
>>>>
>>>>   > and why can't there be a high-level
>>>>> PHY API for this?
>>>>
>>>> The current generic phy API seems to not have any bus specific methods, I
>>>> know that
>>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>>> consider
>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>
>>>> If we decide to add bus specific methods, then the question becomes if having
>>>>
>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>
>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>> specific,
>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>> phy-ops, and
>>>> 1 doing the sunxi implementation.
>
> Please don't do that. We don't want to be bloating phy framework with platform
> specific hooks.

Right, that was my feeling too. I believe that using sunxi specific phy functions
here is best given that we're dealing with an otg controller + phy both if which
are integrated in the same SoC, so we will never seen one used without the other
or vice versa.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
  2015-03-10  8:56                 ` Hans de Goede
@ 2015-03-10 13:43                     ` Arnd Bergmann
  -1 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10 13:43 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Maxime Ripard,
	Chen-Yu Tsai, Roman Byshko, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

On Tuesday 10 March 2015 09:56:52 Hans de Goede wrote:
> On 10-03-15 09:50, Arnd Bergmann wrote:
> > On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
> >> On 09-03-15 22:50, Arnd Bergmann wrote:
> >>> On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
> >>>> The generic fifo functions already use non wrapped accesses in various
> >>>> cases through the iowrite#_rep functions, and all platforms which override
> >>>> the default musb_read[b|w] / _write[b|w] functions also provide their own
> >>>> fifo access functions, so we can safely drop the unnecessary indirection
> >>>> from the fifo access functions.
> >>>>
> >>>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> >>>>
> >>>
> >>> The patch looks reasonably, but the description seem misleading.
> >>> I believe the real reason why it's ok to use __raw_writew for the
> >>> FIFO is that a FIFO by definition is using CPU endian access for
> >>> copying byte streams from memory, which is unlike any other MMIO
> >>> register that requires fixed-endian accessors.
> >>
> >> I'm not sure that that is the case here, this fifo allows reading
> >> 4 bytes at a time using 32 bit word access, so endianness may come
> >> into play. This patch is safe however since all existing users of
> >> the generic fifo_read / write helpers which this patch touches, are
> >> also using the generic musb_read[b|w] / _write[b|w] functions which
> >> are just __raw_foo wrappers, so there is no functional change, which
> >> is what the commit message tries to say.
> >
> > This probably means that the generic musb helpers are not safe to use
> > on big-endian ARM systems (but may work on MIPS). The only one currently
> > not using the generic helpers is blackfin, which is fixed to little
> > endian.
> >
> >> Note that sunxi needs this function because of the register address
> >> translation the sunxi_musb_readb / writeb wrappers are doing which
> >> does not know how to deal with fifo data, and besides that it should
> >> make the generic read / write fifo helpers somewhat faster by removing
> >> an indirect function call.
> >
> > Your sunxi_musb_readw/writew functions however also are endian-safe
> > and seem to get this part right, unlike all other platforms that use
> > the generic __raw_*() accessors. With this patch applied, it should
> > actually work fine, and it would work on other platforms as well
> > if we change all __raw_*() calls outside of musb_default_write_fifo()
> > and musb_default_read_fifo() to use *_relaxed() instead.
> 
> I think that that change falls outside of the scope of this patchset.

Yes, sorry for not being clear about that.

> I agree that it would be probably a good idea to get rid of the
> __raw_foo usage in musb, which is why I've used the non __raw
> versions in the sunxi glue, but as said I believe this falls outside
> of the scope of this patchset. All my preparation patches for adding
> sunxi support carefully do not make any functional changes, as I
> do not want to cause regressions on hardware which I cannot test.

Right.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions
@ 2015-03-10 13:43                     ` Arnd Bergmann
  0 siblings, 0 replies; 88+ messages in thread
From: Arnd Bergmann @ 2015-03-10 13:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 March 2015 09:56:52 Hans de Goede wrote:
> On 10-03-15 09:50, Arnd Bergmann wrote:
> > On Tuesday 10 March 2015 08:43:22 Hans de Goede wrote:
> >> On 09-03-15 22:50, Arnd Bergmann wrote:
> >>> On Monday 09 March 2015 21:40:18 Hans de Goede wrote:
> >>>> The generic fifo functions already use non wrapped accesses in various
> >>>> cases through the iowrite#_rep functions, and all platforms which override
> >>>> the default musb_read[b|w] / _write[b|w] functions also provide their own
> >>>> fifo access functions, so we can safely drop the unnecessary indirection
> >>>> from the fifo access functions.
> >>>>
> >>>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>>>
> >>>
> >>> The patch looks reasonably, but the description seem misleading.
> >>> I believe the real reason why it's ok to use __raw_writew for the
> >>> FIFO is that a FIFO by definition is using CPU endian access for
> >>> copying byte streams from memory, which is unlike any other MMIO
> >>> register that requires fixed-endian accessors.
> >>
> >> I'm not sure that that is the case here, this fifo allows reading
> >> 4 bytes at a time using 32 bit word access, so endianness may come
> >> into play. This patch is safe however since all existing users of
> >> the generic fifo_read / write helpers which this patch touches, are
> >> also using the generic musb_read[b|w] / _write[b|w] functions which
> >> are just __raw_foo wrappers, so there is no functional change, which
> >> is what the commit message tries to say.
> >
> > This probably means that the generic musb helpers are not safe to use
> > on big-endian ARM systems (but may work on MIPS). The only one currently
> > not using the generic helpers is blackfin, which is fixed to little
> > endian.
> >
> >> Note that sunxi needs this function because of the register address
> >> translation the sunxi_musb_readb / writeb wrappers are doing which
> >> does not know how to deal with fifo data, and besides that it should
> >> make the generic read / write fifo helpers somewhat faster by removing
> >> an indirect function call.
> >
> > Your sunxi_musb_readw/writew functions however also are endian-safe
> > and seem to get this part right, unlike all other platforms that use
> > the generic __raw_*() accessors. With this patch applied, it should
> > actually work fine, and it would work on other platforms as well
> > if we change all __raw_*() calls outside of musb_default_write_fifo()
> > and musb_default_read_fifo() to use *_relaxed() instead.
> 
> I think that that change falls outside of the scope of this patchset.

Yes, sorry for not being clear about that.

> I agree that it would be probably a good idea to get rid of the
> __raw_foo usage in musb, which is why I've used the non __raw
> versions in the sunxi glue, but as said I believe this falls outside
> of the scope of this patchset. All my preparation patches for adding
> sunxi support carefully do not make any functional changes, as I
> do not want to cause regressions on hardware which I cannot test.

Right.

	Arnd

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
  2015-03-09 20:40     ` Hans de Goede
@ 2015-03-10 15:07         ` Maxime Ripard
  -1 siblings, 0 replies; 88+ messages in thread
From: Maxime Ripard @ 2015-03-10 15:07 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

[-- Attachment #1: Type: text/plain, Size: 1804 bytes --]

Hi Hans,

On Mon, Mar 09, 2015 at 09:40:25PM +0100, Hans de Goede wrote:
> Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.
> 
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
>  arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> index 97fca89..034396c 100644
> --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> @@ -111,6 +111,26 @@
>  	status = "okay";
>  };
>  
> +&pio {
> +	usb0_id_detect_pin: usb0_id_detect_pin@0 {
> +		allwinner,pins = "PH4";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> +	};
> +
> +	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
> +		allwinner,pins = "PH5";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
> +	};
> +};
> +
> +&reg_usb0_vbus {
> +	status = "okay";
> +};
> +
>  &reg_usb2_vbus {
>  	status = "okay";
>  };
> @@ -121,7 +141,18 @@
>  	status = "okay";
>  };
>  
> +&usb_otg {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_id_detect_pin
> +		     &usb0_vbus_detect_pin>;
> +	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
> +	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
> +	dr_mode = "otg";

Is there a reason to not put that in the DTSI?

All the users seem to be wiring it as OTG.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
@ 2015-03-10 15:07         ` Maxime Ripard
  0 siblings, 0 replies; 88+ messages in thread
From: Maxime Ripard @ 2015-03-10 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Hans,

On Mon, Mar 09, 2015 at 09:40:25PM +0100, Hans de Goede wrote:
> Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> index 97fca89..034396c 100644
> --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> @@ -111,6 +111,26 @@
>  	status = "okay";
>  };
>  
> +&pio {
> +	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
> +		allwinner,pins = "PH4";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> +	};
> +
> +	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
> +		allwinner,pins = "PH5";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
> +	};
> +};
> +
> +&reg_usb0_vbus {
> +	status = "okay";
> +};
> +
>  &reg_usb2_vbus {
>  	status = "okay";
>  };
> @@ -121,7 +141,18 @@
>  	status = "okay";
>  };
>  
> +&usb_otg {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_id_detect_pin
> +		     &usb0_vbus_detect_pin>;
> +	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
> +	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
> +	dr_mode = "otg";

Is there a reason to not put that in the DTSI?

All the users seem to be wiring it as OTG.

Thanks!
Maxime

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

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
  2015-03-10 15:07         ` Maxime Ripard
@ 2015-03-10 15:23           ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 15:23 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 03/10/2015 04:07 PM, Maxime Ripard wrote:
> Hi Hans,
>
> On Mon, Mar 09, 2015 at 09:40:25PM +0100, Hans de Goede wrote:
>> Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>>   arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
>>   1 file changed, 31 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
>> index 97fca89..034396c 100644
>> --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
>> +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
>> @@ -111,6 +111,26 @@
>>   	status = "okay";
>>   };
>>
>> +&pio {
>> +	usb0_id_detect_pin: usb0_id_detect_pin@0 {
>> +		allwinner,pins = "PH4";
>> +		allwinner,function = "gpio_in";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>> +	};
>> +
>> +	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
>> +		allwinner,pins = "PH5";
>> +		allwinner,function = "gpio_in";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
>> +	};
>> +};
>> +
>> +&reg_usb0_vbus {
>> +	status = "okay";
>> +};
>> +
>>   &reg_usb2_vbus {
>>   	status = "okay";
>>   };
>> @@ -121,7 +141,18 @@
>>   	status = "okay";
>>   };
>>
>> +&usb_otg {
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&usb0_id_detect_pin
>> +		     &usb0_vbus_detect_pin>;
>> +	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
>> +	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
>> +	dr_mode = "otg";
>
> Is there a reason to not put that in the DTSI?

This is not in the dtsi because it is board specific.

> All the users seem to be wiring it as OTG.

Sofar I've only enabled the otg on a handful of boards,
the otg on the Mele-M9 for example is connected to a usb->sata
bridge and as such should be brought up in host only mode.

And on the wobo-i5 (which I still need to create a dts file for)
the otg is connected to an usb wifi module.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
@ 2015-03-10 15:23           ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 15:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 03/10/2015 04:07 PM, Maxime Ripard wrote:
> Hi Hans,
>
> On Mon, Mar 09, 2015 at 09:40:25PM +0100, Hans de Goede wrote:
>> Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>   arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
>>   1 file changed, 31 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
>> index 97fca89..034396c 100644
>> --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
>> +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
>> @@ -111,6 +111,26 @@
>>   	status = "okay";
>>   };
>>
>> +&pio {
>> +	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
>> +		allwinner,pins = "PH4";
>> +		allwinner,function = "gpio_in";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>> +	};
>> +
>> +	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
>> +		allwinner,pins = "PH5";
>> +		allwinner,function = "gpio_in";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
>> +	};
>> +};
>> +
>> +&reg_usb0_vbus {
>> +	status = "okay";
>> +};
>> +
>>   &reg_usb2_vbus {
>>   	status = "okay";
>>   };
>> @@ -121,7 +141,18 @@
>>   	status = "okay";
>>   };
>>
>> +&usb_otg {
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&usb0_id_detect_pin
>> +		     &usb0_vbus_detect_pin>;
>> +	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
>> +	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
>> +	dr_mode = "otg";
>
> Is there a reason to not put that in the DTSI?

This is not in the dtsi because it is board specific.

> All the users seem to be wiring it as OTG.

Sofar I've only enabled the otg on a handful of boards,
the otg on the Mele-M9 for example is connected to a usb->sata
bridge and as such should be brought up in host only mode.

And on the wobo-i5 (which I still need to create a dts file for)
the otg is connected to an usb wifi module.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-09 20:40 ` Hans de Goede
@ 2015-03-10 17:41     ` Maxime Ripard
  -1 siblings, 0 replies; 88+ messages in thread
From: Maxime Ripard @ 2015-03-10 17:41 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

[-- Attachment #1: Type: text/plain, Size: 2749 bytes --]

On Mon, Mar 09, 2015 at 09:40:13PM +0100, Hans de Goede wrote:
> Hi All,
> 
> This patch set has been a while in the making, so I'm very happy to present
> the end result here, and I hope everyone likes it.
> 
> Before talking about merging this there are 2 things which I would like to
> point out:
> 
> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
> mapped to the musb controller by poking some bits in the SRAM controller,
> just like the EMAC patches which were send a while back I've chosen to use
> syscon for this, actually 2 of the patches in this set come directly from the
> SRAM mapping patchset for the EMAC.
> 
> I know that Maxime is not 100% in favor of using syscon:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
> 
> But I disagree with his arguments for writing a special driver for the SRAM
> controller:

And I disagree with your disagreement :)

> 1) syscon was specifically designed for global system control registers like
> this and is fine to use as long as there are no conflicts where 1 bit is of
> interest to multiple drivers, and there is no such conflict here

No. Syscon has been designed for being lazy.

This is a huge abstraction non-sense. You have to put all the logic of
dealing with some external register layout in clients drivers,
including dealing with the different revisions/SoC that are different
from that aspect, and duplicating that code across all client drivers.

> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
> to have a specific driver for this, without really proving a hard need for
> such a driver. But writing such a driver is going to be a lot of work, and
> we've a ton of other work to do, and as said there is no real need for a
> separate driver, syscon works fine for this.

Actually, I already wrote some prototype for this. I'll clean this up
and send it tonight/tomorrow.

> 3) I actually believe that having a specific driver for this is a bad idea,
> because that means inventing a whole new cross driver API for this, and
> getting those right is, hard, a lot of work, and even then one is still likely
> to get it wrong. We can avoid all this by going with the proven syscon solution.

Except that modifying an in-kernel API, especially when we have two
users, is easy. Moving back from syscon is not.

> Maxime, can we please have your ack for moving forward with this using syscon?
> (see above for my arguments why)

If you can address my objections above, sure.

Thanks for your awesome work on this,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-10 17:41     ` Maxime Ripard
  0 siblings, 0 replies; 88+ messages in thread
From: Maxime Ripard @ 2015-03-10 17:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 09, 2015 at 09:40:13PM +0100, Hans de Goede wrote:
> Hi All,
> 
> This patch set has been a while in the making, so I'm very happy to present
> the end result here, and I hope everyone likes it.
> 
> Before talking about merging this there are 2 things which I would like to
> point out:
> 
> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
> mapped to the musb controller by poking some bits in the SRAM controller,
> just like the EMAC patches which were send a while back I've chosen to use
> syscon for this, actually 2 of the patches in this set come directly from the
> SRAM mapping patchset for the EMAC.
> 
> I know that Maxime is not 100% in favor of using syscon:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
> 
> But I disagree with his arguments for writing a special driver for the SRAM
> controller:

And I disagree with your disagreement :)

> 1) syscon was specifically designed for global system control registers like
> this and is fine to use as long as there are no conflicts where 1 bit is of
> interest to multiple drivers, and there is no such conflict here

No. Syscon has been designed for being lazy.

This is a huge abstraction non-sense. You have to put all the logic of
dealing with some external register layout in clients drivers,
including dealing with the different revisions/SoC that are different
from that aspect, and duplicating that code across all client drivers.

> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
> to have a specific driver for this, without really proving a hard need for
> such a driver. But writing such a driver is going to be a lot of work, and
> we've a ton of other work to do, and as said there is no real need for a
> separate driver, syscon works fine for this.

Actually, I already wrote some prototype for this. I'll clean this up
and send it tonight/tomorrow.

> 3) I actually believe that having a specific driver for this is a bad idea,
> because that means inventing a whole new cross driver API for this, and
> getting those right is, hard, a lot of work, and even then one is still likely
> to get it wrong. We can avoid all this by going with the proven syscon solution.

Except that modifying an in-kernel API, especially when we have two
users, is easy. Moving back from syscon is not.

> Maxime, can we please have your ack for moving forward with this using syscon?
> (see above for my arguments why)

If you can address my objections above, sure.

Thanks for your awesome work on this,
Maxime

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

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
  2015-03-10 15:23           ` Hans de Goede
@ 2015-03-10 18:17               ` Maxime Ripard
  -1 siblings, 0 replies; 88+ messages in thread
From: Maxime Ripard @ 2015-03-10 18:17 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

[-- Attachment #1: Type: text/plain, Size: 2375 bytes --]

On Tue, Mar 10, 2015 at 04:23:09PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 03/10/2015 04:07 PM, Maxime Ripard wrote:
> >Hi Hans,
> >
> >On Mon, Mar 09, 2015 at 09:40:25PM +0100, Hans de Goede wrote:
> >>Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.
> >>
> >>Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> >>---
> >>  arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
> >>  1 file changed, 31 insertions(+)
> >>
> >>diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> >>index 97fca89..034396c 100644
> >>--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> >>+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> >>@@ -111,6 +111,26 @@
> >>  	status = "okay";
> >>  };
> >>
> >>+&pio {
> >>+	usb0_id_detect_pin: usb0_id_detect_pin@0 {
> >>+		allwinner,pins = "PH4";
> >>+		allwinner,function = "gpio_in";
> >>+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> >>+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> >>+	};
> >>+
> >>+	usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
> >>+		allwinner,pins = "PH5";
> >>+		allwinner,function = "gpio_in";
> >>+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> >>+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
> >>+	};
> >>+};
> >>+
> >>+&reg_usb0_vbus {
> >>+	status = "okay";
> >>+};
> >>+
> >>  &reg_usb2_vbus {
> >>  	status = "okay";
> >>  };
> >>@@ -121,7 +141,18 @@
> >>  	status = "okay";
> >>  };
> >>
> >>+&usb_otg {
> >>+	pinctrl-names = "default";
> >>+	pinctrl-0 = <&usb0_id_detect_pin
> >>+		     &usb0_vbus_detect_pin>;
> >>+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
> >>+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
> >>+	dr_mode = "otg";
> >
> >Is there a reason to not put that in the DTSI?
> 
> This is not in the dtsi because it is board specific.
> 
> >All the users seem to be wiring it as OTG.
> 
> Sofar I've only enabled the otg on a handful of boards,
> the otg on the Mele-M9 for example is connected to a usb->sata
> bridge and as such should be brought up in host only mode.
> 
> And on the wobo-i5 (which I still need to create a dts file for)
> the otg is connected to an usb wifi module.

Ok, that seems like a good reason :)

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
@ 2015-03-10 18:17               ` Maxime Ripard
  0 siblings, 0 replies; 88+ messages in thread
From: Maxime Ripard @ 2015-03-10 18:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 10, 2015 at 04:23:09PM +0100, Hans de Goede wrote:
> Hi,
> 
> On 03/10/2015 04:07 PM, Maxime Ripard wrote:
> >Hi Hans,
> >
> >On Mon, Mar 09, 2015 at 09:40:25PM +0100, Hans de Goede wrote:
> >>Enable the otg/drc usb controller on the Chuwi V7 CW0825 tablet.
> >>
> >>Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> >>---
> >>  arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 31 +++++++++++++++++++++++++
> >>  1 file changed, 31 insertions(+)
> >>
> >>diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> >>index 97fca89..034396c 100644
> >>--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> >>+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
> >>@@ -111,6 +111,26 @@
> >>  	status = "okay";
> >>  };
> >>
> >>+&pio {
> >>+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
> >>+		allwinner,pins = "PH4";
> >>+		allwinner,function = "gpio_in";
> >>+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> >>+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> >>+	};
> >>+
> >>+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
> >>+		allwinner,pins = "PH5";
> >>+		allwinner,function = "gpio_in";
> >>+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> >>+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
> >>+	};
> >>+};
> >>+
> >>+&reg_usb0_vbus {
> >>+	status = "okay";
> >>+};
> >>+
> >>  &reg_usb2_vbus {
> >>  	status = "okay";
> >>  };
> >>@@ -121,7 +141,18 @@
> >>  	status = "okay";
> >>  };
> >>
> >>+&usb_otg {
> >>+	pinctrl-names = "default";
> >>+	pinctrl-0 = <&usb0_id_detect_pin
> >>+		     &usb0_vbus_detect_pin>;
> >>+	id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
> >>+	vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
> >>+	dr_mode = "otg";
> >
> >Is there a reason to not put that in the DTSI?
> 
> This is not in the dtsi because it is board specific.
> 
> >All the users seem to be wiring it as OTG.
> 
> Sofar I've only enabled the otg on a handful of boards,
> the otg on the Mele-M9 for example is connected to a usb->sata
> bridge and as such should be brought up in host only mode.
> 
> And on the wobo-i5 (which I still need to create a dts file for)
> the otg is connected to an usb wifi module.

Ok, that seems like a good reason :)

Maxime

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

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
  2015-03-10 17:41     ` Maxime Ripard
@ 2015-03-10 22:35       ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 22:35 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Felipe Balbi, Kishon Vijay Abraham I, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 03/10/2015 06:41 PM, Maxime Ripard wrote:
> On Mon, Mar 09, 2015 at 09:40:13PM +0100, Hans de Goede wrote:
>> Hi All,
>>
>> This patch set has been a while in the making, so I'm very happy to present
>> the end result here, and I hope everyone likes it.
>>
>> Before talking about merging this there are 2 things which I would like to
>> point out:
>>
>> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
>> mapped to the musb controller by poking some bits in the SRAM controller,
>> just like the EMAC patches which were send a while back I've chosen to use
>> syscon for this, actually 2 of the patches in this set come directly from the
>> SRAM mapping patchset for the EMAC.
>>
>> I know that Maxime is not 100% in favor of using syscon:
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
>>
>> But I disagree with his arguments for writing a special driver for the SRAM
>> controller:
>
> And I disagree with your disagreement :)
>
>> 1) syscon was specifically designed for global system control registers like
>> this and is fine to use as long as there are no conflicts where 1 bit is of
>> interest to multiple drivers, and there is no such conflict here
>
> No. Syscon has been designed for being lazy.
>
> This is a huge abstraction non-sense. You have to put all the logic of
> dealing with some external register layout in clients drivers,
> including dealing with the different revisions/SoC that are different
> from that aspect, and duplicating that code across all client drivers.
>
>> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
>> to have a specific driver for this, without really proving a hard need for
>> such a driver. But writing such a driver is going to be a lot of work, and
>> we've a ton of other work to do, and as said there is no real need for a
>> separate driver, syscon works fine for this.
>
> Actually, I already wrote some prototype for this. I'll clean this up
> and send it tonight/tomorrow.

Ok, lets see your prototype and then we'll go from there.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller
@ 2015-03-10 22:35       ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-10 22:35 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 03/10/2015 06:41 PM, Maxime Ripard wrote:
> On Mon, Mar 09, 2015 at 09:40:13PM +0100, Hans de Goede wrote:
>> Hi All,
>>
>> This patch set has been a while in the making, so I'm very happy to present
>> the end result here, and I hope everyone likes it.
>>
>> Before talking about merging this there are 2 things which I would like to
>> point out:
>>
>> a) The musb controller in the sunxi SoCs uses some SRAM which needs to be
>> mapped to the musb controller by poking some bits in the SRAM controller,
>> just like the EMAC patches which were send a while back I've chosen to use
>> syscon for this, actually 2 of the patches in this set come directly from the
>> SRAM mapping patchset for the EMAC.
>>
>> I know that Maxime is not 100% in favor of using syscon:
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/320221.html
>>
>> But I disagree with his arguments for writing a special driver for the SRAM
>> controller:
>
> And I disagree with your disagreement :)
>
>> 1) syscon was specifically designed for global system control registers like
>> this and is fine to use as long as there are no conflicts where 1 bit is of
>> interest to multiple drivers, and there is no such conflict here
>
> No. Syscon has been designed for being lazy.
>
> This is a huge abstraction non-sense. You have to put all the logic of
> dealing with some external register layout in clients drivers,
> including dealing with the different revisions/SoC that are different
> from that aspect, and duplicating that code across all client drivers.
>
>> 2) Maxime's other arguments seem to boil down to it would be nice / prettier
>> to have a specific driver for this, without really proving a hard need for
>> such a driver. But writing such a driver is going to be a lot of work, and
>> we've a ton of other work to do, and as said there is no real need for a
>> separate driver, syscon works fine for this.
>
> Actually, I already wrote some prototype for this. I'll clean this up
> and send it tonight/tomorrow.

Ok, lets see your prototype and then we'll go from there.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-10 11:03                         ` Hans de Goede
@ 2015-03-11  9:13                             ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-11  9:13 UTC (permalink / raw)
  To: Hans de Goede, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
> Hi,
>
> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>> +{
>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>> +       u32 iscr;
>>>>>>> +
>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>> +       iscr &= ~clr;
>>>>>>> +       iscr |= set;
>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>> +
>>>>>>>
>>>>>>
>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>> calling sun4i_usb_phy_update_iscr()
>>
>> right. That would bind the PHY driver and the controller driver and would
>> start creating problems when a different PHY is connected with the
>> controller.
>>>>>
>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>
>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>> using (these pins are not routed to the outside).
>>>>>
>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>> (including non irq capable pins on some designs requiring polling).
>>
>> The polling can still be done in PHY driver and can use the extcon framework
>> to report the status to controller driver no?
>
> Technically the polling can be moved to the phy driver yes, but it is not easy,
> e.g. we only need to poll when we're in otg mode rather then host-only
> or peripheral-only mode, and the mode gets set by the musb driver not phy
> the phy driver. The sunxi musb implementation uses an integrated phy, so it
> is just much easier and more logical to have all control / polling happening
> from a single module rather then from 2 different modules.
>
>>>>>
>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>
>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>> work at all is because the iscr register allows the user to override
>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>> report to the musb core as id and vbus status.
>>>>>
>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>
>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>> {
>>>>>           struct sunxi_glue *glue =
>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>
>>>>>           if (val)
>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>           else
>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>
>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>> val);
>>
>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>> interrupt handler?
>
> No this changes the vbus and id status as seen by the musb core, and the musb
> responds to this, by e.g. starting a session, or when vbus does not get high
> after a session request by reporting a vbus-error interrupt.
>
> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
> pins which are used to monitor the id and vbus status.
>
>
>>>>> }
>>>>>
>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>> {
>>>>>           struct sunxi_glue *glue =
>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>
>>>>>           if (val)
>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>           else
>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>
>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>> val);
>>>>> }
>>>>>
>>>>> I will happily admit that these 2 functions are a better API between the
>>>>> sunxi musb
>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>> sun4i_usb_phy_update_iscr
>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>> functions like
>>>>> the one above, which actually reflect what is happening would indeed be
>>>>> better.
>>>>
>>>> Ok, that would definitely improve things.
>>>>
>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>> driver for various
>>>>> reasons:
>>>>>
>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>> case there are no
>>>>> pins at all.
>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>
>>>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>>>> your second point.
>>>>>
>>>>>   > and why can't there be a high-level
>>>>>> PHY API for this?
>>>>>
>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>> know that
>>>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>>>> consider
>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>
>>>>> If we decide to add bus specific methods, then the question becomes if having
>>>>>
>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>
>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>> specific,
>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>> phy-ops, and
>>>>> 1 doing the sunxi implementation.
>>
>> Please don't do that. We don't want to be bloating phy framework with platform
>> specific hooks.
>
> Right, that was my feeling too. I believe that using sunxi specific phy functions
> here is best given that we're dealing with an otg controller + phy both if which

Using platform specific PHY functions dissolves the very purpose of creating
the PHY framework. We have to find a better way.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-11  9:13                             ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-11  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
> Hi,
>
> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>> +{
>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>> +       u32 iscr;
>>>>>>> +
>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>> +       iscr &= ~clr;
>>>>>>> +       iscr |= set;
>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>> +}
>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>> +
>>>>>>>
>>>>>>
>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>> calling sun4i_usb_phy_update_iscr()
>>
>> right. That would bind the PHY driver and the controller driver and would
>> start creating problems when a different PHY is connected with the
>> controller.
>>>>>
>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>
>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>> using (these pins are not routed to the outside).
>>>>>
>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>> (including non irq capable pins on some designs requiring polling).
>>
>> The polling can still be done in PHY driver and can use the extcon framework
>> to report the status to controller driver no?
>
> Technically the polling can be moved to the phy driver yes, but it is not easy,
> e.g. we only need to poll when we're in otg mode rather then host-only
> or peripheral-only mode, and the mode gets set by the musb driver not phy
> the phy driver. The sunxi musb implementation uses an integrated phy, so it
> is just much easier and more logical to have all control / polling happening
> from a single module rather then from 2 different modules.
>
>>>>>
>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>
>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>> work at all is because the iscr register allows the user to override
>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>> report to the musb core as id and vbus status.
>>>>>
>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>
>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>> {
>>>>>           struct sunxi_glue *glue =
>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>
>>>>>           if (val)
>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>           else
>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>
>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>> val);
>>
>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>> interrupt handler?
>
> No this changes the vbus and id status as seen by the musb core, and the musb
> responds to this, by e.g. starting a session, or when vbus does not get high
> after a session request by reporting a vbus-error interrupt.
>
> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
> pins which are used to monitor the id and vbus status.
>
>
>>>>> }
>>>>>
>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>> {
>>>>>           struct sunxi_glue *glue =
>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>
>>>>>           if (val)
>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>           else
>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>
>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>> val);
>>>>> }
>>>>>
>>>>> I will happily admit that these 2 functions are a better API between the
>>>>> sunxi musb
>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>> sun4i_usb_phy_update_iscr
>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>> functions like
>>>>> the one above, which actually reflect what is happening would indeed be
>>>>> better.
>>>>
>>>> Ok, that would definitely improve things.
>>>>
>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>> driver for various
>>>>> reasons:
>>>>>
>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>> case there are no
>>>>> pins at all.
>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>
>>>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>>>> your second point.
>>>>>
>>>>>   > and why can't there be a high-level
>>>>>> PHY API for this?
>>>>>
>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>> know that
>>>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>>>> consider
>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>
>>>>> If we decide to add bus specific methods, then the question becomes if having
>>>>>
>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>
>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>> specific,
>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>> phy-ops, and
>>>>> 1 doing the sunxi implementation.
>>
>> Please don't do that. We don't want to be bloating phy framework with platform
>> specific hooks.
>
> Right, that was my feeling too. I believe that using sunxi specific phy functions
> here is best given that we're dealing with an otg controller + phy both if which

Using platform specific PHY functions dissolves the very purpose of creating
the PHY framework. We have to find a better way.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-11  9:13                             ` Kishon Vijay Abraham I
@ 2015-03-11 11:39                                 ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-11 11:39 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>> +{
>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>> +       u32 iscr;
>>>>>>>> +
>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>> +       iscr &= ~clr;
>>>>>>>> +       iscr |= set;
>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>> +}
>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>> +
>>>>>>>>
>>>>>>>
>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>
>>> right. That would bind the PHY driver and the controller driver and would
>>> start creating problems when a different PHY is connected with the
>>> controller.
>>>>>>
>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>
>>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>>> using (these pins are not routed to the outside).
>>>>>>
>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>> (including non irq capable pins on some designs requiring polling).
>>>
>>> The polling can still be done in PHY driver and can use the extcon framework
>>> to report the status to controller driver no?
>>
>> Technically the polling can be moved to the phy driver yes, but it is not easy,
>> e.g. we only need to poll when we're in otg mode rather then host-only
>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>> is just much easier and more logical to have all control / polling happening
>> from a single module rather then from 2 different modules.
>>
>>>>>>
>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>
>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>> work at all is because the iscr register allows the user to override
>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>> report to the musb core as id and vbus status.
>>>>>>
>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>
>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>> {
>>>>>>           struct sunxi_glue *glue =
>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>
>>>>>>           if (val)
>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>           else
>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>
>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>> val);
>>>
>>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>>> interrupt handler?
>>
>> No this changes the vbus and id status as seen by the musb core, and the musb
>> responds to this, by e.g. starting a session, or when vbus does not get high
>> after a session request by reporting a vbus-error interrupt.
>>
>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>> pins which are used to monitor the id and vbus status.
>>
>>
>>>>>> }
>>>>>>
>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>> {
>>>>>>           struct sunxi_glue *glue =
>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>
>>>>>>           if (val)
>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>           else
>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>
>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>> val);
>>>>>> }
>>>>>>
>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>> sunxi musb
>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>> sun4i_usb_phy_update_iscr
>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>> functions like
>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>> better.
>>>>>
>>>>> Ok, that would definitely improve things.
>>>>>
>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>> driver for various
>>>>>> reasons:
>>>>>>
>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>> case there are no
>>>>>> pins at all.
>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>
>>>>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>>>>> your second point.
>>>>>>
>>>>>>   > and why can't there be a high-level
>>>>>>> PHY API for this?
>>>>>>
>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>> know that
>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>>>>> consider
>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>
>>>>>> If we decide to add bus specific methods, then the question becomes if having
>>>>>>
>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>
>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>> specific,
>>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>> phy-ops, and
>>>>>> 1 doing the sunxi implementation.
>>>
>>> Please don't do that. We don't want to be bloating phy framework with platform
>>> specific hooks.
>>
>> Right, that was my feeling too. I believe that using sunxi specific phy functions
>> here is best given that we're dealing with an otg controller + phy both if which
>
> Using platform specific PHY functions dissolves the very purpose of creating
> the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at
hand. We're talking about a phy integrated on the same die, as, and closely working
together with the otg controller, so we need some sort of coordination between the
two.

The 2 logical options for coordinatinon are:

1) Add generic phy framework functions for such coordination
  -> Which you've nacked

2) Use platform private functions for this
  -> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
and communicate through that, but AFAIK that is deprecated ...

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-11 11:39                                 ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-11 11:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>> +{
>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>> +       u32 iscr;
>>>>>>>> +
>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>> +       iscr &= ~clr;
>>>>>>>> +       iscr |= set;
>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>> +}
>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>> +
>>>>>>>>
>>>>>>>
>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>
>>> right. That would bind the PHY driver and the controller driver and would
>>> start creating problems when a different PHY is connected with the
>>> controller.
>>>>>>
>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>
>>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>>> using (these pins are not routed to the outside).
>>>>>>
>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>> (including non irq capable pins on some designs requiring polling).
>>>
>>> The polling can still be done in PHY driver and can use the extcon framework
>>> to report the status to controller driver no?
>>
>> Technically the polling can be moved to the phy driver yes, but it is not easy,
>> e.g. we only need to poll when we're in otg mode rather then host-only
>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>> is just much easier and more logical to have all control / polling happening
>> from a single module rather then from 2 different modules.
>>
>>>>>>
>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>
>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>> work at all is because the iscr register allows the user to override
>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>> report to the musb core as id and vbus status.
>>>>>>
>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>
>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>> {
>>>>>>           struct sunxi_glue *glue =
>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>
>>>>>>           if (val)
>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>           else
>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>
>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>> val);
>>>
>>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>>> interrupt handler?
>>
>> No this changes the vbus and id status as seen by the musb core, and the musb
>> responds to this, by e.g. starting a session, or when vbus does not get high
>> after a session request by reporting a vbus-error interrupt.
>>
>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>> pins which are used to monitor the id and vbus status.
>>
>>
>>>>>> }
>>>>>>
>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>> {
>>>>>>           struct sunxi_glue *glue =
>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>
>>>>>>           if (val)
>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>           else
>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>
>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>> val);
>>>>>> }
>>>>>>
>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>> sunxi musb
>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>> sun4i_usb_phy_update_iscr
>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>> functions like
>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>> better.
>>>>>
>>>>> Ok, that would definitely improve things.
>>>>>
>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>> driver for various
>>>>>> reasons:
>>>>>>
>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>> case there are no
>>>>>> pins at all.
>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>
>>>>>> I'll respin the patch set to do things this way as soon as we've agreement on
>>>>>> your second point.
>>>>>>
>>>>>>   > and why can't there be a high-level
>>>>>>> PHY API for this?
>>>>>>
>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>> know that
>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we should
>>>>>> consider
>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>
>>>>>> If we decide to add bus specific methods, then the question becomes if having
>>>>>>
>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>
>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>> specific,
>>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>> phy-ops, and
>>>>>> 1 doing the sunxi implementation.
>>>
>>> Please don't do that. We don't want to be bloating phy framework with platform
>>> specific hooks.
>>
>> Right, that was my feeling too. I believe that using sunxi specific phy functions
>> here is best given that we're dealing with an otg controller + phy both if which
>
> Using platform specific PHY functions dissolves the very purpose of creating
> the PHY framework. We have to find a better way.

"We have to find a better way" is not really a helpful answer to the problem at
hand. We're talking about a phy integrated on the same die, as, and closely working
together with the otg controller, so we need some sort of coordination between the
two.

The 2 logical options for coordinatinon are:

1) Add generic phy framework functions for such coordination
  -> Which you've nacked

2) Use platform private functions for this
  -> Which you are essentially nacking above.

Which leaves us with what as solution exactly ?

I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
and communicate through that, but AFAIK that is deprecated ...

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-11 11:39                                 ` Hans de Goede
@ 2015-03-11 12:50                                     ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-11 12:50 UTC (permalink / raw)
  To: Hans de Goede, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
> Hi,
>
> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>> Hi,
>>>>
>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>> +{
>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>> +       u32 iscr;
>>>>>>>>> +
>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>> +       iscr |= set;
>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>> +}
>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>> +
>>>>>>>>>
>>>>>>>>
>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>
>>>> right. That would bind the PHY driver and the controller driver and would
>>>> start creating problems when a different PHY is connected with the
>>>> controller.
>>>>>>>
>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>
>>>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>>>> using (these pins are not routed to the outside).
>>>>>>>
>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>
>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>> to report the status to controller driver no?
>>>
>>> Technically the polling can be moved to the phy driver yes, but it is not easy,
>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>> is just much easier and more logical to have all control / polling happening
>>> from a single module rather then from 2 different modules.
>>>
>>>>>>>
>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>
>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>> report to the musb core as id and vbus status.
>>>>>>>
>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>
>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>> {
>>>>>>>           struct sunxi_glue *glue =
>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>
>>>>>>>           if (val)
>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>           else
>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>
>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>> val);
>>>>
>>>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>>>> interrupt handler?
>>>
>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>> after a session request by reporting a vbus-error interrupt.
>>>
>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>> pins which are used to monitor the id and vbus status.
>>>
>>>
>>>>>>> }
>>>>>>>
>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>> {
>>>>>>>           struct sunxi_glue *glue =
>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>
>>>>>>>           if (val)
>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>           else
>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>
>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>> val);
>>>>>>> }
>>>>>>>
>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>> sunxi musb
>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>> functions like
>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>> better.
>>>>>>
>>>>>> Ok, that would definitely improve things.
>>>>>>
>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>> driver for various
>>>>>>> reasons:
>>>>>>>
>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>> case there are no
>>>>>>> pins at all.
>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>
>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>> agreement on
>>>>>>> your second point.
>>>>>>>
>>>>>>>   > and why can't there be a high-level
>>>>>>>> PHY API for this?
>>>>>>>
>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>> know that
>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>> should
>>>>>>> consider
>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>
>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>> having
>>>>>>>
>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>
>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>> specific,
>>>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>> phy-ops, and
>>>>>>> 1 doing the sunxi implementation.
>>>>
>>>> Please don't do that. We don't want to be bloating phy framework with platform
>>>> specific hooks.
>>>
>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>> functions
>>> here is best given that we're dealing with an otg controller + phy both if
>>> which
>>
>> Using platform specific PHY functions dissolves the very purpose of creating
>> the PHY framework. We have to find a better way.
>
> "We have to find a better way" is not really a helpful answer to the problem at
> hand. We're talking about a phy integrated on the same die, as, and closely
> working

It's integrated in the same die but it is not within the controller IP. It's
still possible to replace the PHY and have the same controller in the next SoC.
> together with the otg controller, so we need some sort of coordination between the
> two.
>
> The 2 logical options for coordinatinon are:
>
> 1) Add generic phy framework functions for such coordination
>   -> Which you've nacked
>
> 2) Use platform private functions for this
>   -> Which you are essentially nacking above.
>
> Which leaves us with what as solution exactly ?

We could poll on the GPIO in PHY driver to update the iscr register. I think
it's alright to poll on the GPIO in multiple modules for serving it's own
purpose IMHO.
>
> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,

I'm not sure how will that help.

Cheers
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-11 12:50                                     ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-11 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
> Hi,
>
> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>> Hi,
>>>>
>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>> +{
>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>> +       u32 iscr;
>>>>>>>>> +
>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>> +       iscr |= set;
>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>> +}
>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>> +
>>>>>>>>>
>>>>>>>>
>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>
>>>> right. That would bind the PHY driver and the controller driver and would
>>>> start creating problems when a different PHY is connected with the
>>>> controller.
>>>>>>>
>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>
>>>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>>>> using (these pins are not routed to the outside).
>>>>>>>
>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>
>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>> to report the status to controller driver no?
>>>
>>> Technically the polling can be moved to the phy driver yes, but it is not easy,
>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>> is just much easier and more logical to have all control / polling happening
>>> from a single module rather then from 2 different modules.
>>>
>>>>>>>
>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>
>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>> report to the musb core as id and vbus status.
>>>>>>>
>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>
>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>> {
>>>>>>>           struct sunxi_glue *glue =
>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>
>>>>>>>           if (val)
>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>           else
>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>
>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>> val);
>>>>
>>>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>>>> interrupt handler?
>>>
>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>> after a session request by reporting a vbus-error interrupt.
>>>
>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>> pins which are used to monitor the id and vbus status.
>>>
>>>
>>>>>>> }
>>>>>>>
>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>> {
>>>>>>>           struct sunxi_glue *glue =
>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>
>>>>>>>           if (val)
>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>           else
>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>
>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>> val);
>>>>>>> }
>>>>>>>
>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>> sunxi musb
>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>> functions like
>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>> better.
>>>>>>
>>>>>> Ok, that would definitely improve things.
>>>>>>
>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>> driver for various
>>>>>>> reasons:
>>>>>>>
>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>> case there are no
>>>>>>> pins at all.
>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>
>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>> agreement on
>>>>>>> your second point.
>>>>>>>
>>>>>>>   > and why can't there be a high-level
>>>>>>>> PHY API for this?
>>>>>>>
>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>> know that
>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>> should
>>>>>>> consider
>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>
>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>> having
>>>>>>>
>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>
>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>> specific,
>>>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>> phy-ops, and
>>>>>>> 1 doing the sunxi implementation.
>>>>
>>>> Please don't do that. We don't want to be bloating phy framework with platform
>>>> specific hooks.
>>>
>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>> functions
>>> here is best given that we're dealing with an otg controller + phy both if
>>> which
>>
>> Using platform specific PHY functions dissolves the very purpose of creating
>> the PHY framework. We have to find a better way.
>
> "We have to find a better way" is not really a helpful answer to the problem at
> hand. We're talking about a phy integrated on the same die, as, and closely
> working

It's integrated in the same die but it is not within the controller IP. It's
still possible to replace the PHY and have the same controller in the next SoC.
> together with the otg controller, so we need some sort of coordination between the
> two.
>
> The 2 logical options for coordinatinon are:
>
> 1) Add generic phy framework functions for such coordination
>   -> Which you've nacked
>
> 2) Use platform private functions for this
>   -> Which you are essentially nacking above.
>
> Which leaves us with what as solution exactly ?

We could poll on the GPIO in PHY driver to update the iscr register. I think
it's alright to poll on the GPIO in multiple modules for serving it's own
purpose IMHO.
>
> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,

I'm not sure how will that help.

Cheers
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-11 12:50                                     ` Kishon Vijay Abraham I
@ 2015-03-11 13:03                                         ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-11 13:03 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 11-03-15 13:50, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>>> Hi,
>>>>>
>>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>>> +{
>>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>>> +       u32 iscr;
>>>>>>>>>> +
>>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>>> +       iscr |= set;
>>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>>> +}
>>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>>> +
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>>
>>>>> right. That would bind the PHY driver and the controller driver and would
>>>>> start creating problems when a different PHY is connected with the
>>>>> controller.
>>>>>>>>
>>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>>
>>>>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>>>>> using (these pins are not routed to the outside).
>>>>>>>>
>>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>>
>>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>>> to report the status to controller driver no?
>>>>
>>>> Technically the polling can be moved to the phy driver yes, but it is not easy,
>>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>>> is just much easier and more logical to have all control / polling happening
>>>> from a single module rather then from 2 different modules.
>>>>
>>>>>>>>
>>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>>
>>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>>> report to the musb core as id and vbus status.
>>>>>>>>
>>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>>
>>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>>> {
>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>
>>>>>>>>           if (val)
>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>>           else
>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>>
>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>>> val);
>>>>>
>>>>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>>>>> interrupt handler?
>>>>
>>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>>> after a session request by reporting a vbus-error interrupt.
>>>>
>>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>>> pins which are used to monitor the id and vbus status.
>>>>
>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>>> {
>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>
>>>>>>>>           if (val)
>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>>           else
>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>>
>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>>> val);
>>>>>>>> }
>>>>>>>>
>>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>>> sunxi musb
>>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>>> functions like
>>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>>> better.
>>>>>>>
>>>>>>> Ok, that would definitely improve things.
>>>>>>>
>>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>>> driver for various
>>>>>>>> reasons:
>>>>>>>>
>>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>>> case there are no
>>>>>>>> pins at all.
>>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>>
>>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>>> agreement on
>>>>>>>> your second point.
>>>>>>>>
>>>>>>>>   > and why can't there be a high-level
>>>>>>>>> PHY API for this?
>>>>>>>>
>>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>>> know that
>>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>>> should
>>>>>>>> consider
>>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>>
>>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>>> having
>>>>>>>>
>>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>>
>>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>>> specific,
>>>>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>>> phy-ops, and
>>>>>>>> 1 doing the sunxi implementation.
>>>>>
>>>>> Please don't do that. We don't want to be bloating phy framework with platform
>>>>> specific hooks.
>>>>
>>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>>> functions
>>>> here is best given that we're dealing with an otg controller + phy both if
>>>> which
>>>
>>> Using platform specific PHY functions dissolves the very purpose of creating
>>> the PHY framework. We have to find a better way.
>>
>> "We have to find a better way" is not really a helpful answer to the problem at
>> hand. We're talking about a phy integrated on the same die, as, and closely
>> working
>
> It's integrated in the same die but it is not within the controller IP. It's
> still possible to replace the PHY and have the same controller in the next SoC.
>> together with the otg controller, so we need some sort of coordination between the
>> two.
>>
>> The 2 logical options for coordinatinon are:
>>
>> 1) Add generic phy framework functions for such coordination
>>   -> Which you've nacked
>>
>> 2) Use platform private functions for this
>>   -> Which you are essentially nacking above.
>>
>> Which leaves us with what as solution exactly ?
>
> We could poll on the GPIO in PHY driver to update the iscr register. I think
> it's alright to poll on the GPIO in multiple modules for serving it's own
> purpose IMHO.

No, polling in multiple places is just plain and simple wrong, also where-ever
possible we use edge triggered gpio-interrupts for this and having multiple
handlers for the same interrupt is even more wrong.

I'm fine with moving all the polling to the phy driver, but then we need to
have a way to notify the sunxi musb glue about id pin changes.

>> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
>> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
>
> I'm not sure how will that help.

It helps when we move the polling to the phy driver as it has a notification
mechanism for events which we can then use to tell the musb-sunxi glue about
id pin changes.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-11 13:03                                         ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-11 13:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 11-03-15 13:50, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>>> Hi,
>>>>>
>>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>>> +{
>>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>>> +       u32 iscr;
>>>>>>>>>> +
>>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>>> +       iscr |= set;
>>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>>> +}
>>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>>> +
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>>
>>>>> right. That would bind the PHY driver and the controller driver and would
>>>>> start creating problems when a different PHY is connected with the
>>>>> controller.
>>>>>>>>
>>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>>
>>>>>>>> The second use-case is more tricky, for some reasons Allwinner has decided
>>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they are
>>>>>>>> using (these pins are not routed to the outside).
>>>>>>>>
>>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>>
>>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>>> to report the status to controller driver no?
>>>>
>>>> Technically the polling can be moved to the phy driver yes, but it is not easy,
>>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>>> is just much easier and more logical to have all control / polling happening
>>>> from a single module rather then from 2 different modules.
>>>>
>>>>>>>>
>>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>>
>>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>>> and gets this from the usb0-phy iscr register, which reflects the status of
>>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>>> report to the musb core as id and vbus status.
>>>>>>>>
>>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>>
>>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>>> {
>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>
>>>>>>>>           if (val)
>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>>           else
>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>>
>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>>> val);
>>>>>
>>>>> What will writing to this register lead to? call to sunxi_musb_id_vbus_det_irq
>>>>> interrupt handler?
>>>>
>>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>>> after a session request by reporting a vbus-error interrupt.
>>>>
>>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>>> pins which are used to monitor the id and vbus status.
>>>>
>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>>> {
>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>
>>>>>>>>           if (val)
>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>>           else
>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>>
>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>>> val);
>>>>>>>> }
>>>>>>>>
>>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>>> sunxi musb
>>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>>> functions like
>>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>>> better.
>>>>>>>
>>>>>>> Ok, that would definitely improve things.
>>>>>>>
>>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>>> driver for various
>>>>>>>> reasons:
>>>>>>>>
>>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>>> case there are no
>>>>>>>> pins at all.
>>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>>
>>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>>> agreement on
>>>>>>>> your second point.
>>>>>>>>
>>>>>>>>   > and why can't there be a high-level
>>>>>>>>> PHY API for this?
>>>>>>>>
>>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>>> know that
>>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>>> should
>>>>>>>> consider
>>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>>
>>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>>> having
>>>>>>>>
>>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>>
>>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>>> specific,
>>>>>>>> I'm fine with doing this either way. If we want to go the generic phy route
>>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>>> phy-ops, and
>>>>>>>> 1 doing the sunxi implementation.
>>>>>
>>>>> Please don't do that. We don't want to be bloating phy framework with platform
>>>>> specific hooks.
>>>>
>>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>>> functions
>>>> here is best given that we're dealing with an otg controller + phy both if
>>>> which
>>>
>>> Using platform specific PHY functions dissolves the very purpose of creating
>>> the PHY framework. We have to find a better way.
>>
>> "We have to find a better way" is not really a helpful answer to the problem at
>> hand. We're talking about a phy integrated on the same die, as, and closely
>> working
>
> It's integrated in the same die but it is not within the controller IP. It's
> still possible to replace the PHY and have the same controller in the next SoC.
>> together with the otg controller, so we need some sort of coordination between the
>> two.
>>
>> The 2 logical options for coordinatinon are:
>>
>> 1) Add generic phy framework functions for such coordination
>>   -> Which you've nacked
>>
>> 2) Use platform private functions for this
>>   -> Which you are essentially nacking above.
>>
>> Which leaves us with what as solution exactly ?
>
> We could poll on the GPIO in PHY driver to update the iscr register. I think
> it's alright to poll on the GPIO in multiple modules for serving it's own
> purpose IMHO.

No, polling in multiple places is just plain and simple wrong, also where-ever
possible we use edge triggered gpio-interrupts for this and having multiple
handlers for the same interrupt is even more wrong.

I'm fine with moving all the polling to the phy driver, but then we need to
have a way to notify the sunxi musb glue about id pin changes.

>> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
>> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
>
> I'm not sure how will that help.

It helps when we move the polling to the phy driver as it has a notification
mechanism for events which we can then use to tell the musb-sunxi glue about
id pin changes.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-11 13:03                                         ` Hans de Goede
@ 2015-03-11 13:07                                             ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-11 13:07 UTC (permalink / raw)
  To: Hans de Goede, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On Wednesday 11 March 2015 06:33 PM, Hans de Goede wrote:
> Hi,
>
> On 11-03-15 13:50, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>>>> Hi,
>>>>
>>>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>>>> +{
>>>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>>>> +       u32 iscr;
>>>>>>>>>>> +
>>>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>>>> +       iscr |= set;
>>>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>>>> +}
>>>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>>>> +
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>>>
>>>>>> right. That would bind the PHY driver and the controller driver and would
>>>>>> start creating problems when a different PHY is connected with the
>>>>>> controller.
>>>>>>>>>
>>>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>>>
>>>>>>>>> The second use-case is more tricky, for some reasons Allwinner has
>>>>>>>>> decided
>>>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they
>>>>>>>>> are
>>>>>>>>> using (these pins are not routed to the outside).
>>>>>>>>>
>>>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>>>
>>>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>>>> to report the status to controller driver no?
>>>>>
>>>>> Technically the polling can be moved to the phy driver yes, but it is not
>>>>> easy,
>>>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>>>> is just much easier and more logical to have all control / polling happening
>>>>> from a single module rather then from 2 different modules.
>>>>>
>>>>>>>>>
>>>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>>>
>>>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>>>> and gets this from the usb0-phy iscr register, which reflects the
>>>>>>>>> status of
>>>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>>>> report to the musb core as id and vbus status.
>>>>>>>>>
>>>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>>>
>>>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>>>> {
>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>
>>>>>>>>>           if (val)
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>>>           else
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>>>
>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>>>> val);
>>>>>>
>>>>>> What will writing to this register lead to? call to
>>>>>> sunxi_musb_id_vbus_det_irq
>>>>>> interrupt handler?
>>>>>
>>>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>>>> after a session request by reporting a vbus-error interrupt.
>>>>>
>>>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>>>> pins which are used to monitor the id and vbus status.
>>>>>
>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>>>> {
>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>
>>>>>>>>>           if (val)
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>>>           else
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>>>
>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy,
>>>>>>>>> SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>>>> val);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>>>> sunxi musb
>>>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>>>> functions like
>>>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>>>> better.
>>>>>>>>
>>>>>>>> Ok, that would definitely improve things.
>>>>>>>>
>>>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>>>> driver for various
>>>>>>>>> reasons:
>>>>>>>>>
>>>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>>>> case there are no
>>>>>>>>> pins at all.
>>>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>>>
>>>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>>>> agreement on
>>>>>>>>> your second point.
>>>>>>>>>
>>>>>>>>>   > and why can't there be a high-level
>>>>>>>>>> PHY API for this?
>>>>>>>>>
>>>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>>>> know that
>>>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>>>> should
>>>>>>>>> consider
>>>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>>>
>>>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>>>> having
>>>>>>>>>
>>>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>>>
>>>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>>>> specific,
>>>>>>>>> I'm fine with doing this either way. If we want to go the generic phy
>>>>>>>>> route
>>>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>>>> phy-ops, and
>>>>>>>>> 1 doing the sunxi implementation.
>>>>>>
>>>>>> Please don't do that. We don't want to be bloating phy framework with
>>>>>> platform
>>>>>> specific hooks.
>>>>>
>>>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>>>> functions
>>>>> here is best given that we're dealing with an otg controller + phy both if
>>>>> which
>>>>
>>>> Using platform specific PHY functions dissolves the very purpose of creating
>>>> the PHY framework. We have to find a better way.
>>>
>>> "We have to find a better way" is not really a helpful answer to the problem at
>>> hand. We're talking about a phy integrated on the same die, as, and closely
>>> working
>>
>> It's integrated in the same die but it is not within the controller IP. It's
>> still possible to replace the PHY and have the same controller in the next SoC.
>>> together with the otg controller, so we need some sort of coordination
>>> between the
>>> two.
>>>
>>> The 2 logical options for coordinatinon are:
>>>
>>> 1) Add generic phy framework functions for such coordination
>>>   -> Which you've nacked
>>>
>>> 2) Use platform private functions for this
>>>   -> Which you are essentially nacking above.
>>>
>>> Which leaves us with what as solution exactly ?
>>
>> We could poll on the GPIO in PHY driver to update the iscr register. I think
>> it's alright to poll on the GPIO in multiple modules for serving it's own
>> purpose IMHO.
>
> No, polling in multiple places is just plain and simple wrong, also where-ever
> possible we use edge triggered gpio-interrupts for this and having multiple
> handlers for the same interrupt is even more wrong.
>
> I'm fine with moving all the polling to the phy driver, but then we need to
> have a way to notify the sunxi musb glue about id pin changes.

As I mentioned before, we can use extcon framework for it.
>
>>> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
>>> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
>>
>> I'm not sure how will that help.
>
> It helps when we move the polling to the phy driver as it has a notification
> mechanism for events which we can then use to tell the musb-sunxi glue about
> id pin changes.

extcon framework might help here.

Cheers
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-11 13:07                                             ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 88+ messages in thread
From: Kishon Vijay Abraham I @ 2015-03-11 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Wednesday 11 March 2015 06:33 PM, Hans de Goede wrote:
> Hi,
>
> On 11-03-15 13:50, Kishon Vijay Abraham I wrote:
>> Hi,
>>
>> On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>>>> Hi,
>>>>
>>>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>>>> Hi,
>>>>>
>>>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>>>> +{
>>>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>>>> +       u32 iscr;
>>>>>>>>>>> +
>>>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>>>> +       iscr |= set;
>>>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>>>> +}
>>>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>>>> +
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>>>
>>>>>> right. That would bind the PHY driver and the controller driver and would
>>>>>> start creating problems when a different PHY is connected with the
>>>>>> controller.
>>>>>>>>>
>>>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>>>
>>>>>>>>> The second use-case is more tricky, for some reasons Allwinner has
>>>>>>>>> decided
>>>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they
>>>>>>>>> are
>>>>>>>>> using (these pins are not routed to the outside).
>>>>>>>>>
>>>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>>>
>>>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>>>> to report the status to controller driver no?
>>>>>
>>>>> Technically the polling can be moved to the phy driver yes, but it is not
>>>>> easy,
>>>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>>>> is just much easier and more logical to have all control / polling happening
>>>>> from a single module rather then from 2 different modules.
>>>>>
>>>>>>>>>
>>>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>>>
>>>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>>>> and gets this from the usb0-phy iscr register, which reflects the
>>>>>>>>> status of
>>>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>>>> report to the musb core as id and vbus status.
>>>>>>>>>
>>>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>>>
>>>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>>>> {
>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>
>>>>>>>>>           if (val)
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>>>           else
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>>>
>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>>>> val);
>>>>>>
>>>>>> What will writing to this register lead to? call to
>>>>>> sunxi_musb_id_vbus_det_irq
>>>>>> interrupt handler?
>>>>>
>>>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>>>> after a session request by reporting a vbus-error interrupt.
>>>>>
>>>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>>>> pins which are used to monitor the id and vbus status.
>>>>>
>>>>>
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>>>> {
>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>
>>>>>>>>>           if (val)
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>>>           else
>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>>>
>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy,
>>>>>>>>> SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>>>> val);
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>>>> sunxi musb
>>>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>>>> functions like
>>>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>>>> better.
>>>>>>>>
>>>>>>>> Ok, that would definitely improve things.
>>>>>>>>
>>>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>>>> driver for various
>>>>>>>>> reasons:
>>>>>>>>>
>>>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>>>> case there are no
>>>>>>>>> pins at all.
>>>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>>>
>>>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>>>> agreement on
>>>>>>>>> your second point.
>>>>>>>>>
>>>>>>>>>   > and why can't there be a high-level
>>>>>>>>>> PHY API for this?
>>>>>>>>>
>>>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>>>> know that
>>>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>>>> should
>>>>>>>>> consider
>>>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>>>
>>>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>>>> having
>>>>>>>>>
>>>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>>>
>>>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>>>> specific,
>>>>>>>>> I'm fine with doing this either way. If we want to go the generic phy
>>>>>>>>> route
>>>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>>>> phy-ops, and
>>>>>>>>> 1 doing the sunxi implementation.
>>>>>>
>>>>>> Please don't do that. We don't want to be bloating phy framework with
>>>>>> platform
>>>>>> specific hooks.
>>>>>
>>>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>>>> functions
>>>>> here is best given that we're dealing with an otg controller + phy both if
>>>>> which
>>>>
>>>> Using platform specific PHY functions dissolves the very purpose of creating
>>>> the PHY framework. We have to find a better way.
>>>
>>> "We have to find a better way" is not really a helpful answer to the problem at
>>> hand. We're talking about a phy integrated on the same die, as, and closely
>>> working
>>
>> It's integrated in the same die but it is not within the controller IP. It's
>> still possible to replace the PHY and have the same controller in the next SoC.
>>> together with the otg controller, so we need some sort of coordination
>>> between the
>>> two.
>>>
>>> The 2 logical options for coordinatinon are:
>>>
>>> 1) Add generic phy framework functions for such coordination
>>>   -> Which you've nacked
>>>
>>> 2) Use platform private functions for this
>>>   -> Which you are essentially nacking above.
>>>
>>> Which leaves us with what as solution exactly ?
>>
>> We could poll on the GPIO in PHY driver to update the iscr register. I think
>> it's alright to poll on the GPIO in multiple modules for serving it's own
>> purpose IMHO.
>
> No, polling in multiple places is just plain and simple wrong, also where-ever
> possible we use edge triggered gpio-interrupts for this and having multiple
> handlers for the same interrupt is even more wrong.
>
> I'm fine with moving all the polling to the phy driver, but then we need to
> have a way to notify the sunxi musb glue about id pin changes.

As I mentioned before, we can use extcon framework for it.
>
>>> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
>>> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
>>
>> I'm not sure how will that help.
>
> It helps when we move the polling to the phy driver as it has a notification
> mechanism for events which we can then use to tell the musb-sunxi glue about
> id pin changes.

extcon framework might help here.

Cheers
Kishon

^ permalink raw reply	[flat|nested] 88+ messages in thread

* Re: [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
  2015-03-11 13:07                                             ` Kishon Vijay Abraham I
@ 2015-03-11 14:44                                                 ` Hans de Goede
  -1 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-11 14:44 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Arnd Bergmann
  Cc: Felipe Balbi, Maxime Ripard, Chen-Yu Tsai, Roman Byshko,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw

Hi,

On 11-03-15 14:07, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Wednesday 11 March 2015 06:33 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 11-03-15 13:50, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>>>>> Hi,
>>>>>
>>>>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>>>>> +{
>>>>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>>>>> +       u32 iscr;
>>>>>>>>>>>> +
>>>>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>>>>> +       iscr |= set;
>>>>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>>>>> +}
>>>>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>>>>> +
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>>>>
>>>>>>> right. That would bind the PHY driver and the controller driver and would
>>>>>>> start creating problems when a different PHY is connected with the
>>>>>>> controller.
>>>>>>>>>>
>>>>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>>>>
>>>>>>>>>> The second use-case is more tricky, for some reasons Allwinner has
>>>>>>>>>> decided
>>>>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they
>>>>>>>>>> are
>>>>>>>>>> using (these pins are not routed to the outside).
>>>>>>>>>>
>>>>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>>>>
>>>>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>>>>> to report the status to controller driver no?
>>>>>>
>>>>>> Technically the polling can be moved to the phy driver yes, but it is not
>>>>>> easy,
>>>>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>>>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>>>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>>>>> is just much easier and more logical to have all control / polling happening
>>>>>> from a single module rather then from 2 different modules.
>>>>>>
>>>>>>>>>>
>>>>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>>>>
>>>>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>>>>> and gets this from the usb0-phy iscr register, which reflects the
>>>>>>>>>> status of
>>>>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>>>>> report to the musb core as id and vbus status.
>>>>>>>>>>
>>>>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>>>>
>>>>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>>>>> {
>>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>>
>>>>>>>>>>           if (val)
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>>>>           else
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>>>>
>>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>>>>> val);
>>>>>>>
>>>>>>> What will writing to this register lead to? call to
>>>>>>> sunxi_musb_id_vbus_det_irq
>>>>>>> interrupt handler?
>>>>>>
>>>>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>>>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>>>>> after a session request by reporting a vbus-error interrupt.
>>>>>>
>>>>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>>>>> pins which are used to monitor the id and vbus status.
>>>>>>
>>>>>>
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>>>>> {
>>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>>
>>>>>>>>>>           if (val)
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>>>>           else
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>>>>
>>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy,
>>>>>>>>>> SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>>>>> val);
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>>>>> sunxi musb
>>>>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>>>>> functions like
>>>>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>>>>> better.
>>>>>>>>>
>>>>>>>>> Ok, that would definitely improve things.
>>>>>>>>>
>>>>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>>>>> driver for various
>>>>>>>>>> reasons:
>>>>>>>>>>
>>>>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>>>>> case there are no
>>>>>>>>>> pins at all.
>>>>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>>>>
>>>>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>>>>> agreement on
>>>>>>>>>> your second point.
>>>>>>>>>>
>>>>>>>>>>   > and why can't there be a high-level
>>>>>>>>>>> PHY API for this?
>>>>>>>>>>
>>>>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>>>>> know that
>>>>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>>>>> should
>>>>>>>>>> consider
>>>>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>>>>
>>>>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>>>>> having
>>>>>>>>>>
>>>>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>>>>
>>>>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>>>>> specific,
>>>>>>>>>> I'm fine with doing this either way. If we want to go the generic phy
>>>>>>>>>> route
>>>>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>>>>> phy-ops, and
>>>>>>>>>> 1 doing the sunxi implementation.
>>>>>>>
>>>>>>> Please don't do that. We don't want to be bloating phy framework with
>>>>>>> platform
>>>>>>> specific hooks.
>>>>>>
>>>>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>>>>> functions
>>>>>> here is best given that we're dealing with an otg controller + phy both if
>>>>>> which
>>>>>
>>>>> Using platform specific PHY functions dissolves the very purpose of creating
>>>>> the PHY framework. We have to find a better way.
>>>>
>>>> "We have to find a better way" is not really a helpful answer to the problem at
>>>> hand. We're talking about a phy integrated on the same die, as, and closely
>>>> working
>>>
>>> It's integrated in the same die but it is not within the controller IP. It's
>>> still possible to replace the PHY and have the same controller in the next SoC.
>>>> together with the otg controller, so we need some sort of coordination
>>>> between the
>>>> two.
>>>>
>>>> The 2 logical options for coordinatinon are:
>>>>
>>>> 1) Add generic phy framework functions for such coordination
>>>>   -> Which you've nacked
>>>>
>>>> 2) Use platform private functions for this
>>>>   -> Which you are essentially nacking above.
>>>>
>>>> Which leaves us with what as solution exactly ?
>>>
>>> We could poll on the GPIO in PHY driver to update the iscr register. I think
>>> it's alright to poll on the GPIO in multiple modules for serving it's own
>>> purpose IMHO.
>>
>> No, polling in multiple places is just plain and simple wrong, also where-ever
>> possible we use edge triggered gpio-interrupts for this and having multiple
>> handlers for the same interrupt is even more wrong.
>>
>> I'm fine with moving all the polling to the phy driver, but then we need to
>> have a way to notify the sunxi musb glue about id pin changes.
>
> As I mentioned before, we can use extcon framework for it.
>>
>>>> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
>>>> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
>>>
>>> I'm not sure how will that help.
>>
>> It helps when we move the polling to the phy driver as it has a notification
>> mechanism for events which we can then use to tell the musb-sunxi glue about
>> id pin changes.
>
> extcon framework might help here.

Ok, I've taken a look and I see that it is already used for exactly this purpose
in drivers/usb/phy/phy-tahvo.c and drivers/usb/phy/phy-omap-otg.c .

Since I take it that this is the preferred solution for dealing with this, I'll
go and rework my patchset to move the polling to the phy driver and use extcon
to signal the status of the id / vbus det pins to other interested parties.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

* [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register
@ 2015-03-11 14:44                                                 ` Hans de Goede
  0 siblings, 0 replies; 88+ messages in thread
From: Hans de Goede @ 2015-03-11 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 11-03-15 14:07, Kishon Vijay Abraham I wrote:
> Hi,
>
> On Wednesday 11 March 2015 06:33 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 11-03-15 13:50, Kishon Vijay Abraham I wrote:
>>> Hi,
>>>
>>> On Wednesday 11 March 2015 05:09 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 11-03-15 10:13, Kishon Vijay Abraham I wrote:
>>>>> Hi,
>>>>>
>>>>> On Tuesday 10 March 2015 04:33 PM, Hans de Goede wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 10-03-15 11:53, Kishon Vijay Abraham I wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Tuesday 10 March 2015 03:43 PM, Hans de Goede wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 10-03-15 09:57, Arnd Bergmann wrote:
>>>>>>>>> On Tuesday 10 March 2015 09:04:43 Hans de Goede wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> On 09-03-15 22:47, Arnd Bergmann wrote:
>>>>>>>>>>> On Monday 09 March 2015 21:40:15 Hans de Goede wrote:
>>>>>>>>>>>> +void sun4i_usb_phy_update_iscr(struct phy *_phy, u32 clr, u32 set)
>>>>>>>>>>>> +{
>>>>>>>>>>>> +       struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>>>>>>>>>>>> +       struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>>>>>>>>>>>> +       u32 iscr;
>>>>>>>>>>>> +
>>>>>>>>>>>> +       iscr = readl(data->base + REG_ISCR);
>>>>>>>>>>>> +       iscr &= ~clr;
>>>>>>>>>>>> +       iscr |= set;
>>>>>>>>>>>> +       writel(iscr, data->base + REG_ISCR);
>>>>>>>>>>>> +}
>>>>>>>>>>>> +EXPORT_SYMBOL(sun4i_usb_phy_update_iscr);
>>>>>>>>>>>> +
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> I would generally consider this a bad design. What is the purpose of
>>>>>>>>>>> calling sun4i_usb_phy_update_iscr()
>>>>>>>
>>>>>>> right. That would bind the PHY driver and the controller driver and would
>>>>>>> start creating problems when a different PHY is connected with the
>>>>>>> controller.
>>>>>>>>>>
>>>>>>>>>> There are 2 different use cases for this one is to enable the dataline
>>>>>>>>>> pull-ups at driver init and disable them at driver exit, this could /
>>>>>>>>>> should probably be moved to the phy_init / phy_exit code for the usb0 phy
>>>>>>>>>> removing the need to do this from within the sunxi musb glue.
>>>>>>>>>>
>>>>>>>>>> The second use-case is more tricky, for some reasons Allwinner has
>>>>>>>>>> decided
>>>>>>>>>> to not use the dedicated id-detect and vusb-sense pins of the phy they
>>>>>>>>>> are
>>>>>>>>>> using (these pins are not routed to the outside).
>>>>>>>>>>
>>>>>>>>>> Instead id-detect and vusb-sense are done through any $random gpio pins
>>>>>>>>>> (including non irq capable pins on some designs requiring polling).
>>>>>>>
>>>>>>> The polling can still be done in PHY driver and can use the extcon framework
>>>>>>> to report the status to controller driver no?
>>>>>>
>>>>>> Technically the polling can be moved to the phy driver yes, but it is not
>>>>>> easy,
>>>>>> e.g. we only need to poll when we're in otg mode rather then host-only
>>>>>> or peripheral-only mode, and the mode gets set by the musb driver not phy
>>>>>> the phy driver. The sunxi musb implementation uses an integrated phy, so it
>>>>>> is just much easier and more logical to have all control / polling happening
>>>>>> from a single module rather then from 2 different modules.
>>>>>>
>>>>>>>>>>
>>>>>>>>>> But the musb-core still needs to know the status of the id and vbus pins,
>>>>>>>
>>>>>>> musb-core or the musb-glue (musb/sunxi.c in this case)?
>>>>>>>>>> and gets this from the usb0-phy iscr register, which reflects the
>>>>>>>>>> status of
>>>>>>>>>> the not connected dedicated pins of the phy. The reason this can still
>>>>>>>>>> work at all is because the iscr register allows the user to override
>>>>>>>>>> whatever the not connected phy pins are seeing and forcing a value to
>>>>>>>>>> report to the musb core as id and vbus status.
>>>>>>>>>>
>>>>>>>>>> This is done by these 2 functions in the musb sunxi glue:
>>>>>>>>>>
>>>>>>>>>> static void sunxi_musb_force_id(struct musb *musb, u32 val)
>>>>>>>>>> {
>>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>>
>>>>>>>>>>           if (val)
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_HIGH;
>>>>>>>>>>           else
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_ID_LOW;
>>>>>>>>>>
>>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy, SUNXI_ISCR_FORCE_ID_MASK,
>>>>>>>>>> val);
>>>>>>>
>>>>>>> What will writing to this register lead to? call to
>>>>>>> sunxi_musb_id_vbus_det_irq
>>>>>>> interrupt handler?
>>>>>>
>>>>>> No this changes the vbus and id status as seen by the musb core, and the musb
>>>>>> responds to this, by e.g. starting a session, or when vbus does not get high
>>>>>> after a session request by reporting a vbus-error interrupt.
>>>>>>
>>>>>> The sunxi_musb_id_vbus_det_irq handler gets triggered by edges on the gpio
>>>>>> pins which are used to monitor the id and vbus status.
>>>>>>
>>>>>>
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> static void sunxi_musb_force_vbus(struct musb *musb, u32 val)
>>>>>>>>>> {
>>>>>>>>>>           struct sunxi_glue *glue =
>>>>>>>>>> dev_get_drvdata(musb->controller->parent);
>>>>>>>>>>
>>>>>>>>>>           if (val)
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_HIGH;
>>>>>>>>>>           else
>>>>>>>>>>                   val = SUNXI_ISCR_FORCE_VBUS_LOW;
>>>>>>>>>>
>>>>>>>>>>           sun4i_usb_phy_update_iscr(glue->phy,
>>>>>>>>>> SUNXI_ISCR_FORCE_VBUS_MASK,
>>>>>>>>>> val);
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> I will happily admit that these 2 functions are a better API between the
>>>>>>>>>> sunxi musb
>>>>>>>>>> glue and the sunxi usb phy driver. I started with the minimal
>>>>>>>>>> sun4i_usb_phy_update_iscr
>>>>>>>>>> approach as I wanted to keep the API as small as possible, but having 2
>>>>>>>>>> functions like
>>>>>>>>>> the one above, which actually reflect what is happening would indeed be
>>>>>>>>>> better.
>>>>>>>>>
>>>>>>>>> Ok, that would definitely improve things.
>>>>>>>>>
>>>>>>>>>> Note that the polling of the pins cannot (easily) be moved into the phy
>>>>>>>>>> driver for various
>>>>>>>>>> reasons:
>>>>>>>>>>
>>>>>>>>>> 1) It depends on dr_mode, the otg may be used in host only mode in which
>>>>>>>>>> case there are no
>>>>>>>>>> pins at all.
>>>>>>>>>> 2) the musb set_vbus callback needs access to the pins
>>>>>>>>>> 3) When id changes some musb core state changes are necessary.
>>>>>>>>>>
>>>>>>>>>> I'll respin the patch set to do things this way as soon as we've
>>>>>>>>>> agreement on
>>>>>>>>>> your second point.
>>>>>>>>>>
>>>>>>>>>>   > and why can't there be a high-level
>>>>>>>>>>> PHY API for this?
>>>>>>>>>>
>>>>>>>>>> The current generic phy API seems to not have any bus specific methods, I
>>>>>>>>>> know that
>>>>>>>>>> in the long run people want to get rid of struct usb_phy, so maybe we
>>>>>>>>>> should
>>>>>>>>>> consider
>>>>>>>>>> adding bus specific methods to the generic phy API for things like otg.
>>>>>>>>>>
>>>>>>>>>> If we decide to add bus specific methods, then the question becomes if
>>>>>>>>>> having
>>>>>>>>>>
>>>>>>>>>> int phy_usb_set_id_detect(struct phy *phy, bool val);
>>>>>>>>>> int phy_usb_set_vbus_detect(struct phy *phy, bool val);
>>>>>>>>>>
>>>>>>>>>> Functions in the generic phy API is a good idea, or if this is too sunxi
>>>>>>>>>> specific,
>>>>>>>>>> I'm fine with doing this either way. If we want to go the generic phy
>>>>>>>>>> route
>>>>>>>>>> I'll split this in 2 patches, one adding these 2 generic functions &
>>>>>>>>>> phy-ops, and
>>>>>>>>>> 1 doing the sunxi implementation.
>>>>>>>
>>>>>>> Please don't do that. We don't want to be bloating phy framework with
>>>>>>> platform
>>>>>>> specific hooks.
>>>>>>
>>>>>> Right, that was my feeling too. I believe that using sunxi specific phy
>>>>>> functions
>>>>>> here is best given that we're dealing with an otg controller + phy both if
>>>>>> which
>>>>>
>>>>> Using platform specific PHY functions dissolves the very purpose of creating
>>>>> the PHY framework. We have to find a better way.
>>>>
>>>> "We have to find a better way" is not really a helpful answer to the problem at
>>>> hand. We're talking about a phy integrated on the same die, as, and closely
>>>> working
>>>
>>> It's integrated in the same die but it is not within the controller IP. It's
>>> still possible to replace the PHY and have the same controller in the next SoC.
>>>> together with the otg controller, so we need some sort of coordination
>>>> between the
>>>> two.
>>>>
>>>> The 2 logical options for coordinatinon are:
>>>>
>>>> 1) Add generic phy framework functions for such coordination
>>>>   -> Which you've nacked
>>>>
>>>> 2) Use platform private functions for this
>>>>   -> Which you are essentially nacking above.
>>>>
>>>> Which leaves us with what as solution exactly ?
>>>
>>> We could poll on the GPIO in PHY driver to update the iscr register. I think
>>> it's alright to poll on the GPIO in multiple modules for serving it's own
>>> purpose IMHO.
>>
>> No, polling in multiple places is just plain and simple wrong, also where-ever
>> possible we use edge triggered gpio-interrupts for this and having multiple
>> handlers for the same interrupt is even more wrong.
>>
>> I'm fine with moving all the polling to the phy driver, but then we need to
>> have a way to notify the sunxi musb glue about id pin changes.
>
> As I mentioned before, we can use extcon framework for it.
>>
>>>> I could make the phy-sun4i-usb.c driver register a struct usb_phy, as
>>>> drivers/phy/phy-omap-usb2.c and drivers/phy/phy-twl4030-usb.c does,
>>>
>>> I'm not sure how will that help.
>>
>> It helps when we move the polling to the phy driver as it has a notification
>> mechanism for events which we can then use to tell the musb-sunxi glue about
>> id pin changes.
>
> extcon framework might help here.

Ok, I've taken a look and I see that it is already used for exactly this purpose
in drivers/usb/phy/phy-tahvo.c and drivers/usb/phy/phy-omap-otg.c .

Since I take it that this is the preferred solution for dealing with this, I'll
go and rework my patchset to move the polling to the phy driver and use extcon
to signal the status of the id / vbus det pins to other interested parties.

Regards,

Hans

^ permalink raw reply	[flat|nested] 88+ messages in thread

end of thread, other threads:[~2015-03-11 14:44 UTC | newest]

Thread overview: 88+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-09 20:40 [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller Hans de Goede
2015-03-09 20:40 ` Hans de Goede
     [not found] ` <1425933628-9672-1-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-09 20:40   ` [PATCH 01/15] ARM: sunxi: Add register bit definitions for SRAM mapping syscon Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 02/15] phy-sun4i-usb: Add a helper function to update the iscr register Hans de Goede
2015-03-09 20:40     ` Hans de Goede
     [not found]     ` <1425933628-9672-3-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-09 21:47       ` Arnd Bergmann
2015-03-09 21:47         ` Arnd Bergmann
2015-03-10  8:04         ` Hans de Goede
2015-03-10  8:04           ` Hans de Goede
     [not found]           ` <54FEA59B.7020400-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-10  8:57             ` Arnd Bergmann
2015-03-10  8:57               ` Arnd Bergmann
2015-03-10 10:13               ` Hans de Goede
2015-03-10 10:13                 ` Hans de Goede
     [not found]                 ` <54FEC3DD.10108-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-10 10:53                   ` Kishon Vijay Abraham I
2015-03-10 10:53                     ` Kishon Vijay Abraham I
     [not found]                     ` <54FECD30.6080106-l0cyMroinI0@public.gmane.org>
2015-03-10 11:03                       ` Hans de Goede
2015-03-10 11:03                         ` Hans de Goede
     [not found]                         ` <54FECF9F.7020606-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-11  9:13                           ` Kishon Vijay Abraham I
2015-03-11  9:13                             ` Kishon Vijay Abraham I
     [not found]                             ` <55000749.9040606-l0cyMroinI0@public.gmane.org>
2015-03-11 11:39                               ` Hans de Goede
2015-03-11 11:39                                 ` Hans de Goede
     [not found]                                 ` <55002970.8090206-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-11 12:50                                   ` Kishon Vijay Abraham I
2015-03-11 12:50                                     ` Kishon Vijay Abraham I
     [not found]                                     ` <55003A15.2070900-l0cyMroinI0@public.gmane.org>
2015-03-11 13:03                                       ` Hans de Goede
2015-03-11 13:03                                         ` Hans de Goede
     [not found]                                         ` <55003D2B.60502-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-11 13:07                                           ` Kishon Vijay Abraham I
2015-03-11 13:07                                             ` Kishon Vijay Abraham I
     [not found]                                             ` <55003E0D.9040509-l0cyMroinI0@public.gmane.org>
2015-03-11 14:44                                               ` Hans de Goede
2015-03-11 14:44                                                 ` Hans de Goede
2015-03-09 20:40   ` [PATCH 03/15] musb: Make musb_write_rxfun* and musb_write_rxhub* work like their tx versions Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 04/15] musb: Make busctl_offset an io-op rather then a define Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 05/15] musb: Do not use musb_read[b|w] / _write[b|w] wrappers in generic fifo functions Hans de Goede
2015-03-09 20:40     ` Hans de Goede
     [not found]     ` <1425933628-9672-6-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-09 21:50       ` Arnd Bergmann
2015-03-09 21:50         ` Arnd Bergmann
2015-03-10  7:43         ` Hans de Goede
2015-03-10  7:43           ` Hans de Goede
     [not found]           ` <54FEA09A.6040401-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-10  8:50             ` Arnd Bergmann
2015-03-10  8:50               ` Arnd Bergmann
2015-03-10  8:56               ` Hans de Goede
2015-03-10  8:56                 ` Hans de Goede
     [not found]                 ` <54FEB1D4.3080700-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-10 13:43                   ` Arnd Bergmann
2015-03-10 13:43                     ` Arnd Bergmann
2015-03-09 20:40   ` [PATCH 06/15] musb: Fix platform code being unable to override ep access ops Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 07/15] musb: Add support for the Allwinner sunxi musb controller Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 08/15] ARM: dts: sunxi: Add syscon node for controlling SRAM mapping Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 09/15] ARM: dts: sun4i: Add USB Dual Role Controller Hans de Goede
2015-03-09 20:40     ` Hans de Goede
     [not found]     ` <1425933628-9672-10-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-09 23:31       ` Julian Calaby
2015-03-09 23:31         ` [linux-sunxi] " Julian Calaby
     [not found]         ` <CAGRGNgVsf05rtLC2+yOPrbrPV-ceQzPC=ZX1zX+hfNxdC7OX-A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-10  9:10           ` Hans de Goede
2015-03-10  9:10             ` [linux-sunxi] " Hans de Goede
2015-03-09 20:40   ` [PATCH 10/15] ARM: dts: sun5i: " Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 11/15] ARM: dts: sun7i: " Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 12/15] ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825 Hans de Goede
2015-03-09 20:40     ` Hans de Goede
     [not found]     ` <1425933628-9672-13-git-send-email-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-10 15:07       ` Maxime Ripard
2015-03-10 15:07         ` Maxime Ripard
2015-03-10 15:23         ` Hans de Goede
2015-03-10 15:23           ` Hans de Goede
     [not found]           ` <54FF0C5D.3090706-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-10 18:17             ` Maxime Ripard
2015-03-10 18:17               ` Maxime Ripard
2015-03-09 20:40   ` [PATCH 13/15] ARM: dts: sun5i: Enable USB DRC on UTOO P66 Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 14/15] ARM: dts: sun7i: Enable USB DRC on Cubietruck Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 20:40   ` [PATCH 15/15] ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime Hans de Goede
2015-03-09 20:40     ` Hans de Goede
2015-03-09 21:44   ` [PATCH 00/15] musb: Add support for the Allwinner sunxi musb controller Arnd Bergmann
2015-03-09 21:44     ` Arnd Bergmann
2015-03-10  1:46     ` Chen-Yu Tsai
2015-03-10  1:46       ` Chen-Yu Tsai
     [not found]       ` <CAGb2v67GkL9Mdr98Chf6MhMff7CO8OGgfF2kaB3Xcnz=SkMG3w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-10  7:38         ` Hans de Goede
2015-03-10  7:38           ` Hans de Goede
2015-03-10  8:31         ` Arnd Bergmann
2015-03-10  8:31           ` Arnd Bergmann
2015-03-10 17:41   ` Maxime Ripard
2015-03-10 17:41     ` Maxime Ripard
2015-03-10 22:35     ` Hans de Goede
2015-03-10 22:35       ` Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.