All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] SA11x0/PXA pcmcia fixes
@ 2016-08-29 10:02 Russell King - ARM Linux
  2016-08-29 10:03 ` [PATCH 1/3] pcmcia: sa11xx_base: fix reporting of timing information Russell King
                   ` (4 more replies)
  0 siblings, 5 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

Further to the DS suspend/resume fix, here's a few more for SA11x0/PXA.

 drivers/pcmcia/sa11xx_base.c | 8 ++++----
 drivers/pcmcia/soc_common.c  | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 1/3] pcmcia: sa11xx_base: fix reporting of timing information
  2016-08-29 10:02 [PATCH 0/3] SA11x0/PXA pcmcia fixes Russell King - ARM Linux
@ 2016-08-29 10:03 ` Russell King
  2016-08-29 10:03 ` [PATCH 2/3] pcmcia: sa11xx_base: add units to the " Russell King
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

Fix the reporting of the currently programmed timing information.  These
entries have been showing zero due to the clock rate being a factor of
1000 too big.  With this change, we go from:

I/O      : 165 (0)
attribute: 300 (0)
common   : 300 (0)

to:

I/O      : 165 (172)
attribute: 300 (316)
common   : 300 (316)

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa11xx_base.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 9f6ec87b9f9e..af37b7ec1c73 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -144,7 +144,7 @@ static int
 sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
 {
 	struct soc_pcmcia_timing timing;
-	unsigned int clock = clk_get_rate(skt->clk);
+	unsigned int clock = clk_get_rate(skt->clk) / 1000;
 	unsigned long mecr = MECR;
 	char *p = buf;
 
-- 
2.1.0

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

* [PATCH 2/3] pcmcia: sa11xx_base: add units to the timing information
  2016-08-29 10:02 [PATCH 0/3] SA11x0/PXA pcmcia fixes Russell King - ARM Linux
  2016-08-29 10:03 ` [PATCH 1/3] pcmcia: sa11xx_base: fix reporting of timing information Russell King
@ 2016-08-29 10:03 ` Russell King
  2016-08-29 10:03 ` [PATCH 3/3] pcmcia: soc_common: fix SS_STSCHG polarity Russell King
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

Add units to the timing information, so we know that the numbers are
nanoseconds.  The output changes from:

I/O      : 165 (172)
attribute: 300 (316)
common   : 300 (316)

to:

I/O      : 165ns (172ns)
attribute: 300ns (316ns)
common   : 300ns (316ns)

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa11xx_base.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index af37b7ec1c73..48140ac73ed6 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -150,13 +150,13 @@ sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
 
 	soc_common_pcmcia_get_timing(skt, &timing);
 
-	p+=sprintf(p, "I/O      : %u (%u)\n", timing.io,
+	p+=sprintf(p, "I/O      : %uns (%uns)\n", timing.io,
 		   sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr)));
 
-	p+=sprintf(p, "attribute: %u (%u)\n", timing.attr,
+	p+=sprintf(p, "attribute: %uns (%uns)\n", timing.attr,
 		   sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr)));
 
-	p+=sprintf(p, "common   : %u (%u)\n", timing.mem,
+	p+=sprintf(p, "common   : %uns (%uns)\n", timing.mem,
 		   sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr)));
 
 	return p - buf;
-- 
2.1.0

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

* [PATCH 3/3] pcmcia: soc_common: fix SS_STSCHG polarity
  2016-08-29 10:02 [PATCH 0/3] SA11x0/PXA pcmcia fixes Russell King - ARM Linux
  2016-08-29 10:03 ` [PATCH 1/3] pcmcia: sa11xx_base: fix reporting of timing information Russell King
  2016-08-29 10:03 ` [PATCH 2/3] pcmcia: sa11xx_base: add units to the " Russell King
@ 2016-08-29 10:03 ` Russell King
  2016-08-29 10:23   ` Russell King - ARM Linux
  2016-09-06 14:46 ` [PATCH 0/3] SA11x0/PXA pcmcia fixes Russell King - ARM Linux
  4 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

SS_STSCHG should be set for an IO card when the BVD1 signal is asserted
low, not high.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index eed5e9c05353..d5ca760c4eb2 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -235,7 +235,7 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 	stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
 
 	if (skt->cs_state.flags & SS_IOCARD)
-		stat |= state.bvd1 ? SS_STSCHG : 0;
+		stat |= state.bvd1 ? 0 : SS_STSCHG;
 	else {
 		if (state.bvd1 == 0)
 			stat |= SS_BATDEAD;
-- 
2.1.0

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

* [RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)
  2016-08-29 10:02 [PATCH 0/3] SA11x0/PXA pcmcia fixes Russell King - ARM Linux
@ 2016-08-29 10:23   ` Russell King - ARM Linux
  2016-08-29 10:03 ` [PATCH 2/3] pcmcia: sa11xx_base: add units to the " Russell King
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 10:23 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Following on from the PCMCIA fixes, this series reworks GPIO on SA11x0
and PXA platforms.  This is a subset of a larger series, which I'm
splitting up due to its size.  This part contains the base and PCMCIA
updates.  Further updates for IrDA drivers, DMA engine, serial, and
ethernet will follow in time.

Modern gpiolib provides us with a very flexible way to handle hardware
control and status signals without distributing board specifics in
drivers.  Legacy board files are able to describe the relationship
between physical GPIOs to drivers through gpio lookup tables, as well
as their polarity.

Drivers using the gpio descriptor APIs are able to lookup these GPIOs,
which may be optional, and binding to the appropriate GPIO provider.
What's even nicer is that this is forwards compatible with DT.

Several platforms provide "miscellaneous" control and status registers
which are very GPIO-like.  We add a fixed-direction GPIO driver to
gpiolib to support these, where the register address, number of GPIOs,
and their direction are all fixed at initialisation time.  This allows
(eg) the Assabet board control/status register, the Neponset control
and modem signal registers, and Lubbock miscellaneous write register
to be modelled as a set of GPIOs.

This permits us to implement reusable drivers for PCMCIA - we can
get rid of several board specific PCMCIA drivers in favour of a more
generic driver for the SoC.

Over the full series, we have a net increase in kernel LoC of less
than 200 lines, with the following significant changes:

 59 files changed, 1690 insertions(+), 1504 deletions(-)
 rename arch/arm/mach-sa1100/{include/mach => }/cerf.h (66%)
 delete mode 100644 arch/arm/mach-sa1100/include/mach/neponset.h
 rename arch/arm/mach-sa1100/{include/mach => }/nanoengine.h (69%)
 create mode 100644 drivers/gpio/gpio-reg.c
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h
 delete mode 100644 drivers/pcmcia/sa1100_assabet.c
 delete mode 100644 drivers/pcmcia/sa1100_cerf.c
 delete mode 100644 drivers/pcmcia/sa1100_nanoengine.c
 create mode 100644 include/linux/gpio-reg.h
 delete mode 100644 include/linux/platform_data/irda-sa11x0.h
 delete mode 100644 include/linux/sa11x0-dma.h

However, deleting the unused SA-1101.h header file gives is a net
decrease in LoC.

For this series only:

 arch/arm/common/sa1111.c                    | 227 ++++++++++++++++++--------
 arch/arm/include/asm/hardware/sa1111.h      |   4 -
 arch/arm/mach-pxa/Kconfig                   |   1 +
 arch/arm/mach-pxa/lubbock.c                 |  40 ++++-
 arch/arm/mach-sa1100/Kconfig                |   1 +
 arch/arm/mach-sa1100/assabet.c              | 130 +++++++++++++--
 arch/arm/mach-sa1100/cerf.c                 |  18 ++-
 arch/arm/mach-sa1100/clock.c                |   2 +
 arch/arm/mach-sa1100/generic.c              |  14 +-
 arch/arm/mach-sa1100/generic.h              |   3 +
 arch/arm/mach-sa1100/h3xxx.c                |  17 ++
 arch/arm/mach-sa1100/include/mach/assabet.h |   6 -
 arch/arm/mach-sa1100/jornada720.c           |  12 ++
 arch/arm/mach-sa1100/nanoengine.c           |  23 +++
 arch/arm/mach-sa1100/neponset.c             | 172 +++++++++++++-------
 arch/arm/mach-sa1100/shannon.c              |  13 ++
 arch/arm/mach-sa1100/simpad.c               |  12 ++
 drivers/gpio/Kconfig                        |   6 +
 drivers/gpio/Makefile                       |   1 +
 drivers/gpio/gpio-reg.c                     | 139 ++++++++++++++++
 drivers/gpio/gpio-sa1100.c                  | 218 ++++++++++++++++---------
 drivers/pcmcia/Kconfig                      |   5 +
 drivers/pcmcia/Makefile                     |   3 +-
 drivers/pcmcia/max1600.c                    | 119 ++++++++++++++
 drivers/pcmcia/max1600.h                    |  31 ++++
 drivers/pcmcia/sa1100_assabet.c             | 106 -------------
 drivers/pcmcia/sa1100_cerf.c                |  92 -----------
 drivers/pcmcia/sa1100_generic.c             | 129 +++++++++++++--
 drivers/pcmcia/sa1100_generic.h             |   3 -
 drivers/pcmcia/sa1100_h3600.c               |  16 +-
 drivers/pcmcia/sa1100_nanoengine.c          | 133 ----------------
 drivers/pcmcia/sa1100_shannon.c             |  29 +---
 drivers/pcmcia/sa1100_simpad.c              |  16 +-
 drivers/pcmcia/sa1111_generic.h             |   1 +
 drivers/pcmcia/sa1111_jornada720.c          |  81 ++++++----
 drivers/pcmcia/sa1111_lubbock.c             | 110 +++----------
 drivers/pcmcia/sa1111_neponset.c            |  79 +++------
 drivers/pcmcia/soc_common.c                 | 238 +++++++++++++++++++---------
 drivers/pcmcia/soc_common.h                 |  24 ++-
 include/linux/gpio-reg.h                    |  12 ++
 40 files changed, 1400 insertions(+), 886 deletions(-)
 create mode 100644 drivers/gpio/gpio-reg.c
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h
 delete mode 100644 drivers/pcmcia/sa1100_assabet.c
 delete mode 100644 drivers/pcmcia/sa1100_cerf.c
 delete mode 100644 drivers/pcmcia/sa1100_nanoengine.c
 create mode 100644 include/linux/gpio-reg.h

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)
@ 2016-08-29 10:23   ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 10:23 UTC (permalink / raw)
  To: linux-arm-kernel

Following on from the PCMCIA fixes, this series reworks GPIO on SA11x0
and PXA platforms.  This is a subset of a larger series, which I'm
splitting up due to its size.  This part contains the base and PCMCIA
updates.  Further updates for IrDA drivers, DMA engine, serial, and
ethernet will follow in time.

Modern gpiolib provides us with a very flexible way to handle hardware
control and status signals without distributing board specifics in
drivers.  Legacy board files are able to describe the relationship
between physical GPIOs to drivers through gpio lookup tables, as well
as their polarity.

Drivers using the gpio descriptor APIs are able to lookup these GPIOs,
which may be optional, and binding to the appropriate GPIO provider.
What's even nicer is that this is forwards compatible with DT.

Several platforms provide "miscellaneous" control and status registers
which are very GPIO-like.  We add a fixed-direction GPIO driver to
gpiolib to support these, where the register address, number of GPIOs,
and their direction are all fixed at initialisation time.  This allows
(eg) the Assabet board control/status register, the Neponset control
and modem signal registers, and Lubbock miscellaneous write register
to be modelled as a set of GPIOs.

This permits us to implement reusable drivers for PCMCIA - we can
get rid of several board specific PCMCIA drivers in favour of a more
generic driver for the SoC.

Over the full series, we have a net increase in kernel LoC of less
than 200 lines, with the following significant changes:

 59 files changed, 1690 insertions(+), 1504 deletions(-)
 rename arch/arm/mach-sa1100/{include/mach => }/cerf.h (66%)
 delete mode 100644 arch/arm/mach-sa1100/include/mach/neponset.h
 rename arch/arm/mach-sa1100/{include/mach => }/nanoengine.h (69%)
 create mode 100644 drivers/gpio/gpio-reg.c
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h
 delete mode 100644 drivers/pcmcia/sa1100_assabet.c
 delete mode 100644 drivers/pcmcia/sa1100_cerf.c
 delete mode 100644 drivers/pcmcia/sa1100_nanoengine.c
 create mode 100644 include/linux/gpio-reg.h
 delete mode 100644 include/linux/platform_data/irda-sa11x0.h
 delete mode 100644 include/linux/sa11x0-dma.h

However, deleting the unused SA-1101.h header file gives is a net
decrease in LoC.

For this series only:

 arch/arm/common/sa1111.c                    | 227 ++++++++++++++++++--------
 arch/arm/include/asm/hardware/sa1111.h      |   4 -
 arch/arm/mach-pxa/Kconfig                   |   1 +
 arch/arm/mach-pxa/lubbock.c                 |  40 ++++-
 arch/arm/mach-sa1100/Kconfig                |   1 +
 arch/arm/mach-sa1100/assabet.c              | 130 +++++++++++++--
 arch/arm/mach-sa1100/cerf.c                 |  18 ++-
 arch/arm/mach-sa1100/clock.c                |   2 +
 arch/arm/mach-sa1100/generic.c              |  14 +-
 arch/arm/mach-sa1100/generic.h              |   3 +
 arch/arm/mach-sa1100/h3xxx.c                |  17 ++
 arch/arm/mach-sa1100/include/mach/assabet.h |   6 -
 arch/arm/mach-sa1100/jornada720.c           |  12 ++
 arch/arm/mach-sa1100/nanoengine.c           |  23 +++
 arch/arm/mach-sa1100/neponset.c             | 172 +++++++++++++-------
 arch/arm/mach-sa1100/shannon.c              |  13 ++
 arch/arm/mach-sa1100/simpad.c               |  12 ++
 drivers/gpio/Kconfig                        |   6 +
 drivers/gpio/Makefile                       |   1 +
 drivers/gpio/gpio-reg.c                     | 139 ++++++++++++++++
 drivers/gpio/gpio-sa1100.c                  | 218 ++++++++++++++++---------
 drivers/pcmcia/Kconfig                      |   5 +
 drivers/pcmcia/Makefile                     |   3 +-
 drivers/pcmcia/max1600.c                    | 119 ++++++++++++++
 drivers/pcmcia/max1600.h                    |  31 ++++
 drivers/pcmcia/sa1100_assabet.c             | 106 -------------
 drivers/pcmcia/sa1100_cerf.c                |  92 -----------
 drivers/pcmcia/sa1100_generic.c             | 129 +++++++++++++--
 drivers/pcmcia/sa1100_generic.h             |   3 -
 drivers/pcmcia/sa1100_h3600.c               |  16 +-
 drivers/pcmcia/sa1100_nanoengine.c          | 133 ----------------
 drivers/pcmcia/sa1100_shannon.c             |  29 +---
 drivers/pcmcia/sa1100_simpad.c              |  16 +-
 drivers/pcmcia/sa1111_generic.h             |   1 +
 drivers/pcmcia/sa1111_jornada720.c          |  81 ++++++----
 drivers/pcmcia/sa1111_lubbock.c             | 110 +++----------
 drivers/pcmcia/sa1111_neponset.c            |  79 +++------
 drivers/pcmcia/soc_common.c                 | 238 +++++++++++++++++++---------
 drivers/pcmcia/soc_common.h                 |  24 ++-
 include/linux/gpio-reg.h                    |  12 ++
 40 files changed, 1400 insertions(+), 886 deletions(-)
 create mode 100644 drivers/gpio/gpio-reg.c
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h
 delete mode 100644 drivers/pcmcia/sa1100_assabet.c
 delete mode 100644 drivers/pcmcia/sa1100_cerf.c
 delete mode 100644 drivers/pcmcia/sa1100_nanoengine.c
 create mode 100644 include/linux/gpio-reg.h

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 01/33] gpio: sa1100: fix irq probing for ucb1x00
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

ucb1x00 has used IRQ probing since it's dawn to find the GPIO interrupt
that it's connected to.  However, commit 23393d49fb75 ("gpio: kill off
set_irq_flags usage") broke this by disabling IRQ probing on GPIO
interrupts.  Fix this.

Fixes: 23393d49fb75 ("gpio: kill off set_irq_flags usage")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index 0c99e8fb9af3..8d8ee0ebf14c 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -155,7 +155,7 @@ static int sa1100_gpio_irqdomain_map(struct irq_domain *d,
 {
 	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip,
 				 handle_edge_irq);
-	irq_set_noprobe(irq);
+	irq_set_probe(irq);
 
 	return 0;
 }
-- 
2.1.0


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

* [PATCH 01/33] gpio: sa1100: fix irq probing for ucb1x00
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

ucb1x00 has used IRQ probing since it's dawn to find the GPIO interrupt
that it's connected to.  However, commit 23393d49fb75 ("gpio: kill off
set_irq_flags usage") broke this by disabling IRQ probing on GPIO
interrupts.  Fix this.

Fixes: 23393d49fb75 ("gpio: kill off set_irq_flags usage")
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index 0c99e8fb9af3..8d8ee0ebf14c 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -155,7 +155,7 @@ static int sa1100_gpio_irqdomain_map(struct irq_domain *d,
 {
 	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip,
 				 handle_edge_irq);
-	irq_set_noprobe(irq);
+	irq_set_probe(irq);
 
 	return 0;
 }
-- 
2.1.0

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

* [PATCH 02/33] gpio: sa1100: use sa11x0_gpio_set_wake()
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Use sa11x0_gpio_set_wake() to set the PWER register, as provided by
Dmitry some time back.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index 8d8ee0ebf14c..fb9d52a57d78 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/syscore_ops.h>
+#include <soc/sa1100/pwer.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
@@ -73,6 +74,7 @@ static struct gpio_chip sa1100_gpio_chip = {
 static int GPIO_IRQ_rising_edge;
 static int GPIO_IRQ_falling_edge;
 static int GPIO_IRQ_mask;
+static int GPIO_IRQ_wake;
 
 static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
 {
@@ -131,11 +133,14 @@ static void sa1100_gpio_unmask(struct irq_data *d)
 
 static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
 {
-	if (on)
-		PWER |= BIT(d->hwirq);
-	else
-		PWER &= ~BIT(d->hwirq);
-	return 0;
+	int ret = sa11x0_gpio_set_wake(d->hwirq, on);
+	if (!ret) {
+		if (on)
+			GPIO_IRQ_wake |= BIT(d->hwirq);
+		else
+			GPIO_IRQ_wake &= ~BIT(d->hwirq);
+	}
+	return ret;
 }
 
 /*
@@ -201,8 +206,8 @@ static int sa1100_gpio_suspend(void)
 	/*
 	 * Set the appropriate edges for wakeup.
 	 */
-	GRER = PWER & GPIO_IRQ_rising_edge;
-	GFER = PWER & GPIO_IRQ_falling_edge;
+	GRER = GPIO_IRQ_wake & GPIO_IRQ_rising_edge;
+	GFER = GPIO_IRQ_wake & GPIO_IRQ_falling_edge;
 
 	/*
 	 * Clear any pending GPIO interrupts.
-- 
2.1.0


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

* [PATCH 02/33] gpio: sa1100: use sa11x0_gpio_set_wake()
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Use sa11x0_gpio_set_wake() to set the PWER register, as provided by
Dmitry some time back.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index 8d8ee0ebf14c..fb9d52a57d78 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/io.h>
 #include <linux/syscore_ops.h>
+#include <soc/sa1100/pwer.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
@@ -73,6 +74,7 @@ static struct gpio_chip sa1100_gpio_chip = {
 static int GPIO_IRQ_rising_edge;
 static int GPIO_IRQ_falling_edge;
 static int GPIO_IRQ_mask;
+static int GPIO_IRQ_wake;
 
 static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
 {
@@ -131,11 +133,14 @@ static void sa1100_gpio_unmask(struct irq_data *d)
 
 static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
 {
-	if (on)
-		PWER |= BIT(d->hwirq);
-	else
-		PWER &= ~BIT(d->hwirq);
-	return 0;
+	int ret = sa11x0_gpio_set_wake(d->hwirq, on);
+	if (!ret) {
+		if (on)
+			GPIO_IRQ_wake |= BIT(d->hwirq);
+		else
+			GPIO_IRQ_wake &= ~BIT(d->hwirq);
+	}
+	return ret;
 }
 
 /*
@@ -201,8 +206,8 @@ static int sa1100_gpio_suspend(void)
 	/*
 	 * Set the appropriate edges for wakeup.
 	 */
-	GRER = PWER & GPIO_IRQ_rising_edge;
-	GFER = PWER & GPIO_IRQ_falling_edge;
+	GRER = GPIO_IRQ_wake & GPIO_IRQ_rising_edge;
+	GFER = GPIO_IRQ_wake & GPIO_IRQ_falling_edge;
 
 	/*
 	 * Clear any pending GPIO interrupts.
-- 
2.1.0

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

* [PATCH 03/33] gpio: sa1100: convert to use IO accessors
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 199 ++++++++++++++++++++++++++++-----------------
 1 file changed, 124 insertions(+), 75 deletions(-)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index fb9d52a57d78..bad0169524c9 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -16,54 +16,85 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+struct sa1100_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem *membase;
+	int irqbase;
+	u32 irqmask;
+	u32 irqrising;
+	u32 irqfalling;
+	u32 irqwake;
+};
+
+#define sa1100_gpio_chip(x) container_of(x, struct sa1100_gpio_chip, chip)
+
+enum {
+	R_GPLR = 0x00,
+	R_GPDR = 0x04,
+	R_GPSR = 0x08,
+	R_GPCR = 0x0c,
+	R_GRER = 0x10,
+	R_GFER = 0x14,
+	R_GEDR = 0x18,
+	R_GAFR = 0x1c,
+};
+
 static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	return !!(GPLR & GPIO_GPIO(offset));
+	return readl_relaxed(sa1100_gpio_chip(chip)->membase + R_GPLR) &
+		BIT(offset);
 }
 
 static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
-	if (value)
-		GPSR = GPIO_GPIO(offset);
-	else
-		GPCR = GPIO_GPIO(offset);
+	int reg = value ? R_GPSR : R_GPCR;
+
+	writel_relaxed(BIT(offset), sa1100_gpio_chip(chip)->membase + reg);
 }
 
 static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
 {
+	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	GPDR &= ~GPIO_GPIO(offset);
+	writel_relaxed(readl_relaxed(gpdr) & ~BIT(offset), gpdr);
 	local_irq_restore(flags);
+
 	return 0;
 }
 
 static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value)
 {
+	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
 	unsigned long flags;
 
 	local_irq_save(flags);
 	sa1100_gpio_set(chip, offset, value);
-	GPDR |= GPIO_GPIO(offset);
+	writel_relaxed(readl_relaxed(gpdr) | BIT(offset), gpdr);
 	local_irq_restore(flags);
+
 	return 0;
 }
 
 static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-	return IRQ_GPIO0 + offset;
+	return sa1100_gpio_chip(chip)->irqbase + offset;
 }
 
-static struct gpio_chip sa1100_gpio_chip = {
-	.label			= "gpio",
-	.direction_input	= sa1100_direction_input,
-	.direction_output	= sa1100_direction_output,
-	.set			= sa1100_gpio_set,
-	.get			= sa1100_gpio_get,
-	.to_irq			= sa1100_to_irq,
-	.base			= 0,
-	.ngpio			= GPIO_MAX + 1,
+static struct sa1100_gpio_chip sa1100_gpio_chip = {
+	.chip = {
+		.label			= "gpio",
+		.direction_input	= sa1100_direction_input,
+		.direction_output	= sa1100_direction_output,
+		.set			= sa1100_gpio_set,
+		.get			= sa1100_gpio_get,
+		.to_irq			= sa1100_to_irq,
+		.base			= 0,
+		.ngpio			= GPIO_MAX + 1,
+	},
+	.membase = (void *)&GPLR,
+	.irqbase = IRQ_GPIO0,
 };
 
 /*
@@ -71,34 +102,39 @@ static struct gpio_chip sa1100_gpio_chip = {
  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
  * Use this instead of directly setting GRER/GFER.
  */
-static int GPIO_IRQ_rising_edge;
-static int GPIO_IRQ_falling_edge;
-static int GPIO_IRQ_mask;
-static int GPIO_IRQ_wake;
+static void sa1100_update_edge_regs(struct sa1100_gpio_chip *sgc)
+{
+	void *base = sgc->membase;
+	u32 grer, gfer;
+
+	grer = sgc->irqrising & sgc->irqmask;
+	gfer = sgc->irqfalling & sgc->irqmask;
+
+	writel_relaxed(grer, base + R_GRER);
+	writel_relaxed(gfer, base + R_GFER);
+}
 
 static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
 {
-	unsigned int mask;
-
-	mask = BIT(d->hwirq);
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
+	unsigned int mask = BIT(d->hwirq);
 
 	if (type == IRQ_TYPE_PROBE) {
-		if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
+		if ((sgc->irqrising | sgc->irqfalling) & mask)
 			return 0;
 		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
 	}
 
 	if (type & IRQ_TYPE_EDGE_RISING)
-		GPIO_IRQ_rising_edge |= mask;
+		sgc->irqrising |= mask;
 	else
-		GPIO_IRQ_rising_edge &= ~mask;
+		sgc->irqrising &= ~mask;
 	if (type & IRQ_TYPE_EDGE_FALLING)
-		GPIO_IRQ_falling_edge |= mask;
+		sgc->irqfalling |= mask;
 	else
-		GPIO_IRQ_falling_edge &= ~mask;
+		sgc->irqfalling &= ~mask;
 
-	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
-	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+	sa1100_update_edge_regs(sgc);
 
 	return 0;
 }
@@ -108,37 +144,40 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
  */
 static void sa1100_gpio_ack(struct irq_data *d)
 {
-	GEDR = BIT(d->hwirq);
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
+
+	writel_relaxed(BIT(d->hwirq), sgc->membase + R_GEDR);
 }
 
 static void sa1100_gpio_mask(struct irq_data *d)
 {
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
 	unsigned int mask = BIT(d->hwirq);
 
-	GPIO_IRQ_mask &= ~mask;
+	sgc->irqmask &= ~mask;
 
-	GRER &= ~mask;
-	GFER &= ~mask;
+	sa1100_update_edge_regs(sgc);
 }
 
 static void sa1100_gpio_unmask(struct irq_data *d)
 {
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
 	unsigned int mask = BIT(d->hwirq);
 
-	GPIO_IRQ_mask |= mask;
+	sgc->irqmask |= mask;
 
-	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
-	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+	sa1100_update_edge_regs(sgc);
 }
 
 static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
 {
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
 	int ret = sa11x0_gpio_set_wake(d->hwirq, on);
 	if (!ret) {
 		if (on)
-			GPIO_IRQ_wake |= BIT(d->hwirq);
+			sgc->irqwake |= BIT(d->hwirq);
 		else
-			GPIO_IRQ_wake &= ~BIT(d->hwirq);
+			sgc->irqwake &= ~BIT(d->hwirq);
 	}
 	return ret;
 }
@@ -158,8 +197,10 @@ static struct irq_chip sa1100_gpio_irq_chip = {
 static int sa1100_gpio_irqdomain_map(struct irq_domain *d,
 		unsigned int irq, irq_hw_number_t hwirq)
 {
-	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip,
-				 handle_edge_irq);
+	struct sa1100_gpio_chip *sgc = d->host_data;
+
+	irq_set_chip_data(irq, sgc);
+	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, handle_edge_irq);
 	irq_set_probe(irq);
 
 	return 0;
@@ -179,17 +220,19 @@ static struct irq_domain *sa1100_gpio_irqdomain;
  */
 static void sa1100_gpio_handler(struct irq_desc *desc)
 {
+	struct sa1100_gpio_chip *sgc = irq_desc_get_handler_data(desc);
 	unsigned int irq, mask;
+	void __iomem *gedr = sgc->membase + R_GEDR;
 
-	mask = GEDR;
+	mask = readl_relaxed(gedr);
 	do {
 		/*
 		 * clear down all currently active IRQ sources.
 		 * We will be processing them all.
 		 */
-		GEDR = mask;
+		writel_relaxed(mask, gedr);
 
-		irq = IRQ_GPIO0;
+		irq = sgc->irqbase;
 		do {
 			if (mask & 1)
 				generic_handle_irq(irq);
@@ -197,30 +240,32 @@ static void sa1100_gpio_handler(struct irq_desc *desc)
 			irq++;
 		} while (mask);
 
-		mask = GEDR;
+		mask = readl_relaxed(gedr);
 	} while (mask);
 }
 
 static int sa1100_gpio_suspend(void)
 {
+	struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip;
+
 	/*
 	 * Set the appropriate edges for wakeup.
 	 */
-	GRER = GPIO_IRQ_wake & GPIO_IRQ_rising_edge;
-	GFER = GPIO_IRQ_wake & GPIO_IRQ_falling_edge;
+	writel_relaxed(sgc->irqwake & sgc->irqrising, sgc->membase + R_GRER);
+	writel_relaxed(sgc->irqwake & sgc->irqfalling, sgc->membase + R_GFER);
 
 	/*
 	 * Clear any pending GPIO interrupts.
 	 */
-	GEDR = GEDR;
+	writel_relaxed(readl_relaxed(sgc->membase + R_GEDR),
+		       sgc->membase + R_GEDR);
 
 	return 0;
 }
 
 static void sa1100_gpio_resume(void)
 {
-	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
-	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+	sa1100_update_edge_regs(&sa1100_gpio_chip);
 }
 
 static struct syscore_ops sa1100_gpio_syscore_ops = {
@@ -236,36 +281,40 @@ static int __init sa1100_gpio_init_devicefs(void)
 
 device_initcall(sa1100_gpio_init_devicefs);
 
+static const int sa1100_gpio_irqs[] __initconst = {
+	/* Install handlers for GPIO 0-10 edge detect interrupts */
+	IRQ_GPIO0_SC,
+	IRQ_GPIO1_SC,
+	IRQ_GPIO2_SC,
+	IRQ_GPIO3_SC,
+	IRQ_GPIO4_SC,
+	IRQ_GPIO5_SC,
+	IRQ_GPIO6_SC,
+	IRQ_GPIO7_SC,
+	IRQ_GPIO8_SC,
+	IRQ_GPIO9_SC,
+	IRQ_GPIO10_SC,
+	/* Install handler for GPIO 11-27 edge detect interrupts */
+	IRQ_GPIO11_27,
+};
+
 void __init sa1100_init_gpio(void)
 {
+	struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip;
+	int i;
+
 	/* clear all GPIO edge detects */
-	GFER = 0;
-	GRER = 0;
-	GEDR = -1;
+	writel_relaxed(0, sgc->membase + R_GFER);
+	writel_relaxed(0, sgc->membase + R_GRER);
+	writel_relaxed(-1, sgc->membase + R_GEDR);
 
-	gpiochip_add_data(&sa1100_gpio_chip, NULL);
+	gpiochip_add_data(&sa1100_gpio_chip.chip, NULL);
 
 	sa1100_gpio_irqdomain = irq_domain_add_simple(NULL,
 			28, IRQ_GPIO0,
-			&sa1100_gpio_irqdomain_ops, NULL);
-
-	/*
-	 * Install handlers for GPIO 0-10 edge detect interrupts
-	 */
-	irq_set_chained_handler(IRQ_GPIO0_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO1_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO2_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO3_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO4_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO5_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO6_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO7_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO8_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO9_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO10_SC, sa1100_gpio_handler);
-	/*
-	 * Install handler for GPIO 11-27 edge detect interrupts
-	 */
-	irq_set_chained_handler(IRQ_GPIO11_27, sa1100_gpio_handler);
+			&sa1100_gpio_irqdomain_ops, sgc);
 
+	for (i = 0; i < ARRAY_SIZE(sa1100_gpio_irqs); i++)
+		irq_set_chained_handler_and_data(sa1100_gpio_irqs[i],
+						 sa1100_gpio_handler, sgc);
 }
-- 
2.1.0


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

* [PATCH 03/33] gpio: sa1100: convert to use IO accessors
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 199 ++++++++++++++++++++++++++++-----------------
 1 file changed, 124 insertions(+), 75 deletions(-)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index fb9d52a57d78..bad0169524c9 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -16,54 +16,85 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+struct sa1100_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem *membase;
+	int irqbase;
+	u32 irqmask;
+	u32 irqrising;
+	u32 irqfalling;
+	u32 irqwake;
+};
+
+#define sa1100_gpio_chip(x) container_of(x, struct sa1100_gpio_chip, chip)
+
+enum {
+	R_GPLR = 0x00,
+	R_GPDR = 0x04,
+	R_GPSR = 0x08,
+	R_GPCR = 0x0c,
+	R_GRER = 0x10,
+	R_GFER = 0x14,
+	R_GEDR = 0x18,
+	R_GAFR = 0x1c,
+};
+
 static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	return !!(GPLR & GPIO_GPIO(offset));
+	return readl_relaxed(sa1100_gpio_chip(chip)->membase + R_GPLR) &
+		BIT(offset);
 }
 
 static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
-	if (value)
-		GPSR = GPIO_GPIO(offset);
-	else
-		GPCR = GPIO_GPIO(offset);
+	int reg = value ? R_GPSR : R_GPCR;
+
+	writel_relaxed(BIT(offset), sa1100_gpio_chip(chip)->membase + reg);
 }
 
 static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
 {
+	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
 	unsigned long flags;
 
 	local_irq_save(flags);
-	GPDR &= ~GPIO_GPIO(offset);
+	writel_relaxed(readl_relaxed(gpdr) & ~BIT(offset), gpdr);
 	local_irq_restore(flags);
+
 	return 0;
 }
 
 static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value)
 {
+	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
 	unsigned long flags;
 
 	local_irq_save(flags);
 	sa1100_gpio_set(chip, offset, value);
-	GPDR |= GPIO_GPIO(offset);
+	writel_relaxed(readl_relaxed(gpdr) | BIT(offset), gpdr);
 	local_irq_restore(flags);
+
 	return 0;
 }
 
 static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-	return IRQ_GPIO0 + offset;
+	return sa1100_gpio_chip(chip)->irqbase + offset;
 }
 
-static struct gpio_chip sa1100_gpio_chip = {
-	.label			= "gpio",
-	.direction_input	= sa1100_direction_input,
-	.direction_output	= sa1100_direction_output,
-	.set			= sa1100_gpio_set,
-	.get			= sa1100_gpio_get,
-	.to_irq			= sa1100_to_irq,
-	.base			= 0,
-	.ngpio			= GPIO_MAX + 1,
+static struct sa1100_gpio_chip sa1100_gpio_chip = {
+	.chip = {
+		.label			= "gpio",
+		.direction_input	= sa1100_direction_input,
+		.direction_output	= sa1100_direction_output,
+		.set			= sa1100_gpio_set,
+		.get			= sa1100_gpio_get,
+		.to_irq			= sa1100_to_irq,
+		.base			= 0,
+		.ngpio			= GPIO_MAX + 1,
+	},
+	.membase = (void *)&GPLR,
+	.irqbase = IRQ_GPIO0,
 };
 
 /*
@@ -71,34 +102,39 @@ static struct gpio_chip sa1100_gpio_chip = {
  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
  * Use this instead of directly setting GRER/GFER.
  */
-static int GPIO_IRQ_rising_edge;
-static int GPIO_IRQ_falling_edge;
-static int GPIO_IRQ_mask;
-static int GPIO_IRQ_wake;
+static void sa1100_update_edge_regs(struct sa1100_gpio_chip *sgc)
+{
+	void *base = sgc->membase;
+	u32 grer, gfer;
+
+	grer = sgc->irqrising & sgc->irqmask;
+	gfer = sgc->irqfalling & sgc->irqmask;
+
+	writel_relaxed(grer, base + R_GRER);
+	writel_relaxed(gfer, base + R_GFER);
+}
 
 static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
 {
-	unsigned int mask;
-
-	mask = BIT(d->hwirq);
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
+	unsigned int mask = BIT(d->hwirq);
 
 	if (type == IRQ_TYPE_PROBE) {
-		if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
+		if ((sgc->irqrising | sgc->irqfalling) & mask)
 			return 0;
 		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
 	}
 
 	if (type & IRQ_TYPE_EDGE_RISING)
-		GPIO_IRQ_rising_edge |= mask;
+		sgc->irqrising |= mask;
 	else
-		GPIO_IRQ_rising_edge &= ~mask;
+		sgc->irqrising &= ~mask;
 	if (type & IRQ_TYPE_EDGE_FALLING)
-		GPIO_IRQ_falling_edge |= mask;
+		sgc->irqfalling |= mask;
 	else
-		GPIO_IRQ_falling_edge &= ~mask;
+		sgc->irqfalling &= ~mask;
 
-	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
-	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+	sa1100_update_edge_regs(sgc);
 
 	return 0;
 }
@@ -108,37 +144,40 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
  */
 static void sa1100_gpio_ack(struct irq_data *d)
 {
-	GEDR = BIT(d->hwirq);
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
+
+	writel_relaxed(BIT(d->hwirq), sgc->membase + R_GEDR);
 }
 
 static void sa1100_gpio_mask(struct irq_data *d)
 {
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
 	unsigned int mask = BIT(d->hwirq);
 
-	GPIO_IRQ_mask &= ~mask;
+	sgc->irqmask &= ~mask;
 
-	GRER &= ~mask;
-	GFER &= ~mask;
+	sa1100_update_edge_regs(sgc);
 }
 
 static void sa1100_gpio_unmask(struct irq_data *d)
 {
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
 	unsigned int mask = BIT(d->hwirq);
 
-	GPIO_IRQ_mask |= mask;
+	sgc->irqmask |= mask;
 
-	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
-	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+	sa1100_update_edge_regs(sgc);
 }
 
 static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
 {
+	struct sa1100_gpio_chip *sgc = irq_data_get_irq_chip_data(d);
 	int ret = sa11x0_gpio_set_wake(d->hwirq, on);
 	if (!ret) {
 		if (on)
-			GPIO_IRQ_wake |= BIT(d->hwirq);
+			sgc->irqwake |= BIT(d->hwirq);
 		else
-			GPIO_IRQ_wake &= ~BIT(d->hwirq);
+			sgc->irqwake &= ~BIT(d->hwirq);
 	}
 	return ret;
 }
@@ -158,8 +197,10 @@ static struct irq_chip sa1100_gpio_irq_chip = {
 static int sa1100_gpio_irqdomain_map(struct irq_domain *d,
 		unsigned int irq, irq_hw_number_t hwirq)
 {
-	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip,
-				 handle_edge_irq);
+	struct sa1100_gpio_chip *sgc = d->host_data;
+
+	irq_set_chip_data(irq, sgc);
+	irq_set_chip_and_handler(irq, &sa1100_gpio_irq_chip, handle_edge_irq);
 	irq_set_probe(irq);
 
 	return 0;
@@ -179,17 +220,19 @@ static struct irq_domain *sa1100_gpio_irqdomain;
  */
 static void sa1100_gpio_handler(struct irq_desc *desc)
 {
+	struct sa1100_gpio_chip *sgc = irq_desc_get_handler_data(desc);
 	unsigned int irq, mask;
+	void __iomem *gedr = sgc->membase + R_GEDR;
 
-	mask = GEDR;
+	mask = readl_relaxed(gedr);
 	do {
 		/*
 		 * clear down all currently active IRQ sources.
 		 * We will be processing them all.
 		 */
-		GEDR = mask;
+		writel_relaxed(mask, gedr);
 
-		irq = IRQ_GPIO0;
+		irq = sgc->irqbase;
 		do {
 			if (mask & 1)
 				generic_handle_irq(irq);
@@ -197,30 +240,32 @@ static void sa1100_gpio_handler(struct irq_desc *desc)
 			irq++;
 		} while (mask);
 
-		mask = GEDR;
+		mask = readl_relaxed(gedr);
 	} while (mask);
 }
 
 static int sa1100_gpio_suspend(void)
 {
+	struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip;
+
 	/*
 	 * Set the appropriate edges for wakeup.
 	 */
-	GRER = GPIO_IRQ_wake & GPIO_IRQ_rising_edge;
-	GFER = GPIO_IRQ_wake & GPIO_IRQ_falling_edge;
+	writel_relaxed(sgc->irqwake & sgc->irqrising, sgc->membase + R_GRER);
+	writel_relaxed(sgc->irqwake & sgc->irqfalling, sgc->membase + R_GFER);
 
 	/*
 	 * Clear any pending GPIO interrupts.
 	 */
-	GEDR = GEDR;
+	writel_relaxed(readl_relaxed(sgc->membase + R_GEDR),
+		       sgc->membase + R_GEDR);
 
 	return 0;
 }
 
 static void sa1100_gpio_resume(void)
 {
-	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
-	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+	sa1100_update_edge_regs(&sa1100_gpio_chip);
 }
 
 static struct syscore_ops sa1100_gpio_syscore_ops = {
@@ -236,36 +281,40 @@ static int __init sa1100_gpio_init_devicefs(void)
 
 device_initcall(sa1100_gpio_init_devicefs);
 
+static const int sa1100_gpio_irqs[] __initconst = {
+	/* Install handlers for GPIO 0-10 edge detect interrupts */
+	IRQ_GPIO0_SC,
+	IRQ_GPIO1_SC,
+	IRQ_GPIO2_SC,
+	IRQ_GPIO3_SC,
+	IRQ_GPIO4_SC,
+	IRQ_GPIO5_SC,
+	IRQ_GPIO6_SC,
+	IRQ_GPIO7_SC,
+	IRQ_GPIO8_SC,
+	IRQ_GPIO9_SC,
+	IRQ_GPIO10_SC,
+	/* Install handler for GPIO 11-27 edge detect interrupts */
+	IRQ_GPIO11_27,
+};
+
 void __init sa1100_init_gpio(void)
 {
+	struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip;
+	int i;
+
 	/* clear all GPIO edge detects */
-	GFER = 0;
-	GRER = 0;
-	GEDR = -1;
+	writel_relaxed(0, sgc->membase + R_GFER);
+	writel_relaxed(0, sgc->membase + R_GRER);
+	writel_relaxed(-1, sgc->membase + R_GEDR);
 
-	gpiochip_add_data(&sa1100_gpio_chip, NULL);
+	gpiochip_add_data(&sa1100_gpio_chip.chip, NULL);
 
 	sa1100_gpio_irqdomain = irq_domain_add_simple(NULL,
 			28, IRQ_GPIO0,
-			&sa1100_gpio_irqdomain_ops, NULL);
-
-	/*
-	 * Install handlers for GPIO 0-10 edge detect interrupts
-	 */
-	irq_set_chained_handler(IRQ_GPIO0_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO1_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO2_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO3_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO4_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO5_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO6_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO7_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO8_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO9_SC, sa1100_gpio_handler);
-	irq_set_chained_handler(IRQ_GPIO10_SC, sa1100_gpio_handler);
-	/*
-	 * Install handler for GPIO 11-27 edge detect interrupts
-	 */
-	irq_set_chained_handler(IRQ_GPIO11_27, sa1100_gpio_handler);
+			&sa1100_gpio_irqdomain_ops, sgc);
 
+	for (i = 0; i < ARRAY_SIZE(sa1100_gpio_irqs); i++)
+		irq_set_chained_handler_and_data(sa1100_gpio_irqs[i],
+						 sa1100_gpio_handler, sgc);
 }
-- 
2.1.0

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

* [PATCH 04/33] gpio: sa1100: implement get_direction method
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Allow gpiolib to read back the current IO direction configuration by
implementing the .get_direction callback.  This, in part, allows
debugfs to report the complete true hardware state rather than the
software state.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index bad0169524c9..249f433aa62d 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -52,6 +52,13 @@ static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 	writel_relaxed(BIT(offset), sa1100_gpio_chip(chip)->membase + reg);
 }
 
+static int sa1100_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
+
+	return !(readl_relaxed(gpdr) & BIT(offset));
+}
+
 static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
@@ -85,6 +92,7 @@ static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
 static struct sa1100_gpio_chip sa1100_gpio_chip = {
 	.chip = {
 		.label			= "gpio",
+		.get_direction		= sa1100_get_direction,
 		.direction_input	= sa1100_direction_input,
 		.direction_output	= sa1100_direction_output,
 		.set			= sa1100_gpio_set,
-- 
2.1.0


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

* [PATCH 04/33] gpio: sa1100: implement get_direction method
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Allow gpiolib to read back the current IO direction configuration by
implementing the .get_direction callback.  This, in part, allows
debugfs to report the complete true hardware state rather than the
software state.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/gpio-sa1100.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index bad0169524c9..249f433aa62d 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -52,6 +52,13 @@ static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 	writel_relaxed(BIT(offset), sa1100_gpio_chip(chip)->membase + reg);
 }
 
+static int sa1100_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
+
+	return !(readl_relaxed(gpdr) & BIT(offset));
+}
+
 static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	void __iomem *gpdr = sa1100_gpio_chip(chip)->membase + R_GPDR;
@@ -85,6 +92,7 @@ static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
 static struct sa1100_gpio_chip sa1100_gpio_chip = {
 	.chip = {
 		.label			= "gpio",
+		.get_direction		= sa1100_get_direction,
 		.direction_input	= sa1100_direction_input,
 		.direction_output	= sa1100_direction_output,
 		.set			= sa1100_gpio_set,
-- 
2.1.0

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a simple, generic, single register fixed-direction GPIO driver.
This is able to support a single register where a fixed number of
bits are used for input and a fixed number of bits used for output.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/Kconfig     |   6 ++
 drivers/gpio/Makefile    |   1 +
 drivers/gpio/gpio-reg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/gpio-reg.h |  12 ++++
 4 files changed, 158 insertions(+)
 create mode 100644 drivers/gpio/gpio-reg.c
 create mode 100644 include/linux/gpio-reg.h

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 98dd47a30fc7..49bd8b89712e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -365,6 +365,12 @@ config GPIO_RCAR
 	help
 	  Say yes here to support GPIO on Renesas R-Car SoCs.
 
+config GPIO_REG
+	bool
+	help
+	  A 32-bit single register GPIO fixed in/out implementation.  This
+	  can be used to represent any register as a set of GPIO signals.
+
 config GPIO_SPEAR_SPICS
 	bool "ST SPEAr13xx SPI Chip Select as GPIO support"
 	depends on PLAT_SPEAR
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2a035ed8f168..3fc904fcc595 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_PXA)		+= gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)	+= gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
 obj-$(CONFIG_GPIO_RCAR)		+= gpio-rcar.o
+obj-$(CONFIG_GPIO_REG)		+= gpio-reg.o
 obj-$(CONFIG_ARCH_SA1100)	+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
 obj-$(CONFIG_GPIO_SCH311X)	+= gpio-sch311x.o
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
new file mode 100644
index 000000000000..fc7e0a395f9f
--- /dev/null
+++ b/drivers/gpio/gpio-reg.c
@@ -0,0 +1,139 @@
+#include <linux/gpio/driver.h>
+#include <linux/gpio-reg.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+struct gpio_reg {
+	struct gpio_chip gc;
+	spinlock_t lock;
+	u32 direction;
+	u32 out;
+	void __iomem *reg;
+};
+
+#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
+
+static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+
+	return r->direction & BIT(offset) ? 1 : 0;
+}
+
+static int gpio_reg_direction_output(struct gpio_chip *gc, unsigned offset,
+	int value)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+
+	if (r->direction & BIT(offset))
+		return -ENOTSUPP;
+
+	gc->set(gc, offset, value);
+	return 0;
+}
+
+static int gpio_reg_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+
+	return r->direction & BIT(offset) ? 0 : -ENOTSUPP;
+}
+
+static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	unsigned long flags;
+	u32 val, mask = BIT(offset);
+
+	spin_lock_irqsave(&r->lock, flags);
+	val = r->out;
+	if (value)
+		val |= mask;
+	else
+		val &= ~mask;
+	r->out = val;
+	writel_relaxed(val, r->reg);
+	spin_unlock_irqrestore(&r->lock, flags);
+}
+
+static int gpio_reg_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	u32 val, mask = BIT(offset);
+
+	if (r->direction & mask) {
+		/*
+		 * double-read the value, some registers latch after the
+		 * first read.
+		 */
+		readl_relaxed(r->reg);
+		val = readl_relaxed(r->reg);
+	} else {
+		val = r->out;
+	}
+	return !!(val & mask);
+}
+
+static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&r->lock, flags);
+	r->out = (r->out & ~*mask) | *bits;
+	writel_relaxed(r->out, r->reg);
+	spin_unlock_irqrestore(&r->lock, flags);
+}
+
+struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
+	int base, int num, const char *label, u32 direction, u32 def_out,
+	const char *const *names)
+{
+	struct gpio_reg *r;
+	int ret;
+
+	if (dev)
+		r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
+	else
+		r = kzalloc(sizeof(*r), GFP_KERNEL);
+
+	if (!r)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&r->lock);
+
+	r->gc.label = label;
+	r->gc.get_direction = gpio_reg_get_direction;
+	r->gc.direction_input = gpio_reg_direction_input;
+	r->gc.direction_output = gpio_reg_direction_output;
+	r->gc.set = gpio_reg_set;
+	r->gc.get = gpio_reg_get;
+	r->gc.set_multiple = gpio_reg_set_multiple;
+	r->gc.base = base;
+	r->gc.ngpio = num;
+	r->gc.names = names;
+	r->direction = direction;
+	r->out = def_out;
+	r->reg = reg;
+
+	if (dev)
+		ret = devm_gpiochip_add_data(dev, &r->gc, r);
+	else
+		ret = gpiochip_add_data(&r->gc, r);
+
+	return ret ? ERR_PTR(ret) : &r->gc;
+}
+
+int gpio_reg_resume(struct gpio_chip *gc)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&r->lock, flags);
+	writel_relaxed(r->out, r->reg);
+	spin_unlock_irqrestore(&r->lock, flags);
+
+	return 0;
+}
diff --git a/include/linux/gpio-reg.h b/include/linux/gpio-reg.h
new file mode 100644
index 000000000000..0352bec7319a
--- /dev/null
+++ b/include/linux/gpio-reg.h
@@ -0,0 +1,12 @@
+#ifndef GPIO_REG_H
+#define GPIO_REG_H
+
+struct device;
+
+struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
+	int base, int num, const char *label, u32 direction, u32 def_out,
+	const char *const *names);
+
+int gpio_reg_resume(struct gpio_chip *gc);
+
+#endif
-- 
2.1.0


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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Add a simple, generic, single register fixed-direction GPIO driver.
This is able to support a single register where a fixed number of
bits are used for input and a fixed number of bits used for output.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/gpio/Kconfig     |   6 ++
 drivers/gpio/Makefile    |   1 +
 drivers/gpio/gpio-reg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/gpio-reg.h |  12 ++++
 4 files changed, 158 insertions(+)
 create mode 100644 drivers/gpio/gpio-reg.c
 create mode 100644 include/linux/gpio-reg.h

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 98dd47a30fc7..49bd8b89712e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -365,6 +365,12 @@ config GPIO_RCAR
 	help
 	  Say yes here to support GPIO on Renesas R-Car SoCs.
 
+config GPIO_REG
+	bool
+	help
+	  A 32-bit single register GPIO fixed in/out implementation.  This
+	  can be used to represent any register as a set of GPIO signals.
+
 config GPIO_SPEAR_SPICS
 	bool "ST SPEAr13xx SPI Chip Select as GPIO support"
 	depends on PLAT_SPEAR
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 2a035ed8f168..3fc904fcc595 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_GPIO_PXA)		+= gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583)	+= gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
 obj-$(CONFIG_GPIO_RCAR)		+= gpio-rcar.o
+obj-$(CONFIG_GPIO_REG)		+= gpio-reg.o
 obj-$(CONFIG_ARCH_SA1100)	+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
 obj-$(CONFIG_GPIO_SCH311X)	+= gpio-sch311x.o
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
new file mode 100644
index 000000000000..fc7e0a395f9f
--- /dev/null
+++ b/drivers/gpio/gpio-reg.c
@@ -0,0 +1,139 @@
+#include <linux/gpio/driver.h>
+#include <linux/gpio-reg.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+struct gpio_reg {
+	struct gpio_chip gc;
+	spinlock_t lock;
+	u32 direction;
+	u32 out;
+	void __iomem *reg;
+};
+
+#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
+
+static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+
+	return r->direction & BIT(offset) ? 1 : 0;
+}
+
+static int gpio_reg_direction_output(struct gpio_chip *gc, unsigned offset,
+	int value)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+
+	if (r->direction & BIT(offset))
+		return -ENOTSUPP;
+
+	gc->set(gc, offset, value);
+	return 0;
+}
+
+static int gpio_reg_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+
+	return r->direction & BIT(offset) ? 0 : -ENOTSUPP;
+}
+
+static void gpio_reg_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	unsigned long flags;
+	u32 val, mask = BIT(offset);
+
+	spin_lock_irqsave(&r->lock, flags);
+	val = r->out;
+	if (value)
+		val |= mask;
+	else
+		val &= ~mask;
+	r->out = val;
+	writel_relaxed(val, r->reg);
+	spin_unlock_irqrestore(&r->lock, flags);
+}
+
+static int gpio_reg_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	u32 val, mask = BIT(offset);
+
+	if (r->direction & mask) {
+		/*
+		 * double-read the value, some registers latch after the
+		 * first read.
+		 */
+		readl_relaxed(r->reg);
+		val = readl_relaxed(r->reg);
+	} else {
+		val = r->out;
+	}
+	return !!(val & mask);
+}
+
+static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&r->lock, flags);
+	r->out = (r->out & ~*mask) | *bits;
+	writel_relaxed(r->out, r->reg);
+	spin_unlock_irqrestore(&r->lock, flags);
+}
+
+struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
+	int base, int num, const char *label, u32 direction, u32 def_out,
+	const char *const *names)
+{
+	struct gpio_reg *r;
+	int ret;
+
+	if (dev)
+		r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
+	else
+		r = kzalloc(sizeof(*r), GFP_KERNEL);
+
+	if (!r)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&r->lock);
+
+	r->gc.label = label;
+	r->gc.get_direction = gpio_reg_get_direction;
+	r->gc.direction_input = gpio_reg_direction_input;
+	r->gc.direction_output = gpio_reg_direction_output;
+	r->gc.set = gpio_reg_set;
+	r->gc.get = gpio_reg_get;
+	r->gc.set_multiple = gpio_reg_set_multiple;
+	r->gc.base = base;
+	r->gc.ngpio = num;
+	r->gc.names = names;
+	r->direction = direction;
+	r->out = def_out;
+	r->reg = reg;
+
+	if (dev)
+		ret = devm_gpiochip_add_data(dev, &r->gc, r);
+	else
+		ret = gpiochip_add_data(&r->gc, r);
+
+	return ret ? ERR_PTR(ret) : &r->gc;
+}
+
+int gpio_reg_resume(struct gpio_chip *gc)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&r->lock, flags);
+	writel_relaxed(r->out, r->reg);
+	spin_unlock_irqrestore(&r->lock, flags);
+
+	return 0;
+}
diff --git a/include/linux/gpio-reg.h b/include/linux/gpio-reg.h
new file mode 100644
index 000000000000..0352bec7319a
--- /dev/null
+++ b/include/linux/gpio-reg.h
@@ -0,0 +1,12 @@
+#ifndef GPIO_REG_H
+#define GPIO_REG_H
+
+struct device;
+
+struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
+	int base, int num, const char *label, u32 direction, u32 def_out,
+	const char *const *names);
+
+int gpio_reg_resume(struct gpio_chip *gc);
+
+#endif
-- 
2.1.0

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

* [PATCH 06/33] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a gpio driver for the lubbock miscellaneous write IO register so we
can take advantage of subsystems modelled around gpiolib, rather than
having to provide platform specific callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/Kconfig   |  1 +
 arch/arm/mach-pxa/lubbock.c | 24 ++++++++++++++++--------
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index cd894d69e766..e7577803a911 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -29,6 +29,7 @@ config MACH_PXA3XX_DT
 
 config ARCH_LUBBOCK
 	bool "Intel DBPXA250 Development Platform (aka Lubbock)"
+	select GPIO_REG
 	select PXA25x
 	select SA1111
 
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 7245f3359564..e974d1eb0f88 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -13,6 +13,7 @@
  */
 #include <linux/clkdev.h>
 #include <linux/gpio.h>
+#include <linux/gpio-reg.h>
 #include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -110,20 +111,18 @@ static unsigned long lubbock_pin_config[] __initdata = {
 };
 
 #define LUB_HEXLED		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
-#define LUB_MISC_WR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
 
 void lubbock_set_hexled(uint32_t value)
 {
 	LUB_HEXLED = value;
 }
 
+static struct gpio_chip *lubbock_misc_wr_gc;
+
 void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
 {
-	unsigned long flags;
-
-	local_irq_save(flags);
-	LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
-	local_irq_restore(flags);
+	unsigned long m = mask, v = set;
+	lubbock_misc_wr_gc->set_multiple(lubbock_misc_wr_gc, &m, &v);
 }
 EXPORT_SYMBOL(lubbock_set_misc_wr);
 
@@ -443,9 +442,9 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
 
 	local_irq_save(flags);
 	if (mode & IR_SIRMODE) {
-		LUB_MISC_WR &= ~(1 << 4);
+		lubbock_set_misc_wr(BIT(4), 0);
 	} else if (mode & IR_FIRMODE) {
-		LUB_MISC_WR |= 1 << 4;
+		lubbock_set_misc_wr(BIT(4), BIT(4));
 	}
 	pxa2xx_transceiver_mode(dev, mode);
 	local_irq_restore(flags);
@@ -463,6 +462,15 @@ static void __init lubbock_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
 
+	lubbock_misc_wr_gc = gpio_reg_init(NULL, (void *)&LUB_MISC_WR,
+					   -1, 16, "lubbock", 0, LUB_MISC_WR,
+					   NULL);
+	if (IS_ERR(lubbock_misc_wr_gc)) {
+		pr_err("Lubbock: unable to register lubbock GPIOs: %ld\n",
+		       PTR_ERR(lubbock_misc_wr_gc));
+		lubbock_misc_wr_gc = NULL;
+	}
+
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
-- 
2.1.0


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

* [PATCH 06/33] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Add a gpio driver for the lubbock miscellaneous write IO register so we
can take advantage of subsystems modelled around gpiolib, rather than
having to provide platform specific callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/Kconfig   |  1 +
 arch/arm/mach-pxa/lubbock.c | 24 ++++++++++++++++--------
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index cd894d69e766..e7577803a911 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -29,6 +29,7 @@ config MACH_PXA3XX_DT
 
 config ARCH_LUBBOCK
 	bool "Intel DBPXA250 Development Platform (aka Lubbock)"
+	select GPIO_REG
 	select PXA25x
 	select SA1111
 
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 7245f3359564..e974d1eb0f88 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -13,6 +13,7 @@
  */
 #include <linux/clkdev.h>
 #include <linux/gpio.h>
+#include <linux/gpio-reg.h>
 #include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -110,20 +111,18 @@ static unsigned long lubbock_pin_config[] __initdata = {
 };
 
 #define LUB_HEXLED		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
-#define LUB_MISC_WR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
 
 void lubbock_set_hexled(uint32_t value)
 {
 	LUB_HEXLED = value;
 }
 
+static struct gpio_chip *lubbock_misc_wr_gc;
+
 void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
 {
-	unsigned long flags;
-
-	local_irq_save(flags);
-	LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
-	local_irq_restore(flags);
+	unsigned long m = mask, v = set;
+	lubbock_misc_wr_gc->set_multiple(lubbock_misc_wr_gc, &m, &v);
 }
 EXPORT_SYMBOL(lubbock_set_misc_wr);
 
@@ -443,9 +442,9 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
 
 	local_irq_save(flags);
 	if (mode & IR_SIRMODE) {
-		LUB_MISC_WR &= ~(1 << 4);
+		lubbock_set_misc_wr(BIT(4), 0);
 	} else if (mode & IR_FIRMODE) {
-		LUB_MISC_WR |= 1 << 4;
+		lubbock_set_misc_wr(BIT(4), BIT(4));
 	}
 	pxa2xx_transceiver_mode(dev, mode);
 	local_irq_restore(flags);
@@ -463,6 +462,15 @@ static void __init lubbock_init(void)
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
 
+	lubbock_misc_wr_gc = gpio_reg_init(NULL, (void *)&LUB_MISC_WR,
+					   -1, 16, "lubbock", 0, LUB_MISC_WR,
+					   NULL);
+	if (IS_ERR(lubbock_misc_wr_gc)) {
+		pr_err("Lubbock: unable to register lubbock GPIOs: %ld\n",
+		       PTR_ERR(lubbock_misc_wr_gc));
+		lubbock_misc_wr_gc = NULL;
+	}
+
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
-- 
2.1.0

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

* [PATCH 07/33] ARM: sa1100/assabet: add BCR/BSR GPIO driver
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a GPIO driver for the board control register/board status register
for the sa1100/assabet platform.  This allows us to transition a range
of drivers to use the gpiod APIs rather than the platform private
ASSABET_BCR_* interfaces.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/Kconfig   |  1 +
 arch/arm/mach-sa1100/assabet.c | 71 ++++++++++++++++++++++++++++++++----------
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 36e3c79f4973..07df3a59b13f 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -5,6 +5,7 @@ menu "SA11x0 Implementations"
 config SA1100_ASSABET
 	bool "Assabet"
 	select ARM_SA1110_CPUFREQ
+	select GPIO_REG
 	help
 	  Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
 	  Microprocessor Development Board (also known as the Assabet).
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index d28ecb9ef172..8f24c84042e0 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/gpio-reg.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/serial_core.h>
@@ -61,20 +62,45 @@
 unsigned long SCR_value = ASSABET_SCR_INIT;
 EXPORT_SYMBOL(SCR_value);
 
-static unsigned long BCR_value = ASSABET_BCR_DB1110;
+static struct gpio_chip *assabet_bcr_gc;
+
+static const char *assabet_names[] = {
+	"cf_pwr", "cf_gfx_rst", "codec_rst", "irda_fsel",
+	"irda_md0", "irda_md1", "stereo_lb", "cf_bus_off",
+	"audio", "backlight", "lcd_12rgb", "lcd_on",
+	"rs232", "d9_led", "d8_led", "vib_on",
+	"com_dtr", "com_rts", "rad_wu", "smb_en",
+	"tv_ir_dec", "qmute", "rad_on", "spk_off",
+	"rs232_valid", "com_dcd", "com_cts", "com_dsr",
+	"rad_cts", "rad_dsr", "rad_dcd", "rad_ri",
+};
 
+/* The old deprecated interface */
 void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
 {
-	unsigned long flags;
+	unsigned long m = mask, v = val;
 
-	local_irq_save(flags);
-	BCR_value = (BCR_value & ~mask) | val;
-	ASSABET_BCR = BCR_value;
-	local_irq_restore(flags);
+	assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v);
 }
-
 EXPORT_SYMBOL(ASSABET_BCR_frob);
 
+static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
+{
+	struct gpio_chip *gc;
+
+	writel_relaxed(def_val, reg);
+
+	gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
+			   assabet_names);
+
+	if (IS_ERR(gc))
+		return PTR_ERR(gc);
+
+	assabet_bcr_gc = gc;
+
+	return gc->base;
+}
+
 /*
  * The codec reset goes to three devices, so we need to release
  * the rest when any one of these requests it.  However, that
@@ -146,7 +172,7 @@ static void adv7171_write(unsigned reg, unsigned val)
 	unsigned gpdr = GPDR;
 	unsigned gplr = GPLR;
 
-	ASSABET_BCR = BCR_value | ASSABET_BCR_AUDIO_ON;
+	ASSABET_BCR_frob(ASSABET_BCR_AUDIO_ON, ASSABET_BCR_AUDIO_ON);
 	udelay(100);
 
 	GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */
@@ -457,14 +483,6 @@ static void __init assabet_init(void)
 	sa11x0_ppc_configure_mcp();
 
 	if (machine_has_neponset()) {
-		/*
-		 * Angel sets this, but other bootloaders may not.
-		 *
-		 * This must precede any driver calls to BCR_set()
-		 * or BCR_clear().
-		 */
-		ASSABET_BCR = BCR_value = ASSABET_BCR_DB1111;
-
 #ifndef CONFIG_ASSABET_NEPONSET
 		printk( "Warning: Neponset detected but full support "
 			"hasn't been configured in the kernel\n" );
@@ -748,12 +766,31 @@ static int __init assabet_leds_init(void)
 fs_initcall(assabet_leds_init);
 #endif
 
+void __init assabet_init_irq(void)
+{
+	u32 def_val;
+
+	sa1100_init_irq();
+
+	if (machine_has_neponset())
+		def_val = ASSABET_BCR_DB1111;
+	else
+		def_val = ASSABET_BCR_DB1110;
+
+	/*
+	 * Angel sets this, but other bootloaders may not.
+	 *
+	 * This must precede any driver calls to BCR_set() or BCR_clear().
+	 */
+	assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+}
+
 MACHINE_START(ASSABET, "Intel-Assabet")
 	.atag_offset	= 0x100,
 	.fixup		= fixup_assabet,
 	.map_io		= assabet_map_io,
 	.nr_irqs	= SA1100_NR_IRQS,
-	.init_irq	= sa1100_init_irq,
+	.init_irq	= assabet_init_irq,
 	.init_time	= sa1100_timer_init,
 	.init_machine	= assabet_init,
 	.init_late	= sa11x0_init_late,
-- 
2.1.0


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

* [PATCH 07/33] ARM: sa1100/assabet: add BCR/BSR GPIO driver
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Add a GPIO driver for the board control register/board status register
for the sa1100/assabet platform.  This allows us to transition a range
of drivers to use the gpiod APIs rather than the platform private
ASSABET_BCR_* interfaces.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/Kconfig   |  1 +
 arch/arm/mach-sa1100/assabet.c | 71 ++++++++++++++++++++++++++++++++----------
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 36e3c79f4973..07df3a59b13f 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -5,6 +5,7 @@ menu "SA11x0 Implementations"
 config SA1100_ASSABET
 	bool "Assabet"
 	select ARM_SA1110_CPUFREQ
+	select GPIO_REG
 	help
 	  Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
 	  Microprocessor Development Board (also known as the Assabet).
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index d28ecb9ef172..8f24c84042e0 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/gpio-reg.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/serial_core.h>
@@ -61,20 +62,45 @@
 unsigned long SCR_value = ASSABET_SCR_INIT;
 EXPORT_SYMBOL(SCR_value);
 
-static unsigned long BCR_value = ASSABET_BCR_DB1110;
+static struct gpio_chip *assabet_bcr_gc;
+
+static const char *assabet_names[] = {
+	"cf_pwr", "cf_gfx_rst", "codec_rst", "irda_fsel",
+	"irda_md0", "irda_md1", "stereo_lb", "cf_bus_off",
+	"audio", "backlight", "lcd_12rgb", "lcd_on",
+	"rs232", "d9_led", "d8_led", "vib_on",
+	"com_dtr", "com_rts", "rad_wu", "smb_en",
+	"tv_ir_dec", "qmute", "rad_on", "spk_off",
+	"rs232_valid", "com_dcd", "com_cts", "com_dsr",
+	"rad_cts", "rad_dsr", "rad_dcd", "rad_ri",
+};
 
+/* The old deprecated interface */
 void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
 {
-	unsigned long flags;
+	unsigned long m = mask, v = val;
 
-	local_irq_save(flags);
-	BCR_value = (BCR_value & ~mask) | val;
-	ASSABET_BCR = BCR_value;
-	local_irq_restore(flags);
+	assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v);
 }
-
 EXPORT_SYMBOL(ASSABET_BCR_frob);
 
+static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
+{
+	struct gpio_chip *gc;
+
+	writel_relaxed(def_val, reg);
+
+	gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
+			   assabet_names);
+
+	if (IS_ERR(gc))
+		return PTR_ERR(gc);
+
+	assabet_bcr_gc = gc;
+
+	return gc->base;
+}
+
 /*
  * The codec reset goes to three devices, so we need to release
  * the rest when any one of these requests it.  However, that
@@ -146,7 +172,7 @@ static void adv7171_write(unsigned reg, unsigned val)
 	unsigned gpdr = GPDR;
 	unsigned gplr = GPLR;
 
-	ASSABET_BCR = BCR_value | ASSABET_BCR_AUDIO_ON;
+	ASSABET_BCR_frob(ASSABET_BCR_AUDIO_ON, ASSABET_BCR_AUDIO_ON);
 	udelay(100);
 
 	GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */
@@ -457,14 +483,6 @@ static void __init assabet_init(void)
 	sa11x0_ppc_configure_mcp();
 
 	if (machine_has_neponset()) {
-		/*
-		 * Angel sets this, but other bootloaders may not.
-		 *
-		 * This must precede any driver calls to BCR_set()
-		 * or BCR_clear().
-		 */
-		ASSABET_BCR = BCR_value = ASSABET_BCR_DB1111;
-
 #ifndef CONFIG_ASSABET_NEPONSET
 		printk( "Warning: Neponset detected but full support "
 			"hasn't been configured in the kernel\n" );
@@ -748,12 +766,31 @@ static int __init assabet_leds_init(void)
 fs_initcall(assabet_leds_init);
 #endif
 
+void __init assabet_init_irq(void)
+{
+	u32 def_val;
+
+	sa1100_init_irq();
+
+	if (machine_has_neponset())
+		def_val = ASSABET_BCR_DB1111;
+	else
+		def_val = ASSABET_BCR_DB1110;
+
+	/*
+	 * Angel sets this, but other bootloaders may not.
+	 *
+	 * This must precede any driver calls to BCR_set() or BCR_clear().
+	 */
+	assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+}
+
 MACHINE_START(ASSABET, "Intel-Assabet")
 	.atag_offset	= 0x100,
 	.fixup		= fixup_assabet,
 	.map_io		= assabet_map_io,
 	.nr_irqs	= SA1100_NR_IRQS,
-	.init_irq	= sa1100_init_irq,
+	.init_irq	= assabet_init_irq,
 	.init_time	= sa1100_timer_init,
 	.init_machine	= assabet_init,
 	.init_late	= sa11x0_init_late,
-- 
2.1.0

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

* [PATCH 08/33] ARM: sa1100/neponset: add GPIO drivers for control and modem registers
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

The NCR, MDM_CTL* and AUD registers manipulate the state of external
signals (eg, the RTS, DTR signals and the ethernet oscillator enable
signal) or indicate the state of external signals (eg, CTS, DSR).

Where these registers can be written, the current value can be read
back, which relieves us from having to maintain a software copy of
the current state.

Model these registers as fixed-direction GPIO registers.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 153 ++++++++++++++++++++++++----------------
 1 file changed, 93 insertions(+), 60 deletions(-)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 8411985af9ff..75d758ca6799 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -2,6 +2,8 @@
  * linux/arch/arm/mach-sa1100/neponset.c
  */
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio-reg.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -44,10 +46,13 @@
 #define IRR_USAR	(1 << 1)
 #define IRR_SA1111	(1 << 2)
 
+#define NCR_NGPIO	7
+
 #define MDM_CTL0_RTS1	(1 << 0)
 #define MDM_CTL0_DTR1	(1 << 1)
 #define MDM_CTL0_RTS2	(1 << 2)
 #define MDM_CTL0_DTR2	(1 << 3)
+#define MDM_CTL0_NGPIO	4
 
 #define MDM_CTL1_CTS1	(1 << 0)
 #define MDM_CTL1_DSR1	(1 << 1)
@@ -55,80 +60,87 @@
 #define MDM_CTL1_CTS2	(1 << 3)
 #define MDM_CTL1_DSR2	(1 << 4)
 #define MDM_CTL1_DCD2	(1 << 5)
+#define MDM_CTL1_NGPIO	6
 
 #define AUD_SEL_1341	(1 << 0)
 #define AUD_MUTE_1341	(1 << 1)
+#define AUD_NGPIO	2
 
 extern void sa1110_mb_disable(void);
 
+#define to_neponset_gpio_chip(x) container_of(x, struct neponset_gpio_chip, gc)
+
+static const char *neponset_ncr_names[] = {
+	"gp01_off", "tp_power", "ms_power", "enet_osc",
+	"spi_kb_wk_up", "a0vpp", "a1vpp"
+};
+
+static const char *neponset_mdmctl0_names[] = {
+	"rts3", "dtr3", "rts1", "dtr1",
+};
+
+static const char *neponset_mdmctl1_names[] = {
+	"cts3", "dsr3", "dcd3", "cts1", "dsr1", "dcd1"
+};
+
+static const char *neponset_aud_names[] = {
+	"sel_1341", "mute_1341",
+};
+
 struct neponset_drvdata {
 	void __iomem *base;
 	struct platform_device *sa1111;
 	struct platform_device *smc91x;
 	unsigned irq_base;
-#ifdef CONFIG_PM_SLEEP
-	u32 ncr0;
-	u32 mdm_ctl_0;
-#endif
+	struct gpio_chip *gpio[4];
 };
 
-static void __iomem *nep_base;
+static struct neponset_drvdata *nep;
 
 void neponset_ncr_frob(unsigned int mask, unsigned int val)
 {
-	void __iomem *base = nep_base;
-
-	if (base) {
-		unsigned long flags;
-		unsigned v;
-
-		local_irq_save(flags);
-		v = readb_relaxed(base + NCR_0);
-		writeb_relaxed((v & ~mask) | val, base + NCR_0);
-		local_irq_restore(flags);
-	} else {
-		WARN(1, "nep_base unset\n");
-	}
+	struct neponset_drvdata *n = nep;
+	unsigned long m = mask, v = val;
+
+	if (nep)
+		n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
+	else
+		WARN(1, "nep unset\n");
 }
 EXPORT_SYMBOL(neponset_ncr_frob);
 
 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-	void __iomem *base = nep_base;
-	u_int mdm_ctl0;
+	struct neponset_drvdata *n = nep;
+	unsigned long mask, val = 0;
 
-	if (!base)
+	if (!n)
 		return;
 
-	mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
 	if (port->mapbase == _Ser1UTCR0) {
-		if (mctrl & TIOCM_RTS)
-			mdm_ctl0 &= ~MDM_CTL0_RTS2;
-		else
-			mdm_ctl0 |= MDM_CTL0_RTS2;
-
-		if (mctrl & TIOCM_DTR)
-			mdm_ctl0 &= ~MDM_CTL0_DTR2;
-		else
-			mdm_ctl0 |= MDM_CTL0_DTR2;
+		mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2;
+
+		if (!(mctrl & TIOCM_RTS))
+			val |= MDM_CTL0_RTS2;
+
+		if (!(mctrl & TIOCM_DTR))
+			val |= MDM_CTL0_DTR2;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (mctrl & TIOCM_RTS)
-			mdm_ctl0 &= ~MDM_CTL0_RTS1;
-		else
-			mdm_ctl0 |= MDM_CTL0_RTS1;
-
-		if (mctrl & TIOCM_DTR)
-			mdm_ctl0 &= ~MDM_CTL0_DTR1;
-		else
-			mdm_ctl0 |= MDM_CTL0_DTR1;
+		mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1;
+
+		if (!(mctrl & TIOCM_RTS))
+			val |= MDM_CTL0_RTS1;
+
+		if (!(mctrl & TIOCM_DTR))
+			val |= MDM_CTL0_DTR1;
 	}
 
-	writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
+	n->gpio[1]->set_multiple(n->gpio[1], &mask, &val);
 }
 
 static u_int neponset_get_mctrl(struct uart_port *port)
 {
-	void __iomem *base = nep_base;
+	void __iomem *base = nep->base;
 	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
 	u_int mdm_ctl1;
 
@@ -230,6 +242,22 @@ static struct irq_chip nochip = {
 	.irq_unmask = nochip_noop,
 };
 
+static int neponset_init_gpio(struct gpio_chip **gcp,
+	struct device *dev, const char *label, void __iomem *reg,
+	unsigned num, bool in, const char *const * names)
+{
+	struct gpio_chip *gc;
+
+	gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
+			   readl_relaxed(reg), names);
+	if (IS_ERR(gc))
+		return PTR_ERR(gc);
+
+	*gcp = gc;
+
+	return 0;
+}
+
 static struct sa1111_platform_data sa1111_info = {
 	.disable_devs	= SA1111_DEVID_PS2_MSE,
 };
@@ -273,7 +301,7 @@ static int neponset_probe(struct platform_device *dev)
 	};
 	int ret, irq;
 
-	if (nep_base)
+	if (nep)
 		return -EBUSY;
 
 	irq = ret = platform_get_irq(dev, 0);
@@ -329,6 +357,19 @@ static int neponset_probe(struct platform_device *dev)
 	irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
 	irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
 
+	neponset_init_gpio(&d->gpio[0], &dev->dev, "neponset-ncr",
+			   d->base + NCR_0, NCR_NGPIO, false,
+			   neponset_ncr_names);
+	neponset_init_gpio(&d->gpio[1], &dev->dev, "neponset-mdm-ctl0",
+			   d->base + MDM_CTL_0, MDM_CTL0_NGPIO, false,
+			   neponset_mdmctl0_names);
+	neponset_init_gpio(&d->gpio[2], &dev->dev, "neponset-mdm-ctl1",
+			   d->base + MDM_CTL_1, MDM_CTL1_NGPIO, true,
+			   neponset_mdmctl1_names);
+	neponset_init_gpio(&d->gpio[3], &dev->dev, "neponset-aud-ctl",
+			   d->base + AUD_CTL, AUD_NGPIO, false,
+			   neponset_aud_names);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -339,7 +380,7 @@ static int neponset_probe(struct platform_device *dev)
 
 	dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
 		 d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
-	nep_base = d->base;
+	nep = d;
 
 	sa1100_register_uart_fns(&neponset_port_fns);
 
@@ -384,7 +425,7 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->smc91x);
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
-	nep_base = NULL;
+	nep = NULL;
 	iounmap(d->base);
 	kfree(d);
 
@@ -392,30 +433,22 @@ static int neponset_remove(struct platform_device *dev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int neponset_suspend(struct device *dev)
-{
-	struct neponset_drvdata *d = dev_get_drvdata(dev);
-
-	d->ncr0 = readb_relaxed(d->base + NCR_0);
-	d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
-
-	return 0;
-}
-
 static int neponset_resume(struct device *dev)
 {
 	struct neponset_drvdata *d = dev_get_drvdata(dev);
+	int i, ret = 0;
 
-	writeb_relaxed(d->ncr0, d->base + NCR_0);
-	writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
+	for (i = 0; i < ARRAY_SIZE(d->gpio); i++) {
+		ret = gpio_reg_resume(d->gpio[i]);
+		if (ret)
+			break;
+	}
 
-	return 0;
+	return ret;
 }
 
 static const struct dev_pm_ops neponset_pm_ops = {
-	.suspend_noirq = neponset_suspend,
 	.resume_noirq = neponset_resume,
-	.freeze_noirq = neponset_suspend,
 	.restore_noirq = neponset_resume,
 };
 #define PM_OPS &neponset_pm_ops
-- 
2.1.0


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

* [PATCH 08/33] ARM: sa1100/neponset: add GPIO drivers for control and modem registers
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

The NCR, MDM_CTL* and AUD registers manipulate the state of external
signals (eg, the RTS, DTR signals and the ethernet oscillator enable
signal) or indicate the state of external signals (eg, CTS, DSR).

Where these registers can be written, the current value can be read
back, which relieves us from having to maintain a software copy of
the current state.

Model these registers as fixed-direction GPIO registers.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 153 ++++++++++++++++++++++++----------------
 1 file changed, 93 insertions(+), 60 deletions(-)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 8411985af9ff..75d758ca6799 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -2,6 +2,8 @@
  * linux/arch/arm/mach-sa1100/neponset.c
  */
 #include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio-reg.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -44,10 +46,13 @@
 #define IRR_USAR	(1 << 1)
 #define IRR_SA1111	(1 << 2)
 
+#define NCR_NGPIO	7
+
 #define MDM_CTL0_RTS1	(1 << 0)
 #define MDM_CTL0_DTR1	(1 << 1)
 #define MDM_CTL0_RTS2	(1 << 2)
 #define MDM_CTL0_DTR2	(1 << 3)
+#define MDM_CTL0_NGPIO	4
 
 #define MDM_CTL1_CTS1	(1 << 0)
 #define MDM_CTL1_DSR1	(1 << 1)
@@ -55,80 +60,87 @@
 #define MDM_CTL1_CTS2	(1 << 3)
 #define MDM_CTL1_DSR2	(1 << 4)
 #define MDM_CTL1_DCD2	(1 << 5)
+#define MDM_CTL1_NGPIO	6
 
 #define AUD_SEL_1341	(1 << 0)
 #define AUD_MUTE_1341	(1 << 1)
+#define AUD_NGPIO	2
 
 extern void sa1110_mb_disable(void);
 
+#define to_neponset_gpio_chip(x) container_of(x, struct neponset_gpio_chip, gc)
+
+static const char *neponset_ncr_names[] = {
+	"gp01_off", "tp_power", "ms_power", "enet_osc",
+	"spi_kb_wk_up", "a0vpp", "a1vpp"
+};
+
+static const char *neponset_mdmctl0_names[] = {
+	"rts3", "dtr3", "rts1", "dtr1",
+};
+
+static const char *neponset_mdmctl1_names[] = {
+	"cts3", "dsr3", "dcd3", "cts1", "dsr1", "dcd1"
+};
+
+static const char *neponset_aud_names[] = {
+	"sel_1341", "mute_1341",
+};
+
 struct neponset_drvdata {
 	void __iomem *base;
 	struct platform_device *sa1111;
 	struct platform_device *smc91x;
 	unsigned irq_base;
-#ifdef CONFIG_PM_SLEEP
-	u32 ncr0;
-	u32 mdm_ctl_0;
-#endif
+	struct gpio_chip *gpio[4];
 };
 
-static void __iomem *nep_base;
+static struct neponset_drvdata *nep;
 
 void neponset_ncr_frob(unsigned int mask, unsigned int val)
 {
-	void __iomem *base = nep_base;
-
-	if (base) {
-		unsigned long flags;
-		unsigned v;
-
-		local_irq_save(flags);
-		v = readb_relaxed(base + NCR_0);
-		writeb_relaxed((v & ~mask) | val, base + NCR_0);
-		local_irq_restore(flags);
-	} else {
-		WARN(1, "nep_base unset\n");
-	}
+	struct neponset_drvdata *n = nep;
+	unsigned long m = mask, v = val;
+
+	if (nep)
+		n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
+	else
+		WARN(1, "nep unset\n");
 }
 EXPORT_SYMBOL(neponset_ncr_frob);
 
 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-	void __iomem *base = nep_base;
-	u_int mdm_ctl0;
+	struct neponset_drvdata *n = nep;
+	unsigned long mask, val = 0;
 
-	if (!base)
+	if (!n)
 		return;
 
-	mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
 	if (port->mapbase == _Ser1UTCR0) {
-		if (mctrl & TIOCM_RTS)
-			mdm_ctl0 &= ~MDM_CTL0_RTS2;
-		else
-			mdm_ctl0 |= MDM_CTL0_RTS2;
-
-		if (mctrl & TIOCM_DTR)
-			mdm_ctl0 &= ~MDM_CTL0_DTR2;
-		else
-			mdm_ctl0 |= MDM_CTL0_DTR2;
+		mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2;
+
+		if (!(mctrl & TIOCM_RTS))
+			val |= MDM_CTL0_RTS2;
+
+		if (!(mctrl & TIOCM_DTR))
+			val |= MDM_CTL0_DTR2;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (mctrl & TIOCM_RTS)
-			mdm_ctl0 &= ~MDM_CTL0_RTS1;
-		else
-			mdm_ctl0 |= MDM_CTL0_RTS1;
-
-		if (mctrl & TIOCM_DTR)
-			mdm_ctl0 &= ~MDM_CTL0_DTR1;
-		else
-			mdm_ctl0 |= MDM_CTL0_DTR1;
+		mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1;
+
+		if (!(mctrl & TIOCM_RTS))
+			val |= MDM_CTL0_RTS1;
+
+		if (!(mctrl & TIOCM_DTR))
+			val |= MDM_CTL0_DTR1;
 	}
 
-	writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
+	n->gpio[1]->set_multiple(n->gpio[1], &mask, &val);
 }
 
 static u_int neponset_get_mctrl(struct uart_port *port)
 {
-	void __iomem *base = nep_base;
+	void __iomem *base = nep->base;
 	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
 	u_int mdm_ctl1;
 
@@ -230,6 +242,22 @@ static struct irq_chip nochip = {
 	.irq_unmask = nochip_noop,
 };
 
+static int neponset_init_gpio(struct gpio_chip **gcp,
+	struct device *dev, const char *label, void __iomem *reg,
+	unsigned num, bool in, const char *const * names)
+{
+	struct gpio_chip *gc;
+
+	gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
+			   readl_relaxed(reg), names);
+	if (IS_ERR(gc))
+		return PTR_ERR(gc);
+
+	*gcp = gc;
+
+	return 0;
+}
+
 static struct sa1111_platform_data sa1111_info = {
 	.disable_devs	= SA1111_DEVID_PS2_MSE,
 };
@@ -273,7 +301,7 @@ static int neponset_probe(struct platform_device *dev)
 	};
 	int ret, irq;
 
-	if (nep_base)
+	if (nep)
 		return -EBUSY;
 
 	irq = ret = platform_get_irq(dev, 0);
@@ -329,6 +357,19 @@ static int neponset_probe(struct platform_device *dev)
 	irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
 	irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
 
+	neponset_init_gpio(&d->gpio[0], &dev->dev, "neponset-ncr",
+			   d->base + NCR_0, NCR_NGPIO, false,
+			   neponset_ncr_names);
+	neponset_init_gpio(&d->gpio[1], &dev->dev, "neponset-mdm-ctl0",
+			   d->base + MDM_CTL_0, MDM_CTL0_NGPIO, false,
+			   neponset_mdmctl0_names);
+	neponset_init_gpio(&d->gpio[2], &dev->dev, "neponset-mdm-ctl1",
+			   d->base + MDM_CTL_1, MDM_CTL1_NGPIO, true,
+			   neponset_mdmctl1_names);
+	neponset_init_gpio(&d->gpio[3], &dev->dev, "neponset-aud-ctl",
+			   d->base + AUD_CTL, AUD_NGPIO, false,
+			   neponset_aud_names);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -339,7 +380,7 @@ static int neponset_probe(struct platform_device *dev)
 
 	dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
 		 d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
-	nep_base = d->base;
+	nep = d;
 
 	sa1100_register_uart_fns(&neponset_port_fns);
 
@@ -384,7 +425,7 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->smc91x);
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
-	nep_base = NULL;
+	nep = NULL;
 	iounmap(d->base);
 	kfree(d);
 
@@ -392,30 +433,22 @@ static int neponset_remove(struct platform_device *dev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int neponset_suspend(struct device *dev)
-{
-	struct neponset_drvdata *d = dev_get_drvdata(dev);
-
-	d->ncr0 = readb_relaxed(d->base + NCR_0);
-	d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
-
-	return 0;
-}
-
 static int neponset_resume(struct device *dev)
 {
 	struct neponset_drvdata *d = dev_get_drvdata(dev);
+	int i, ret = 0;
 
-	writeb_relaxed(d->ncr0, d->base + NCR_0);
-	writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
+	for (i = 0; i < ARRAY_SIZE(d->gpio); i++) {
+		ret = gpio_reg_resume(d->gpio[i]);
+		if (ret)
+			break;
+	}
 
-	return 0;
+	return ret;
 }
 
 static const struct dev_pm_ops neponset_pm_ops = {
-	.suspend_noirq = neponset_suspend,
 	.resume_noirq = neponset_resume,
-	.freeze_noirq = neponset_suspend,
 	.restore_noirq = neponset_resume,
 };
 #define PM_OPS &neponset_pm_ops
-- 
2.1.0

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

* [PATCH 09/33] ARM: sa1111: implement a gpio_chip for SA1111 GPIOs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a gpio_chip instance for SA1111 GPIOs.  This allows us to use
gpiolib to lookup and manipulate SA1111 GPIOs.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/common/sa1111.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 165 insertions(+), 3 deletions(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index fb0a0a4dfea4..ac19dca4c258 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -15,6 +15,7 @@
  * from machine specific code with proper arguments when required.
  */
 #include <linux/module.h>
+#include <linux/gpio/driver.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
@@ -107,6 +108,7 @@ struct sa1111 {
 	spinlock_t	lock;
 	void __iomem	*base;
 	struct sa1111_platform_data *pdata;
+	struct gpio_chip gc;
 #ifdef CONFIG_PM
 	void		*saved_state;
 #endif
@@ -509,6 +511,163 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
 	return 0;
 }
 
+enum {
+	SA1111_GPIO_PXDDR = (SA1111_GPIO_PADDR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXDRR = (SA1111_GPIO_PADRR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXDWR = (SA1111_GPIO_PADWR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXSDR = (SA1111_GPIO_PASDR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXSSR = (SA1111_GPIO_PASSR - SA1111_GPIO_PADDR),
+};
+
+static struct sa1111 *gc_to_sa1111(struct gpio_chip *gc)
+{
+	return container_of(gc, struct sa1111, gc);
+}
+
+static void __iomem *sa1111_gpio_map_reg(struct sa1111 *sachip, unsigned offset)
+{
+	void __iomem *reg = sachip->base + SA1111_GPIO;
+
+	if (offset < 4)
+		return reg + SA1111_GPIO_PADDR;
+	if (offset < 10)
+		return reg + SA1111_GPIO_PBDDR;
+	if (offset < 18)
+		return reg + SA1111_GPIO_PCDDR;
+	return NULL;
+}
+
+static u32 sa1111_gpio_map_bit(unsigned offset)
+{
+	if (offset < 4)
+		return BIT(offset);
+	if (offset < 10)
+		return BIT(offset - 4);
+	if (offset < 18)
+		return BIT(offset - 10);
+	return 0;
+}
+
+static void sa1111_gpio_modify(void __iomem *reg, u32 mask, u32 set)
+{
+	u32 val;
+
+	val = readl_relaxed(reg);
+	val &= ~mask;
+	val |= mask & set;
+	writel_relaxed(val, reg);
+}
+
+static int sa1111_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	return !!(readl_relaxed(reg + SA1111_GPIO_PXDDR) & mask);
+}
+
+static int sa1111_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDDR, mask, mask);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSDR, mask, mask);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+
+	return 0;
+}
+
+static int sa1111_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
+	int value)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDWR, mask, value ? mask : 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSSR, mask, value ? mask : 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDDR, mask, 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSDR, mask, 0);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+
+	return 0;
+}
+
+static int sa1111_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	return !!(readl_relaxed(reg + SA1111_GPIO_PXDRR) & mask);
+}
+
+static void sa1111_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDWR, mask, value ? mask : 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSSR, mask, value ? mask : 0);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+static void sa1111_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sachip->base + SA1111_GPIO;
+	u32 msk, val;
+
+	msk = *mask;
+	val = *bits;
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PADWR, msk & 15, val);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PASSR, msk & 15, val);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PBDWR, (msk >> 4) & 255, val >> 4);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PBSSR, (msk >> 4) & 255, val >> 4);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PCDWR, (msk >> 12) & 255, val >> 12);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PCSSR, (msk >> 12) & 255, val >> 12);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+static int sa1111_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+
+	return sachip->irq_base + offset;
+}
+
+static int sa1111_setup_gpios(struct sa1111 *sachip)
+{
+	sachip->gc.label = "sa1111";
+	sachip->gc.parent = sachip->dev;
+	sachip->gc.owner = THIS_MODULE;
+	sachip->gc.get_direction = sa1111_gpio_get_direction;
+	sachip->gc.direction_input = sa1111_gpio_direction_input;
+	sachip->gc.direction_output = sa1111_gpio_direction_output;
+	sachip->gc.get = sa1111_gpio_get;
+	sachip->gc.set = sa1111_gpio_set;
+	sachip->gc.set_multiple = sa1111_gpio_set_multiple;
+	sachip->gc.to_irq = sa1111_gpio_to_irq;
+	sachip->gc.base = -1;
+	sachip->gc.ngpio = 18;
+
+	return devm_gpiochip_add_data(sachip->dev, &sachip->gc, sachip);
+}
+
 /*
  * Bring the SA1111 out of reset.  This requires a set procedure:
  *  1. nRESET asserted (by hardware)
@@ -696,7 +855,7 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	if (!pd)
 		return -EINVAL;
 
-	sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
+	sachip = devm_kzalloc(me, sizeof(struct sa1111), GFP_KERNEL);
 	if (!sachip)
 		return -ENOMEM;
 
@@ -747,6 +906,11 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	 */
 	sa1111_wake(sachip);
 
+	/* Setup the GPIOs - should really be done after the IRQ setup */
+	ret = sa1111_setup_gpios(sachip);
+	if (ret)
+		goto err_unmap;
+
 	/*
 	 * The interrupt controller must be initialised before any
 	 * other device to ensure that the interrupts are available.
@@ -806,7 +970,6 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
  err_clkput:
 	clk_put(sachip->clk);
  err_free:
-	kfree(sachip);
 	return ret;
 }
 
@@ -843,7 +1006,6 @@ static void __sa1111_remove(struct sa1111 *sachip)
 
 	iounmap(sachip->base);
 	clk_put(sachip->clk);
-	kfree(sachip);
 }
 
 struct sa1111_save_data {
-- 
2.1.0


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

* [PATCH 09/33] ARM: sa1111: implement a gpio_chip for SA1111 GPIOs
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Add a gpio_chip instance for SA1111 GPIOs.  This allows us to use
gpiolib to lookup and manipulate SA1111 GPIOs.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/common/sa1111.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 165 insertions(+), 3 deletions(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index fb0a0a4dfea4..ac19dca4c258 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -15,6 +15,7 @@
  * from machine specific code with proper arguments when required.
  */
 #include <linux/module.h>
+#include <linux/gpio/driver.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
@@ -107,6 +108,7 @@ struct sa1111 {
 	spinlock_t	lock;
 	void __iomem	*base;
 	struct sa1111_platform_data *pdata;
+	struct gpio_chip gc;
 #ifdef CONFIG_PM
 	void		*saved_state;
 #endif
@@ -509,6 +511,163 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
 	return 0;
 }
 
+enum {
+	SA1111_GPIO_PXDDR = (SA1111_GPIO_PADDR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXDRR = (SA1111_GPIO_PADRR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXDWR = (SA1111_GPIO_PADWR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXSDR = (SA1111_GPIO_PASDR - SA1111_GPIO_PADDR),
+	SA1111_GPIO_PXSSR = (SA1111_GPIO_PASSR - SA1111_GPIO_PADDR),
+};
+
+static struct sa1111 *gc_to_sa1111(struct gpio_chip *gc)
+{
+	return container_of(gc, struct sa1111, gc);
+}
+
+static void __iomem *sa1111_gpio_map_reg(struct sa1111 *sachip, unsigned offset)
+{
+	void __iomem *reg = sachip->base + SA1111_GPIO;
+
+	if (offset < 4)
+		return reg + SA1111_GPIO_PADDR;
+	if (offset < 10)
+		return reg + SA1111_GPIO_PBDDR;
+	if (offset < 18)
+		return reg + SA1111_GPIO_PCDDR;
+	return NULL;
+}
+
+static u32 sa1111_gpio_map_bit(unsigned offset)
+{
+	if (offset < 4)
+		return BIT(offset);
+	if (offset < 10)
+		return BIT(offset - 4);
+	if (offset < 18)
+		return BIT(offset - 10);
+	return 0;
+}
+
+static void sa1111_gpio_modify(void __iomem *reg, u32 mask, u32 set)
+{
+	u32 val;
+
+	val = readl_relaxed(reg);
+	val &= ~mask;
+	val |= mask & set;
+	writel_relaxed(val, reg);
+}
+
+static int sa1111_gpio_get_direction(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	return !!(readl_relaxed(reg + SA1111_GPIO_PXDDR) & mask);
+}
+
+static int sa1111_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDDR, mask, mask);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSDR, mask, mask);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+
+	return 0;
+}
+
+static int sa1111_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
+	int value)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDWR, mask, value ? mask : 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSSR, mask, value ? mask : 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDDR, mask, 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSDR, mask, 0);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+
+	return 0;
+}
+
+static int sa1111_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	return !!(readl_relaxed(reg + SA1111_GPIO_PXDRR) & mask);
+}
+
+static void sa1111_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sa1111_gpio_map_reg(sachip, offset);
+	u32 mask = sa1111_gpio_map_bit(offset);
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXDWR, mask, value ? mask : 0);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PXSSR, mask, value ? mask : 0);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+static void sa1111_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+	unsigned long *bits)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+	unsigned long flags;
+	void __iomem *reg = sachip->base + SA1111_GPIO;
+	u32 msk, val;
+
+	msk = *mask;
+	val = *bits;
+
+	spin_lock_irqsave(&sachip->lock, flags);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PADWR, msk & 15, val);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PASSR, msk & 15, val);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PBDWR, (msk >> 4) & 255, val >> 4);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PBSSR, (msk >> 4) & 255, val >> 4);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PCDWR, (msk >> 12) & 255, val >> 12);
+	sa1111_gpio_modify(reg + SA1111_GPIO_PCSSR, (msk >> 12) & 255, val >> 12);
+	spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+static int sa1111_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct sa1111 *sachip = gc_to_sa1111(gc);
+
+	return sachip->irq_base + offset;
+}
+
+static int sa1111_setup_gpios(struct sa1111 *sachip)
+{
+	sachip->gc.label = "sa1111";
+	sachip->gc.parent = sachip->dev;
+	sachip->gc.owner = THIS_MODULE;
+	sachip->gc.get_direction = sa1111_gpio_get_direction;
+	sachip->gc.direction_input = sa1111_gpio_direction_input;
+	sachip->gc.direction_output = sa1111_gpio_direction_output;
+	sachip->gc.get = sa1111_gpio_get;
+	sachip->gc.set = sa1111_gpio_set;
+	sachip->gc.set_multiple = sa1111_gpio_set_multiple;
+	sachip->gc.to_irq = sa1111_gpio_to_irq;
+	sachip->gc.base = -1;
+	sachip->gc.ngpio = 18;
+
+	return devm_gpiochip_add_data(sachip->dev, &sachip->gc, sachip);
+}
+
 /*
  * Bring the SA1111 out of reset.  This requires a set procedure:
  *  1. nRESET asserted (by hardware)
@@ -696,7 +855,7 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	if (!pd)
 		return -EINVAL;
 
-	sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
+	sachip = devm_kzalloc(me, sizeof(struct sa1111), GFP_KERNEL);
 	if (!sachip)
 		return -ENOMEM;
 
@@ -747,6 +906,11 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	 */
 	sa1111_wake(sachip);
 
+	/* Setup the GPIOs - should really be done after the IRQ setup */
+	ret = sa1111_setup_gpios(sachip);
+	if (ret)
+		goto err_unmap;
+
 	/*
 	 * The interrupt controller must be initialised before any
 	 * other device to ensure that the interrupts are available.
@@ -806,7 +970,6 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
  err_clkput:
 	clk_put(sachip->clk);
  err_free:
-	kfree(sachip);
 	return ret;
 }
 
@@ -843,7 +1006,6 @@ static void __sa1111_remove(struct sa1111 *sachip)
 
 	iounmap(sachip->base);
 	clk_put(sachip->clk);
-	kfree(sachip);
 }
 
 struct sa1111_save_data {
-- 
2.1.0

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

* [PATCH 10/33] pcmcia: soc_common: switch to using gpio_descs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:24     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Switch to using the gpiod_* consumer API rather than the legacy API.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 57 +++++++++++++++++++++++++++++++++------------
 drivers/pcmcia/soc_common.h |  3 +++
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index d5ca760c4eb2..5d167512e96e 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -33,6 +33,7 @@
 
 #include <linux/cpufreq.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -114,8 +115,8 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
 	for (i = 0; i < nr; i++) {
 		if (skt->stat[i].irq)
 			free_irq(skt->stat[i].irq, skt);
-		if (gpio_is_valid(skt->stat[i].gpio))
-			gpio_free(skt->stat[i].gpio);
+		if (skt->stat[i].desc)
+			gpiod_put(skt->stat[i].desc);
 	}
 
 	if (skt->ops->hw_shutdown)
@@ -129,6 +130,30 @@ static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	__soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
 }
 
+int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
+		struct gpio_desc *desc;
+
+		desc = gpiod_get(skt->socket.dev.parent,
+				 skt->stat[i].name, GPIOD_IN);
+		if (IS_ERR(desc)) {
+			dev_err(skt->socket.dev.parent,
+				"Failed to get GPIO for %s: %ld\n",
+				skt->stat[i].name, PTR_ERR(desc));
+			__soc_pcmcia_hw_shutdown(skt, i);
+			return PTR_ERR(desc);
+		}
+
+		skt->stat[i].desc = desc;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(soc_pcmcia_request_gpiods);
+
 static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret = 0, i;
@@ -143,8 +168,6 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
 	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
 		if (gpio_is_valid(skt->stat[i].gpio)) {
-			int irq;
-
 			ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
 					       skt->stat[i].name);
 			if (ret) {
@@ -152,7 +175,11 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 				return ret;
 			}
 
-			irq = gpio_to_irq(skt->stat[i].gpio);
+			skt->stat[i].desc = gpio_to_desc(skt->stat[i].gpio);
+		}
+
+		if (skt->stat[i].desc) {
+			int irq = gpiod_to_irq(skt->stat[i].desc);
 
 			if (i == SOC_STAT_RDY)
 				skt->socket.pci_irq = irq;
@@ -166,8 +193,8 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 					  IRQF_TRIGGER_NONE,
 					  skt->stat[i].name, skt);
 			if (ret) {
-				if (gpio_is_valid(skt->stat[i].gpio))
-					gpio_free(skt->stat[i].gpio);
+				if (skt->stat[i].desc)
+					gpiod_put(skt->stat[i].desc);
 				__soc_pcmcia_hw_shutdown(skt, i);
 				return ret;
 			}
@@ -209,16 +236,16 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 	state.bvd2 = 1;
 
 	/* CD is active low by default */
-	if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio))
-		state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio);
+	if (skt->stat[SOC_STAT_CD].desc)
+		state.detect = !gpiod_get_raw_value(skt->stat[SOC_STAT_CD].desc);
 
 	/* RDY and BVD are active high by default */
-	if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio))
-		state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio);
-	if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio))
-		state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio);
-	if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio))
-		state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio);
+	if (skt->stat[SOC_STAT_RDY].desc)
+		state.ready = !!gpiod_get_value(skt->stat[SOC_STAT_RDY].desc);
+	if (skt->stat[SOC_STAT_BVD1].desc)
+		state.bvd1 = !!gpiod_get_value(skt->stat[SOC_STAT_BVD1].desc);
+	if (skt->stat[SOC_STAT_BVD2].desc)
+		state.bvd2 = !!gpiod_get_value(skt->stat[SOC_STAT_BVD2].desc);
 
 	skt->ops->socket_state(skt, &state);
 
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 94762a54d731..ee40db16dc40 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -17,6 +17,7 @@
 
 
 struct device;
+struct gpio_desc;
 struct pcmcia_low_level;
 
 /*
@@ -52,6 +53,7 @@ struct soc_pcmcia_socket {
 
 	struct {
 		int		gpio;
+		struct gpio_desc *desc;
 		unsigned int	irq;
 		const char	*name;
 	} stat[4];
@@ -136,6 +138,7 @@ void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
 	struct pcmcia_low_level *ops, struct device *dev);
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
 
 
 #ifdef CONFIG_PCMCIA_DEBUG
-- 
2.1.0


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

* [PATCH 10/33] pcmcia: soc_common: switch to using gpio_descs
@ 2016-08-29 10:24     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:24 UTC (permalink / raw)
  To: linux-arm-kernel

Switch to using the gpiod_* consumer API rather than the legacy API.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 57 +++++++++++++++++++++++++++++++++------------
 drivers/pcmcia/soc_common.h |  3 +++
 2 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index d5ca760c4eb2..5d167512e96e 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -33,6 +33,7 @@
 
 #include <linux/cpufreq.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -114,8 +115,8 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
 	for (i = 0; i < nr; i++) {
 		if (skt->stat[i].irq)
 			free_irq(skt->stat[i].irq, skt);
-		if (gpio_is_valid(skt->stat[i].gpio))
-			gpio_free(skt->stat[i].gpio);
+		if (skt->stat[i].desc)
+			gpiod_put(skt->stat[i].desc);
 	}
 
 	if (skt->ops->hw_shutdown)
@@ -129,6 +130,30 @@ static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	__soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
 }
 
+int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
+		struct gpio_desc *desc;
+
+		desc = gpiod_get(skt->socket.dev.parent,
+				 skt->stat[i].name, GPIOD_IN);
+		if (IS_ERR(desc)) {
+			dev_err(skt->socket.dev.parent,
+				"Failed to get GPIO for %s: %ld\n",
+				skt->stat[i].name, PTR_ERR(desc));
+			__soc_pcmcia_hw_shutdown(skt, i);
+			return PTR_ERR(desc);
+		}
+
+		skt->stat[i].desc = desc;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(soc_pcmcia_request_gpiods);
+
 static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret = 0, i;
@@ -143,8 +168,6 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
 	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
 		if (gpio_is_valid(skt->stat[i].gpio)) {
-			int irq;
-
 			ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
 					       skt->stat[i].name);
 			if (ret) {
@@ -152,7 +175,11 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 				return ret;
 			}
 
-			irq = gpio_to_irq(skt->stat[i].gpio);
+			skt->stat[i].desc = gpio_to_desc(skt->stat[i].gpio);
+		}
+
+		if (skt->stat[i].desc) {
+			int irq = gpiod_to_irq(skt->stat[i].desc);
 
 			if (i == SOC_STAT_RDY)
 				skt->socket.pci_irq = irq;
@@ -166,8 +193,8 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 					  IRQF_TRIGGER_NONE,
 					  skt->stat[i].name, skt);
 			if (ret) {
-				if (gpio_is_valid(skt->stat[i].gpio))
-					gpio_free(skt->stat[i].gpio);
+				if (skt->stat[i].desc)
+					gpiod_put(skt->stat[i].desc);
 				__soc_pcmcia_hw_shutdown(skt, i);
 				return ret;
 			}
@@ -209,16 +236,16 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 	state.bvd2 = 1;
 
 	/* CD is active low by default */
-	if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio))
-		state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio);
+	if (skt->stat[SOC_STAT_CD].desc)
+		state.detect = !gpiod_get_raw_value(skt->stat[SOC_STAT_CD].desc);
 
 	/* RDY and BVD are active high by default */
-	if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio))
-		state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio);
-	if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio))
-		state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio);
-	if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio))
-		state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio);
+	if (skt->stat[SOC_STAT_RDY].desc)
+		state.ready = !!gpiod_get_value(skt->stat[SOC_STAT_RDY].desc);
+	if (skt->stat[SOC_STAT_BVD1].desc)
+		state.bvd1 = !!gpiod_get_value(skt->stat[SOC_STAT_BVD1].desc);
+	if (skt->stat[SOC_STAT_BVD2].desc)
+		state.bvd2 = !!gpiod_get_value(skt->stat[SOC_STAT_BVD2].desc);
 
 	skt->ops->socket_state(skt, &state);
 
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 94762a54d731..ee40db16dc40 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -17,6 +17,7 @@
 
 
 struct device;
+struct gpio_desc;
 struct pcmcia_low_level;
 
 /*
@@ -52,6 +53,7 @@ struct soc_pcmcia_socket {
 
 	struct {
 		int		gpio;
+		struct gpio_desc *desc;
 		unsigned int	irq;
 		const char	*name;
 	} stat[4];
@@ -136,6 +138,7 @@ void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
 	struct pcmcia_low_level *ops, struct device *dev);
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
 
 
 #ifdef CONFIG_PCMCIA_DEBUG
-- 
2.1.0

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

* [PATCH 11/33] pcmcia: soc_common: request legacy detect GPIO with active low
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Request the legacy card detect signal with the active low property and
remove our own negation of the detection value.  This allows us to use
the firmware-defined polarities rather than hard-coding it into the
driver.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 5d167512e96e..edfb6045fcda 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -168,7 +168,13 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
 	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
 		if (gpio_is_valid(skt->stat[i].gpio)) {
-			ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
+			unsigned long flags = GPIOF_IN;
+
+			/* CD is active low by default */
+			if (i == SOC_STAT_CD)
+				flags |= GPIOF_ACTIVE_LOW;
+
+			ret = gpio_request_one(skt->stat[i].gpio, flags,
 					       skt->stat[i].name);
 			if (ret) {
 				__soc_pcmcia_hw_shutdown(skt, i);
@@ -235,11 +241,8 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 	state.bvd1 = 1;
 	state.bvd2 = 1;
 
-	/* CD is active low by default */
 	if (skt->stat[SOC_STAT_CD].desc)
-		state.detect = !gpiod_get_raw_value(skt->stat[SOC_STAT_CD].desc);
-
-	/* RDY and BVD are active high by default */
+		state.detect = !!gpiod_get_value(skt->stat[SOC_STAT_CD].desc);
 	if (skt->stat[SOC_STAT_RDY].desc)
 		state.ready = !!gpiod_get_value(skt->stat[SOC_STAT_RDY].desc);
 	if (skt->stat[SOC_STAT_BVD1].desc)
-- 
2.1.0


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

* [PATCH 11/33] pcmcia: soc_common: request legacy detect GPIO with active low
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Request the legacy card detect signal with the active low property and
remove our own negation of the detection value.  This allows us to use
the firmware-defined polarities rather than hard-coding it into the
driver.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 5d167512e96e..edfb6045fcda 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -168,7 +168,13 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
 	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
 		if (gpio_is_valid(skt->stat[i].gpio)) {
-			ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
+			unsigned long flags = GPIOF_IN;
+
+			/* CD is active low by default */
+			if (i == SOC_STAT_CD)
+				flags |= GPIOF_ACTIVE_LOW;
+
+			ret = gpio_request_one(skt->stat[i].gpio, flags,
 					       skt->stat[i].name);
 			if (ret) {
 				__soc_pcmcia_hw_shutdown(skt, i);
@@ -235,11 +241,8 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 	state.bvd1 = 1;
 	state.bvd2 = 1;
 
-	/* CD is active low by default */
 	if (skt->stat[SOC_STAT_CD].desc)
-		state.detect = !gpiod_get_raw_value(skt->stat[SOC_STAT_CD].desc);
-
-	/* RDY and BVD are active high by default */
+		state.detect = !!gpiod_get_value(skt->stat[SOC_STAT_CD].desc);
 	if (skt->stat[SOC_STAT_RDY].desc)
 		state.ready = !!gpiod_get_value(skt->stat[SOC_STAT_RDY].desc);
 	if (skt->stat[SOC_STAT_BVD1].desc)
-- 
2.1.0

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

* [PATCH 12/33] pcmcia: soc_common: add support for reset and bus enable GPIOs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add support to soc_common for controlling reset and bus enable GPIOs
from within the generic soc_common layer, rather than having
individual drivers having to perform this themselves.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 20 ++++++++++++++++++++
 drivers/pcmcia/soc_common.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index edfb6045fcda..822de207c408 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -122,6 +122,11 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
 	if (skt->ops->hw_shutdown)
 		skt->ops->hw_shutdown(skt);
 
+	if (skt->gpio_reset)
+		gpiod_put(skt->gpio_reset);
+	if (skt->gpio_bus_enable)
+		gpiod_put(skt->gpio_bus_enable);
+
 	clk_disable_unprepare(skt->clk);
 }
 
@@ -288,6 +293,21 @@ static int soc_common_pcmcia_config_skt(
 
 	ret = skt->ops->configure_socket(skt, state);
 	if (ret == 0) {
+		struct gpio_desc *descs[2];
+		int values[2], n = 0;
+
+		if (skt->gpio_reset) {
+			descs[n] = skt->gpio_reset;
+			values[n++] = !!(state->flags & SS_RESET);
+		}
+		if (skt->gpio_bus_enable) {
+			descs[n] = skt->gpio_bus_enable;
+			values[n++] = !!(state->flags & SS_OUTPUT_ENA);
+		}
+
+		if (n)
+			gpiod_set_array_value_cansleep(n, descs, values);
+
 		/*
 		 * This really needs a better solution.  The IRQ
 		 * may or may not be claimed by the driver.
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index ee40db16dc40..686ba3238c76 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -62,6 +62,9 @@ struct soc_pcmcia_socket {
 #define SOC_STAT_BVD2		2	/* BATWARN / IOSPKR */
 #define SOC_STAT_RDY		3	/* Ready / Interrupt */
 
+	struct gpio_desc	*gpio_reset;
+	struct gpio_desc	*gpio_bus_enable;
+
 	unsigned int		irq_state;
 
 	struct timer_list	poll_timer;
-- 
2.1.0


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

* [PATCH 12/33] pcmcia: soc_common: add support for reset and bus enable GPIOs
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Add support to soc_common for controlling reset and bus enable GPIOs
from within the generic soc_common layer, rather than having
individual drivers having to perform this themselves.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 20 ++++++++++++++++++++
 drivers/pcmcia/soc_common.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index edfb6045fcda..822de207c408 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -122,6 +122,11 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
 	if (skt->ops->hw_shutdown)
 		skt->ops->hw_shutdown(skt);
 
+	if (skt->gpio_reset)
+		gpiod_put(skt->gpio_reset);
+	if (skt->gpio_bus_enable)
+		gpiod_put(skt->gpio_bus_enable);
+
 	clk_disable_unprepare(skt->clk);
 }
 
@@ -288,6 +293,21 @@ static int soc_common_pcmcia_config_skt(
 
 	ret = skt->ops->configure_socket(skt, state);
 	if (ret == 0) {
+		struct gpio_desc *descs[2];
+		int values[2], n = 0;
+
+		if (skt->gpio_reset) {
+			descs[n] = skt->gpio_reset;
+			values[n++] = !!(state->flags & SS_RESET);
+		}
+		if (skt->gpio_bus_enable) {
+			descs[n] = skt->gpio_bus_enable;
+			values[n++] = !!(state->flags & SS_OUTPUT_ENA);
+		}
+
+		if (n)
+			gpiod_set_array_value_cansleep(n, descs, values);
+
 		/*
 		 * This really needs a better solution.  The IRQ
 		 * may or may not be claimed by the driver.
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index ee40db16dc40..686ba3238c76 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -62,6 +62,9 @@ struct soc_pcmcia_socket {
 #define SOC_STAT_BVD2		2	/* BATWARN / IOSPKR */
 #define SOC_STAT_RDY		3	/* Ready / Interrupt */
 
+	struct gpio_desc	*gpio_reset;
+	struct gpio_desc	*gpio_bus_enable;
+
 	unsigned int		irq_state;
 
 	struct timer_list	poll_timer;
-- 
2.1.0

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

* [PATCH 13/33] pcmcia: soc_common: restore previous socket state on error
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

If an attempt to set a socket state returns an error, restore the
previous socket state.  If restoring the previous socket state
fails, warn about this.

This allows us to have simple error handling in the socket state
configuration handlers - there is no need for every handler
implementation to manually undo the updates, which can be complex
when regulators are involved.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 822de207c408..d8508c41d7da 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -292,6 +292,14 @@ static int soc_common_pcmcia_config_skt(
 	int ret;
 
 	ret = skt->ops->configure_socket(skt, state);
+	if (ret < 0) {
+		pr_err("soc_common_pcmcia: unable to configure socket %d\n",
+		       skt->nr);
+		/* restore the previous state */
+		WARN_ON(skt->ops->configure_socket(skt, &skt->cs_state));
+		return ret;
+	}
+
 	if (ret == 0) {
 		struct gpio_desc *descs[2];
 		int values[2], n = 0;
@@ -324,10 +332,6 @@ static int soc_common_pcmcia_config_skt(
 		skt->cs_state = *state;
 	}
 
-	if (ret < 0)
-		printk(KERN_ERR "soc_common_pcmcia: unable to configure "
-		       "socket %d\n", skt->nr);
-
 	return ret;
 }
 
@@ -776,6 +780,8 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 {
 	int ret;
 
+	skt->cs_state = dead_socket;
+
 	setup_timer(&skt->poll_timer, soc_common_pcmcia_poll_event,
 		    (unsigned long)skt);
 	skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
-- 
2.1.0


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

* [PATCH 13/33] pcmcia: soc_common: restore previous socket state on error
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

If an attempt to set a socket state returns an error, restore the
previous socket state.  If restoring the previous socket state
fails, warn about this.

This allows us to have simple error handling in the socket state
configuration handlers - there is no need for every handler
implementation to manually undo the updates, which can be complex
when regulators are involved.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 822de207c408..d8508c41d7da 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -292,6 +292,14 @@ static int soc_common_pcmcia_config_skt(
 	int ret;
 
 	ret = skt->ops->configure_socket(skt, state);
+	if (ret < 0) {
+		pr_err("soc_common_pcmcia: unable to configure socket %d\n",
+		       skt->nr);
+		/* restore the previous state */
+		WARN_ON(skt->ops->configure_socket(skt, &skt->cs_state));
+		return ret;
+	}
+
 	if (ret == 0) {
 		struct gpio_desc *descs[2];
 		int values[2], n = 0;
@@ -324,10 +332,6 @@ static int soc_common_pcmcia_config_skt(
 		skt->cs_state = *state;
 	}
 
-	if (ret < 0)
-		printk(KERN_ERR "soc_common_pcmcia: unable to configure "
-		       "socket %d\n", skt->nr);
-
 	return ret;
 }
 
@@ -776,6 +780,8 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 {
 	int ret;
 
+	skt->cs_state = dead_socket;
+
 	setup_timer(&skt->poll_timer, soc_common_pcmcia_poll_event,
 		    (unsigned long)skt);
 	skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
-- 
2.1.0

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

* [PATCH 14/33] pcmcia: soc_common: add CF socket state helper
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a helper to get the voltage state of CF sockets, where the voltage
sense pins are not wired up.  Switch assabet and cerf to use this
helper.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_assabet.c |  9 +--------
 drivers/pcmcia/sa1100_cerf.c    |  9 +--------
 drivers/pcmcia/soc_common.c     | 12 ++++++++++++
 drivers/pcmcia/soc_common.h     |  2 ++
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index 44cfc4416e54..71ace6910d7e 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -31,13 +31,6 @@ static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	return 0;
 }
 
-static void
-assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	state->vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
-	state->vs_Xv  = 0;
-}
-
 static int
 assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
@@ -90,7 +83,7 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 static struct pcmcia_low_level assabet_pcmcia_ops = { 
 	.owner			= THIS_MODULE,
 	.hw_init		= assabet_pcmcia_hw_init,
-	.socket_state		= assabet_pcmcia_socket_state,
+	.socket_state		= soc_common_cf_socket_state,
 	.configure_socket	= assabet_pcmcia_configure_socket,
 	.socket_suspend		= assabet_pcmcia_socket_suspend,
 };
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index b3774e5d0396..c3f67363f6a1 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -45,13 +45,6 @@ static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	gpio_free(CERF_GPIO_CF_RESET);
 }
 
-static void
-cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	state->vs_3v	= 1;
-	state->vs_Xv	= 0;
-}
-
 static int
 cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 			     const socket_state_t *state)
@@ -77,7 +70,7 @@ static struct pcmcia_low_level cerf_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 	.hw_init		= cerf_pcmcia_hw_init,
 	.hw_shutdown		= cerf_pcmcia_hw_shutdown,
-	.socket_state		= cerf_pcmcia_socket_state,
+	.socket_state		= soc_common_cf_socket_state,
 	.configure_socket	= cerf_pcmcia_configure_socket,
 };
 
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index d8508c41d7da..f880f805c2ca 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -235,6 +235,18 @@ static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
 			irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
 }
 
+/*
+ * The CF 3.0 specification says that cards tie VS1 to ground and leave
+ * VS2 open.  Many implementations do not wire up the VS signals, so we
+ * provide hard-coded values as per the CF 3.0 spec.
+ */
+void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
+	struct pcmcia_state *state)
+{
+	state->vs_3v = 1;
+}
+EXPORT_SYMBOL_GPL(soc_common_cf_socket_state);
+
 static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 {
 	struct pcmcia_state state;
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 686ba3238c76..39c1e15167f3 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -143,6 +143,8 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
 
+void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
+	struct pcmcia_state *state);
 
 #ifdef CONFIG_PCMCIA_DEBUG
 
-- 
2.1.0


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

* [PATCH 14/33] pcmcia: soc_common: add CF socket state helper
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Add a helper to get the voltage state of CF sockets, where the voltage
sense pins are not wired up.  Switch assabet and cerf to use this
helper.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_assabet.c |  9 +--------
 drivers/pcmcia/sa1100_cerf.c    |  9 +--------
 drivers/pcmcia/soc_common.c     | 12 ++++++++++++
 drivers/pcmcia/soc_common.h     |  2 ++
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index 44cfc4416e54..71ace6910d7e 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -31,13 +31,6 @@ static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	return 0;
 }
 
-static void
-assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	state->vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
-	state->vs_Xv  = 0;
-}
-
 static int
 assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
@@ -90,7 +83,7 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 static struct pcmcia_low_level assabet_pcmcia_ops = { 
 	.owner			= THIS_MODULE,
 	.hw_init		= assabet_pcmcia_hw_init,
-	.socket_state		= assabet_pcmcia_socket_state,
+	.socket_state		= soc_common_cf_socket_state,
 	.configure_socket	= assabet_pcmcia_configure_socket,
 	.socket_suspend		= assabet_pcmcia_socket_suspend,
 };
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index b3774e5d0396..c3f67363f6a1 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -45,13 +45,6 @@ static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 	gpio_free(CERF_GPIO_CF_RESET);
 }
 
-static void
-cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	state->vs_3v	= 1;
-	state->vs_Xv	= 0;
-}
-
 static int
 cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 			     const socket_state_t *state)
@@ -77,7 +70,7 @@ static struct pcmcia_low_level cerf_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 	.hw_init		= cerf_pcmcia_hw_init,
 	.hw_shutdown		= cerf_pcmcia_hw_shutdown,
-	.socket_state		= cerf_pcmcia_socket_state,
+	.socket_state		= soc_common_cf_socket_state,
 	.configure_socket	= cerf_pcmcia_configure_socket,
 };
 
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index d8508c41d7da..f880f805c2ca 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -235,6 +235,18 @@ static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
 			irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
 }
 
+/*
+ * The CF 3.0 specification says that cards tie VS1 to ground and leave
+ * VS2 open.  Many implementations do not wire up the VS signals, so we
+ * provide hard-coded values as per the CF 3.0 spec.
+ */
+void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
+	struct pcmcia_state *state)
+{
+	state->vs_3v = 1;
+}
+EXPORT_SYMBOL_GPL(soc_common_cf_socket_state);
+
 static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 {
 	struct pcmcia_state state;
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 686ba3238c76..39c1e15167f3 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -143,6 +143,8 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
 
+void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
+	struct pcmcia_state *state);
 
 #ifdef CONFIG_PCMCIA_DEBUG
 
-- 
2.1.0

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

* [PATCH 15/33] pcmcia: soc_common: add support for Vcc and Vpp regulators
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add support for handling supply regulators in the soc_common code.  This
allows us to separate out the board specifics for setting voltages from
the PCMCIA code.

We detect when setting a voltage fails, and report this fact - some
platforms have fixed-voltage supplies (eg, for CF sockets at 3.3V) and
we need to ignore attempts to configure for 5V, as per the existing
board specific drivers.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 47 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/pcmcia/soc_common.h | 11 +++++++++++
 2 files changed, 58 insertions(+)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index f880f805c2ca..128d8611f39a 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 
@@ -80,6 +81,50 @@ EXPORT_SYMBOL(soc_pcmcia_debug);
 #define to_soc_pcmcia_socket(x)	\
 	container_of(x, struct soc_pcmcia_socket, socket)
 
+static void soc_pcmcia_regulator_put(struct soc_pcmcia_regulator *r)
+{
+	if (r->reg) {
+		regulator_put(r->reg);
+		r->reg = NULL;
+		r->on = false;
+	}
+}
+
+int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
+	struct soc_pcmcia_regulator *r, int v)
+{
+	bool on;
+	int ret;
+
+	if (!r->reg)
+		return 0;
+
+	on = v != 0;
+	if (r->on == on)
+		return 0;
+
+	if (on) {
+		ret = regulator_set_voltage(r->reg, v * 100000, v * 100000);
+		if (ret) {
+			int vout = regulator_get_voltage(r->reg) / 100000;
+
+			dev_warn(&skt->socket.dev,
+				 "CS requested %s=%u.%uV, applying %u.%uV\n",
+				 r == &skt->vcc ? "Vcc" : "Vpp",
+				 v / 10, v % 10, vout / 10, vout % 10);
+		}
+
+		ret = regulator_enable(r->reg);
+	} else {
+		regulator_disable(r->reg);
+	}
+	if (ret == 0)
+		r->on = on;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(soc_pcmcia_regulator_set);
+
 static unsigned short
 calc_speed(unsigned short *spds, int num, unsigned short dflt)
 {
@@ -126,6 +171,8 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
 		gpiod_put(skt->gpio_reset);
 	if (skt->gpio_bus_enable)
 		gpiod_put(skt->gpio_bus_enable);
+	soc_pcmcia_regulator_put(&skt->vcc);
+	soc_pcmcia_regulator_put(&skt->vpp);
 
 	clk_disable_unprepare(skt->clk);
 }
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 39c1e15167f3..18a6df5ca374 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -19,6 +19,12 @@
 struct device;
 struct gpio_desc;
 struct pcmcia_low_level;
+struct regulator;
+
+struct soc_pcmcia_regulator {
+	struct regulator	*reg;
+	bool			on;
+};
 
 /*
  * This structure encapsulates per-socket state which we might need to
@@ -64,6 +70,8 @@ struct soc_pcmcia_socket {
 
 	struct gpio_desc	*gpio_reset;
 	struct gpio_desc	*gpio_bus_enable;
+	struct soc_pcmcia_regulator vcc;
+	struct soc_pcmcia_regulator vpp;
 
 	unsigned int		irq_state;
 
@@ -146,6 +154,9 @@ int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
 void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
 	struct pcmcia_state *state);
 
+int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
+	struct soc_pcmcia_regulator *r, int v);
+
 #ifdef CONFIG_PCMCIA_DEBUG
 
 extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
-- 
2.1.0


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

* [PATCH 15/33] pcmcia: soc_common: add support for Vcc and Vpp regulators
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for handling supply regulators in the soc_common code.  This
allows us to separate out the board specifics for setting voltages from
the PCMCIA code.

We detect when setting a voltage fails, and report this fact - some
platforms have fixed-voltage supplies (eg, for CF sockets at 3.3V) and
we need to ignore attempts to configure for 5V, as per the existing
board specific drivers.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 47 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/pcmcia/soc_common.h | 11 +++++++++++
 2 files changed, 58 insertions(+)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index f880f805c2ca..128d8611f39a 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -43,6 +43,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 
@@ -80,6 +81,50 @@ EXPORT_SYMBOL(soc_pcmcia_debug);
 #define to_soc_pcmcia_socket(x)	\
 	container_of(x, struct soc_pcmcia_socket, socket)
 
+static void soc_pcmcia_regulator_put(struct soc_pcmcia_regulator *r)
+{
+	if (r->reg) {
+		regulator_put(r->reg);
+		r->reg = NULL;
+		r->on = false;
+	}
+}
+
+int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
+	struct soc_pcmcia_regulator *r, int v)
+{
+	bool on;
+	int ret;
+
+	if (!r->reg)
+		return 0;
+
+	on = v != 0;
+	if (r->on == on)
+		return 0;
+
+	if (on) {
+		ret = regulator_set_voltage(r->reg, v * 100000, v * 100000);
+		if (ret) {
+			int vout = regulator_get_voltage(r->reg) / 100000;
+
+			dev_warn(&skt->socket.dev,
+				 "CS requested %s=%u.%uV, applying %u.%uV\n",
+				 r == &skt->vcc ? "Vcc" : "Vpp",
+				 v / 10, v % 10, vout / 10, vout % 10);
+		}
+
+		ret = regulator_enable(r->reg);
+	} else {
+		regulator_disable(r->reg);
+	}
+	if (ret == 0)
+		r->on = on;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(soc_pcmcia_regulator_set);
+
 static unsigned short
 calc_speed(unsigned short *spds, int num, unsigned short dflt)
 {
@@ -126,6 +171,8 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
 		gpiod_put(skt->gpio_reset);
 	if (skt->gpio_bus_enable)
 		gpiod_put(skt->gpio_bus_enable);
+	soc_pcmcia_regulator_put(&skt->vcc);
+	soc_pcmcia_regulator_put(&skt->vpp);
 
 	clk_disable_unprepare(skt->clk);
 }
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 39c1e15167f3..18a6df5ca374 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -19,6 +19,12 @@
 struct device;
 struct gpio_desc;
 struct pcmcia_low_level;
+struct regulator;
+
+struct soc_pcmcia_regulator {
+	struct regulator	*reg;
+	bool			on;
+};
 
 /*
  * This structure encapsulates per-socket state which we might need to
@@ -64,6 +70,8 @@ struct soc_pcmcia_socket {
 
 	struct gpio_desc	*gpio_reset;
 	struct gpio_desc	*gpio_bus_enable;
+	struct soc_pcmcia_regulator vcc;
+	struct soc_pcmcia_regulator vpp;
 
 	unsigned int		irq_state;
 
@@ -146,6 +154,9 @@ int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
 void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
 	struct pcmcia_state *state);
 
+int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
+	struct soc_pcmcia_regulator *r, int v);
+
 #ifdef CONFIG_PCMCIA_DEBUG
 
 extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,
-- 
2.1.0

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

* [PATCH 16/33] pcmcia: soc_common: switch to a per-socket cpufreq notifier
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Switch to a per-socket cpufreq notifier rather than a global notifier.
This allows each socket to be self-contained.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 77 ++++++++++++++-------------------------------
 drivers/pcmcia/soc_common.h |  3 ++
 2 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 128d8611f39a..c8111807a6aa 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -750,50 +750,15 @@ static struct pccard_operations soc_common_pcmcia_operations = {
 };
 
 
-static LIST_HEAD(soc_pcmcia_sockets);
-static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
-
 #ifdef CONFIG_CPU_FREQ
-static int
-soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
+static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
+	unsigned long val, void *data)
 {
-	struct soc_pcmcia_socket *skt;
+	struct soc_pcmcia_socket *skt = container_of(nb, struct soc_pcmcia_socket, cpufreq_nb);
 	struct cpufreq_freqs *freqs = data;
-	int ret = 0;
-
-	mutex_lock(&soc_pcmcia_sockets_lock);
-	list_for_each_entry(skt, &soc_pcmcia_sockets, node)
-		if (skt->ops->frequency_change)
-			ret += skt->ops->frequency_change(skt, val, freqs);
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
-	return ret;
-}
-
-static struct notifier_block soc_pcmcia_notifier_block = {
-	.notifier_call	= soc_pcmcia_notifier
-};
 
-static int soc_pcmcia_cpufreq_register(void)
-{
-	int ret;
-
-	ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
-					CPUFREQ_TRANSITION_NOTIFIER);
-	if (ret < 0)
-		printk(KERN_ERR "Unable to register CPU frequency change "
-				"notifier for PCMCIA (%d)\n", ret);
-	return ret;
-}
-fs_initcall(soc_pcmcia_cpufreq_register);
-
-static void soc_pcmcia_cpufreq_unregister(void)
-{
-	cpufreq_unregister_notifier(&soc_pcmcia_notifier_block,
-		CPUFREQ_TRANSITION_NOTIFIER);
+	return skt->ops->frequency_change(skt, val, freqs);
 }
-module_exit(soc_pcmcia_cpufreq_unregister);
-
 #endif
 
 void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
@@ -813,19 +778,21 @@ EXPORT_SYMBOL(soc_pcmcia_init_one);
 
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 {
-	mutex_lock(&soc_pcmcia_sockets_lock);
 	del_timer_sync(&skt->poll_timer);
 
 	pcmcia_unregister_socket(&skt->socket);
 
+#ifdef CONFIG_CPU_FREQ
+	if (skt->ops->frequency_change)
+		cpufreq_unregister_notifier(&skt->cpufreq_nb,
+					    CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+
 	soc_pcmcia_hw_shutdown(skt);
 
 	/* should not be required; violates some lowlevel drivers */
 	soc_common_pcmcia_config_skt(skt, &dead_socket);
 
-	list_del(&skt->node);
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
 	iounmap(skt->virt_io);
 	skt->virt_io = NULL;
 	release_resource(&skt->res_attr);
@@ -867,10 +834,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 		goto out_err_5;
 	}
 
-	mutex_lock(&soc_pcmcia_sockets_lock);
-
-	list_add(&skt->node, &soc_pcmcia_sockets);
-
 	/*
 	 * We initialize default socket timing here, because
 	 * we are not guaranteed to see a SetIOMap operation at
@@ -891,14 +854,23 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 
 	skt->status = soc_common_pcmcia_skt_state(skt);
 
+#ifdef CONFIG_CPU_FREQ
+	if (skt->ops->frequency_change) {
+		skt->cpufreq_nb.notifier_call = soc_common_pcmcia_cpufreq_nb;
+
+		ret = cpufreq_register_notifier(&skt->cpufreq_nb,
+						CPUFREQ_TRANSITION_NOTIFIER);
+		if (ret < 0)
+			dev_err(skt->socket.dev.parent,
+				"unable to register CPU frequency change notifier for PCMCIA (%d)\n",
+				ret);
+	}
+#endif
+
 	ret = pcmcia_register_socket(&skt->socket);
 	if (ret)
 		goto out_err_7;
 
-	add_timer(&skt->poll_timer);
-
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
 	ret = device_create_file(&skt->socket.dev, &dev_attr_status);
 	if (ret)
 		goto out_err_8;
@@ -906,15 +878,12 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 	return ret;
 
  out_err_8:
-	mutex_lock(&soc_pcmcia_sockets_lock);
 	del_timer_sync(&skt->poll_timer);
 	pcmcia_unregister_socket(&skt->socket);
 
  out_err_7:
 	soc_pcmcia_hw_shutdown(skt);
  out_err_6:
-	list_del(&skt->node);
-	mutex_unlock(&soc_pcmcia_sockets_lock);
 	iounmap(skt->virt_io);
  out_err_5:
 	release_resource(&skt->res_attr);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 18a6df5ca374..f66e2fb1f33f 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -75,6 +75,9 @@ struct soc_pcmcia_socket {
 
 	unsigned int		irq_state;
 
+#ifdef CONFIG_CPU_FREQ
+	struct notifier_block	cpufreq_nb;
+#endif
 	struct timer_list	poll_timer;
 	struct list_head	node;
 };
-- 
2.1.0


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

* [PATCH 16/33] pcmcia: soc_common: switch to a per-socket cpufreq notifier
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Switch to a per-socket cpufreq notifier rather than a global notifier.
This allows each socket to be self-contained.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 77 ++++++++++++++-------------------------------
 drivers/pcmcia/soc_common.h |  3 ++
 2 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 128d8611f39a..c8111807a6aa 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -750,50 +750,15 @@ static struct pccard_operations soc_common_pcmcia_operations = {
 };
 
 
-static LIST_HEAD(soc_pcmcia_sockets);
-static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
-
 #ifdef CONFIG_CPU_FREQ
-static int
-soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
+static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
+	unsigned long val, void *data)
 {
-	struct soc_pcmcia_socket *skt;
+	struct soc_pcmcia_socket *skt = container_of(nb, struct soc_pcmcia_socket, cpufreq_nb);
 	struct cpufreq_freqs *freqs = data;
-	int ret = 0;
-
-	mutex_lock(&soc_pcmcia_sockets_lock);
-	list_for_each_entry(skt, &soc_pcmcia_sockets, node)
-		if (skt->ops->frequency_change)
-			ret += skt->ops->frequency_change(skt, val, freqs);
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
-	return ret;
-}
-
-static struct notifier_block soc_pcmcia_notifier_block = {
-	.notifier_call	= soc_pcmcia_notifier
-};
 
-static int soc_pcmcia_cpufreq_register(void)
-{
-	int ret;
-
-	ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
-					CPUFREQ_TRANSITION_NOTIFIER);
-	if (ret < 0)
-		printk(KERN_ERR "Unable to register CPU frequency change "
-				"notifier for PCMCIA (%d)\n", ret);
-	return ret;
-}
-fs_initcall(soc_pcmcia_cpufreq_register);
-
-static void soc_pcmcia_cpufreq_unregister(void)
-{
-	cpufreq_unregister_notifier(&soc_pcmcia_notifier_block,
-		CPUFREQ_TRANSITION_NOTIFIER);
+	return skt->ops->frequency_change(skt, val, freqs);
 }
-module_exit(soc_pcmcia_cpufreq_unregister);
-
 #endif
 
 void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
@@ -813,19 +778,21 @@ EXPORT_SYMBOL(soc_pcmcia_init_one);
 
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 {
-	mutex_lock(&soc_pcmcia_sockets_lock);
 	del_timer_sync(&skt->poll_timer);
 
 	pcmcia_unregister_socket(&skt->socket);
 
+#ifdef CONFIG_CPU_FREQ
+	if (skt->ops->frequency_change)
+		cpufreq_unregister_notifier(&skt->cpufreq_nb,
+					    CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+
 	soc_pcmcia_hw_shutdown(skt);
 
 	/* should not be required; violates some lowlevel drivers */
 	soc_common_pcmcia_config_skt(skt, &dead_socket);
 
-	list_del(&skt->node);
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
 	iounmap(skt->virt_io);
 	skt->virt_io = NULL;
 	release_resource(&skt->res_attr);
@@ -867,10 +834,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 		goto out_err_5;
 	}
 
-	mutex_lock(&soc_pcmcia_sockets_lock);
-
-	list_add(&skt->node, &soc_pcmcia_sockets);
-
 	/*
 	 * We initialize default socket timing here, because
 	 * we are not guaranteed to see a SetIOMap operation at
@@ -891,14 +854,23 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 
 	skt->status = soc_common_pcmcia_skt_state(skt);
 
+#ifdef CONFIG_CPU_FREQ
+	if (skt->ops->frequency_change) {
+		skt->cpufreq_nb.notifier_call = soc_common_pcmcia_cpufreq_nb;
+
+		ret = cpufreq_register_notifier(&skt->cpufreq_nb,
+						CPUFREQ_TRANSITION_NOTIFIER);
+		if (ret < 0)
+			dev_err(skt->socket.dev.parent,
+				"unable to register CPU frequency change notifier for PCMCIA (%d)\n",
+				ret);
+	}
+#endif
+
 	ret = pcmcia_register_socket(&skt->socket);
 	if (ret)
 		goto out_err_7;
 
-	add_timer(&skt->poll_timer);
-
-	mutex_unlock(&soc_pcmcia_sockets_lock);
-
 	ret = device_create_file(&skt->socket.dev, &dev_attr_status);
 	if (ret)
 		goto out_err_8;
@@ -906,15 +878,12 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 	return ret;
 
  out_err_8:
-	mutex_lock(&soc_pcmcia_sockets_lock);
 	del_timer_sync(&skt->poll_timer);
 	pcmcia_unregister_socket(&skt->socket);
 
  out_err_7:
 	soc_pcmcia_hw_shutdown(skt);
  out_err_6:
-	list_del(&skt->node);
-	mutex_unlock(&soc_pcmcia_sockets_lock);
 	iounmap(skt->virt_io);
  out_err_5:
 	release_resource(&skt->res_attr);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 18a6df5ca374..f66e2fb1f33f 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -75,6 +75,9 @@ struct soc_pcmcia_socket {
 
 	unsigned int		irq_state;
 
+#ifdef CONFIG_CPU_FREQ
+	struct notifier_block	cpufreq_nb;
+#endif
 	struct timer_list	poll_timer;
 	struct list_head	node;
 };
-- 
2.1.0

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

* [PATCH 17/33] pcmcia: soc_common: constify pcmcia_low_level ops pointer
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Constify the pcmcia_low_level operation pointer to soc_pcmcia_init_one()
which has no need to modify it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 2 +-
 drivers/pcmcia/soc_common.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index c8111807a6aa..13bd50df9294 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -762,7 +762,7 @@ static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
 #endif
 
 void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
-	struct pcmcia_low_level *ops, struct device *dev)
+	const struct pcmcia_low_level *ops, struct device *dev)
 {
 	int i;
 
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index f66e2fb1f33f..7833eae86960 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -149,7 +149,7 @@ struct soc_pcmcia_timing {
 extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
 
 void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
-	struct pcmcia_low_level *ops, struct device *dev);
+	const struct pcmcia_low_level *ops, struct device *dev);
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
-- 
2.1.0


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

* [PATCH 17/33] pcmcia: soc_common: constify pcmcia_low_level ops pointer
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Constify the pcmcia_low_level operation pointer to soc_pcmcia_init_one()
which has no need to modify it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/soc_common.c | 2 +-
 drivers/pcmcia/soc_common.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index c8111807a6aa..13bd50df9294 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -762,7 +762,7 @@ static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
 #endif
 
 void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
-	struct pcmcia_low_level *ops, struct device *dev)
+	const struct pcmcia_low_level *ops, struct device *dev)
 {
 	int i;
 
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index f66e2fb1f33f..7833eae86960 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -149,7 +149,7 @@ struct soc_pcmcia_timing {
 extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
 
 void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
-	struct pcmcia_low_level *ops, struct device *dev);
+	const struct pcmcia_low_level *ops, struct device *dev);
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
-- 
2.1.0

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

* [PATCH 18/33] pcmcia: sa1100: provide generic CF support
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Provide generic non-voltage sensing socket support for StrongARM
platforms using the gpiolib and regulator subsystems to obtain the
resources to control the socket.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_generic.c | 120 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 115 insertions(+), 5 deletions(-)

diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 66acdc85727c..21ccf6360b3e 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -31,7 +31,9 @@
 ======================================================================*/
 
 #include <linux/module.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 
@@ -41,9 +43,78 @@
 
 #include "sa1100_generic.h"
 
+static const char *gpio_name[] = {
+	[SOC_STAT_CD] = "detect",
+	[SOC_STAT_BVD1] = "bvd1",
+	[SOC_STAT_BVD2] = "bvd2",
+	[SOC_STAT_RDY] = "ready",
+};
+
+static int sa11x0_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct device *dev = skt->socket.dev.parent;
+	int i;
+
+	skt->gpio_reset = gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(skt->gpio_reset))
+		return PTR_ERR(skt->gpio_reset);
+
+	skt->gpio_bus_enable = gpiod_get_optional(dev, "bus-enable",
+						  GPIOD_OUT_HIGH);
+	if (IS_ERR(skt->gpio_bus_enable)) {
+		gpiod_put(skt->gpio_reset);
+		return PTR_ERR(skt->gpio_bus_enable);
+	}
+
+	skt->vcc.reg = regulator_get_optional(dev, "vcc");
+	if (IS_ERR(skt->vcc.reg)) {
+		if (skt->gpio_bus_enable)
+			gpiod_put(skt->gpio_bus_enable);
+		gpiod_put(skt->gpio_reset);
+		return PTR_ERR(skt->vcc.reg);
+	}
+
+	if (!skt->vcc.reg)
+		dev_warn(dev,
+			 "no Vcc regulator provided, ignoring Vcc controls\n");
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
+		skt->stat[i].name = gpio_name[i];
+		skt->stat[i].desc = gpiod_get_optional(dev, gpio_name[i],
+						       GPIOD_IN);
+		if (IS_ERR(skt->stat[i].desc)) {
+			int err = PTR_ERR(skt->stat[i].desc);
+
+			while (--i >= 0) {
+				if (skt->stat[i].desc)
+					gpiod_put(skt->stat[i].desc);
+			}
+			if (skt->gpio_bus_enable)
+				gpiod_put(skt->gpio_bus_enable);
+			gpiod_put(skt->gpio_reset);
+
+			return err;
+		}
+	}
+	return 0;
+}
+
+static int sa11x0_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+	const socket_state_t *state)
+{
+	return soc_pcmcia_regulator_set(skt, &skt->vcc, state->Vcc);
+}
+
+static struct pcmcia_low_level sa11x0_ops = {
+	.owner = THIS_MODULE,
+	.hw_init = sa11x0_pcmcia_hw_init,
+	.socket_state = soc_common_cf_socket_state,
+	.configure_socket = sa11x0_pcmcia_configure_socket,
+};
+
 int __init pcmcia_collie_init(struct device *dev);
 
-static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
+static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
 #ifdef CONFIG_SA1100_ASSABET
 	pcmcia_assabet_init,
 #endif
@@ -67,15 +138,15 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
 #endif
 };
 
-static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
+static int sa11x0_drv_pcmcia_legacy_probe(struct platform_device *dev)
 {
 	int i, ret = -ENODEV;
 
 	/*
 	 * Initialise any "on-board" PCMCIA sockets.
 	 */
-	for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
-		ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
+	for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_legacy_hw_init); i++) {
+		ret = sa11x0_pcmcia_legacy_hw_init[i](&dev->dev);
 		if (ret == 0)
 			break;
 	}
@@ -83,7 +154,7 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
 	return ret;
 }
 
-static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+static int sa11x0_drv_pcmcia_legacy_remove(struct platform_device *dev)
 {
 	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
 	int i;
@@ -96,6 +167,45 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
 	return 0;
 }
 
+static int sa11x0_drv_pcmcia_probe(struct platform_device *pdev)
+{
+	struct soc_pcmcia_socket *skt;
+	struct device *dev = &pdev->dev;
+
+	if (dev->id == -1)
+		return sa11x0_drv_pcmcia_legacy_probe(pdev);
+
+	skt = devm_kzalloc(dev, sizeof(*skt), GFP_KERNEL);
+	if (!skt)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, skt);
+
+	skt->nr = pdev->id;
+	skt->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(skt->clk))
+		return PTR_ERR(skt->clk);
+
+	sa11xx_drv_pcmcia_ops(&sa11x0_ops);
+	soc_pcmcia_init_one(skt, &sa11x0_ops, dev);
+
+	return sa11xx_drv_pcmcia_add_one(skt);
+}
+
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+	struct soc_pcmcia_socket *skt;
+
+	if (dev->id == -1)
+		return sa11x0_drv_pcmcia_legacy_remove(dev);
+
+	skt = platform_get_drvdata(dev);
+
+	soc_pcmcia_remove_one(skt);
+
+	return 0;
+}
+
 static struct platform_driver sa11x0_pcmcia_driver = {
 	.driver = {
 		.name		= "sa11x0-pcmcia",
-- 
2.1.0


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

* [PATCH 18/33] pcmcia: sa1100: provide generic CF support
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Provide generic non-voltage sensing socket support for StrongARM
platforms using the gpiolib and regulator subsystems to obtain the
resources to control the socket.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_generic.c | 120 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 115 insertions(+), 5 deletions(-)

diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 66acdc85727c..21ccf6360b3e 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -31,7 +31,9 @@
 ======================================================================*/
 
 #include <linux/module.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 
@@ -41,9 +43,78 @@
 
 #include "sa1100_generic.h"
 
+static const char *gpio_name[] = {
+	[SOC_STAT_CD] = "detect",
+	[SOC_STAT_BVD1] = "bvd1",
+	[SOC_STAT_BVD2] = "bvd2",
+	[SOC_STAT_RDY] = "ready",
+};
+
+static int sa11x0_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct device *dev = skt->socket.dev.parent;
+	int i;
+
+	skt->gpio_reset = gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(skt->gpio_reset))
+		return PTR_ERR(skt->gpio_reset);
+
+	skt->gpio_bus_enable = gpiod_get_optional(dev, "bus-enable",
+						  GPIOD_OUT_HIGH);
+	if (IS_ERR(skt->gpio_bus_enable)) {
+		gpiod_put(skt->gpio_reset);
+		return PTR_ERR(skt->gpio_bus_enable);
+	}
+
+	skt->vcc.reg = regulator_get_optional(dev, "vcc");
+	if (IS_ERR(skt->vcc.reg)) {
+		if (skt->gpio_bus_enable)
+			gpiod_put(skt->gpio_bus_enable);
+		gpiod_put(skt->gpio_reset);
+		return PTR_ERR(skt->vcc.reg);
+	}
+
+	if (!skt->vcc.reg)
+		dev_warn(dev,
+			 "no Vcc regulator provided, ignoring Vcc controls\n");
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
+		skt->stat[i].name = gpio_name[i];
+		skt->stat[i].desc = gpiod_get_optional(dev, gpio_name[i],
+						       GPIOD_IN);
+		if (IS_ERR(skt->stat[i].desc)) {
+			int err = PTR_ERR(skt->stat[i].desc);
+
+			while (--i >= 0) {
+				if (skt->stat[i].desc)
+					gpiod_put(skt->stat[i].desc);
+			}
+			if (skt->gpio_bus_enable)
+				gpiod_put(skt->gpio_bus_enable);
+			gpiod_put(skt->gpio_reset);
+
+			return err;
+		}
+	}
+	return 0;
+}
+
+static int sa11x0_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+	const socket_state_t *state)
+{
+	return soc_pcmcia_regulator_set(skt, &skt->vcc, state->Vcc);
+}
+
+static struct pcmcia_low_level sa11x0_ops = {
+	.owner = THIS_MODULE,
+	.hw_init = sa11x0_pcmcia_hw_init,
+	.socket_state = soc_common_cf_socket_state,
+	.configure_socket = sa11x0_pcmcia_configure_socket,
+};
+
 int __init pcmcia_collie_init(struct device *dev);
 
-static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
+static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
 #ifdef CONFIG_SA1100_ASSABET
 	pcmcia_assabet_init,
 #endif
@@ -67,15 +138,15 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
 #endif
 };
 
-static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
+static int sa11x0_drv_pcmcia_legacy_probe(struct platform_device *dev)
 {
 	int i, ret = -ENODEV;
 
 	/*
 	 * Initialise any "on-board" PCMCIA sockets.
 	 */
-	for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
-		ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
+	for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_legacy_hw_init); i++) {
+		ret = sa11x0_pcmcia_legacy_hw_init[i](&dev->dev);
 		if (ret == 0)
 			break;
 	}
@@ -83,7 +154,7 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
 	return ret;
 }
 
-static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+static int sa11x0_drv_pcmcia_legacy_remove(struct platform_device *dev)
 {
 	struct skt_dev_info *sinfo = platform_get_drvdata(dev);
 	int i;
@@ -96,6 +167,45 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
 	return 0;
 }
 
+static int sa11x0_drv_pcmcia_probe(struct platform_device *pdev)
+{
+	struct soc_pcmcia_socket *skt;
+	struct device *dev = &pdev->dev;
+
+	if (dev->id == -1)
+		return sa11x0_drv_pcmcia_legacy_probe(pdev);
+
+	skt = devm_kzalloc(dev, sizeof(*skt), GFP_KERNEL);
+	if (!skt)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, skt);
+
+	skt->nr = pdev->id;
+	skt->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(skt->clk))
+		return PTR_ERR(skt->clk);
+
+	sa11xx_drv_pcmcia_ops(&sa11x0_ops);
+	soc_pcmcia_init_one(skt, &sa11x0_ops, dev);
+
+	return sa11xx_drv_pcmcia_add_one(skt);
+}
+
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+	struct soc_pcmcia_socket *skt;
+
+	if (dev->id == -1)
+		return sa11x0_drv_pcmcia_legacy_remove(dev);
+
+	skt = platform_get_drvdata(dev);
+
+	soc_pcmcia_remove_one(skt);
+
+	return 0;
+}
+
 static struct platform_driver sa11x0_pcmcia_driver = {
 	.driver = {
 		.name		= "sa11x0-pcmcia",
-- 
2.1.0

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

* [PATCH 19/33] pcmcia: sa1111: add driver-data pointer
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a driver-data pointer so that low level drivers can add additional
data to the sa1111 pcmcia socket structure.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1111_generic.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h
index e74ecfdc1b26..0bfc82080c16 100644
--- a/drivers/pcmcia/sa1111_generic.h
+++ b/drivers/pcmcia/sa1111_generic.h
@@ -5,6 +5,7 @@ struct sa1111_pcmcia_socket {
 	struct soc_pcmcia_socket soc;
 	struct sa1111_dev *dev;
 	struct sa1111_pcmcia_socket *next;
+	void *driver_data;
 };
 
 static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s)
-- 
2.1.0


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

* [PATCH 19/33] pcmcia: sa1111: add driver-data pointer
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Add a driver-data pointer so that low level drivers can add additional
data to the sa1111 pcmcia socket structure.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1111_generic.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h
index e74ecfdc1b26..0bfc82080c16 100644
--- a/drivers/pcmcia/sa1111_generic.h
+++ b/drivers/pcmcia/sa1111_generic.h
@@ -5,6 +5,7 @@ struct sa1111_pcmcia_socket {
 	struct soc_pcmcia_socket soc;
 	struct sa1111_dev *dev;
 	struct sa1111_pcmcia_socket *next;
+	void *driver_data;
 };
 
 static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s)
-- 
2.1.0

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

* [PATCH 20/33] pcmcia: add MAX1600 driver
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add a driver for the MAX1600 PCMCIA power switch device.  This is a
dual-channel device, controlled via four GPIO signals per channel.
Two signals control the Vcc output, and two control the Vpp output.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/Kconfig   |   3 ++
 drivers/pcmcia/Makefile  |   1 +
 drivers/pcmcia/max1600.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pcmcia/max1600.h |  31 ++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index d3c378b4db6c..8ac7f9f270c8 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -63,6 +63,9 @@ config CARDBUS
 
 	  If unsure, say Y.
 
+config PCMCIA_MAX1600
+	tristate
+
 comment "PC-card bridges"
 
 config YENTA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 27e94b30cf96..56880f354361 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_BFIN_CFPCMCIA)			+= bfin_cf_pcmcia.o
 obj-$(CONFIG_AT91_CF)				+= at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o
 obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)		+= db1xxx_ss.o
+obj-$(CONFIG_PCMCIA_MAX1600)			+= max1600.o
 
 sa1111_cs-y					+= sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1111_neponset.o
diff --git a/drivers/pcmcia/max1600.c b/drivers/pcmcia/max1600.c
new file mode 100644
index 000000000000..476627a29baa
--- /dev/null
+++ b/drivers/pcmcia/max1600.c
@@ -0,0 +1,119 @@
+/*
+ * MAX1600 PCMCIA power switch driver
+ *
+ * Copyright (C) 2016 Russell King
+ */
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+#include "max1600.h"
+
+static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = {
+	{ "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
+	{ "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+	unsigned int channel, unsigned int code)
+{
+	struct max1600 *m;
+	int chan;
+	int i;
+
+	switch (channel) {
+	case MAX1600_CHAN_A:
+		chan = 0;
+		break;
+	case MAX1600_CHAN_B:
+		chan = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH)
+		return -EINVAL;
+
+	m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
+	if (!m)
+		return -ENOMEM;
+
+	m->dev = dev;
+	m->code = code;
+
+	for (i = 0; i < MAX1600_GPIO_MAX; i++) {
+		const char *name;
+
+		name = max1600_gpio_name[chan][i];
+		if (i != MAX1600_GPIO_0VPP) {
+			m->gpio[i] = gpiod_get(dev, name, GPIOD_OUT_LOW);
+		} else {
+			m->gpio[i] = gpiod_get_optional(dev, name, GPIOD_OUT_LOW);
+			if (!m->gpio[i])
+				break;
+		}
+		if (IS_ERR(m->gpio[i]))
+			return PTR_ERR(m->gpio[i]);
+	}
+
+	*ptr = m;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(max1600_init);
+
+int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp)
+{
+	int values[MAX1600_GPIO_MAX], n = MAX1600_GPIO_0VPP;
+
+	if (m->gpio[MAX1600_GPIO_0VPP]) {
+		if (vpp == 0) {
+			values[MAX1600_GPIO_0VPP] = 0;
+			values[MAX1600_GPIO_1VPP] = 0;
+		} else if (vpp == 120) {
+			values[MAX1600_GPIO_0VPP] = 0;
+			values[MAX1600_GPIO_1VPP] = 1;
+		} else if (vpp == vcc) {
+			values[MAX1600_GPIO_0VPP] = 1;
+			values[MAX1600_GPIO_1VPP] = 0;
+		} else {
+			dev_err(m->dev, "unrecognised Vpp %u.%uV\n",
+				vpp / 10, vpp % 10);
+			return -EINVAL;
+		}
+		n = MAX1600_GPIO_MAX;
+	} else if (vpp != vcc && vpp != 0) {
+		dev_err(m->dev, "no VPP control\n");
+		return -EINVAL;
+	}
+
+	if (vcc == 0) {
+		values[MAX1600_GPIO_0VCC] = 0;
+		values[MAX1600_GPIO_1VCC] = 0;
+	} else if (vcc == 33) { /* VY */
+		values[MAX1600_GPIO_0VCC] = 1;
+		values[MAX1600_GPIO_1VCC] = 0;
+	} else if (vcc == 50) { /* VX */
+		values[MAX1600_GPIO_0VCC] = 0;
+		values[MAX1600_GPIO_1VCC] = 1;
+	} else {
+		dev_err(m->dev, "unrecognised Vcc %u.%uV\n",
+			vcc / 10, vcc % 10);
+		return -EINVAL;
+	}
+
+	if (m->code == MAX1600_CODE_HIGH) {
+		/*
+		 * Cirrus mode appears to be the same as Intel mode,
+		 * except the VCC pins are inverted.
+		 */
+		values[MAX1600_GPIO_0VCC] = !values[MAX1600_GPIO_0VCC];
+		values[MAX1600_GPIO_1VCC] = !values[MAX1600_GPIO_1VCC];
+	}
+
+	gpiod_set_array_value_cansleep(n, m->gpio, values);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(max1600_configure);
diff --git a/drivers/pcmcia/max1600.h b/drivers/pcmcia/max1600.h
new file mode 100644
index 000000000000..a674ddb5784b
--- /dev/null
+++ b/drivers/pcmcia/max1600.h
@@ -0,0 +1,31 @@
+#ifndef MAX1600_H
+#define MAX1600_H
+
+struct gpio_desc;
+
+enum {
+	MAX1600_GPIO_0VCC = 0,
+	MAX1600_GPIO_1VCC,
+	MAX1600_GPIO_0VPP,
+	MAX1600_GPIO_1VPP,
+	MAX1600_GPIO_MAX,
+
+	MAX1600_CHAN_A,
+	MAX1600_CHAN_B,
+
+	MAX1600_CODE_LOW,
+	MAX1600_CODE_HIGH,
+};
+
+struct max1600 {
+	struct gpio_desc *gpio[MAX1600_GPIO_MAX];
+	struct device *dev;
+	unsigned int code;
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+	unsigned int channel, unsigned int code);
+
+int max1600_configure(struct max1600 *, unsigned int vcc, unsigned int vpp);
+
+#endif
-- 
2.1.0


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

* [PATCH 20/33] pcmcia: add MAX1600 driver
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Add a driver for the MAX1600 PCMCIA power switch device.  This is a
dual-channel device, controlled via four GPIO signals per channel.
Two signals control the Vcc output, and two control the Vpp output.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/Kconfig   |   3 ++
 drivers/pcmcia/Makefile  |   1 +
 drivers/pcmcia/max1600.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pcmcia/max1600.h |  31 ++++++++++++
 4 files changed, 154 insertions(+)
 create mode 100644 drivers/pcmcia/max1600.c
 create mode 100644 drivers/pcmcia/max1600.h

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index d3c378b4db6c..8ac7f9f270c8 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -63,6 +63,9 @@ config CARDBUS
 
 	  If unsure, say Y.
 
+config PCMCIA_MAX1600
+	tristate
+
 comment "PC-card bridges"
 
 config YENTA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 27e94b30cf96..56880f354361 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_BFIN_CFPCMCIA)			+= bfin_cf_pcmcia.o
 obj-$(CONFIG_AT91_CF)				+= at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o
 obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)		+= db1xxx_ss.o
+obj-$(CONFIG_PCMCIA_MAX1600)			+= max1600.o
 
 sa1111_cs-y					+= sa1111_generic.o
 sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1111_neponset.o
diff --git a/drivers/pcmcia/max1600.c b/drivers/pcmcia/max1600.c
new file mode 100644
index 000000000000..476627a29baa
--- /dev/null
+++ b/drivers/pcmcia/max1600.c
@@ -0,0 +1,119 @@
+/*
+ * MAX1600 PCMCIA power switch driver
+ *
+ * Copyright (C) 2016 Russell King
+ */
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+#include "max1600.h"
+
+static const char *max1600_gpio_name[2][MAX1600_GPIO_MAX] = {
+	{ "a0vcc", "a1vcc", "a0vpp", "a1vpp" },
+	{ "b0vcc", "b1vcc", "b0vpp", "b1vpp" },
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+	unsigned int channel, unsigned int code)
+{
+	struct max1600 *m;
+	int chan;
+	int i;
+
+	switch (channel) {
+	case MAX1600_CHAN_A:
+		chan = 0;
+		break;
+	case MAX1600_CHAN_B:
+		chan = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (code != MAX1600_CODE_LOW && code != MAX1600_CODE_HIGH)
+		return -EINVAL;
+
+	m = devm_kzalloc(dev, sizeof(*m), GFP_KERNEL);
+	if (!m)
+		return -ENOMEM;
+
+	m->dev = dev;
+	m->code = code;
+
+	for (i = 0; i < MAX1600_GPIO_MAX; i++) {
+		const char *name;
+
+		name = max1600_gpio_name[chan][i];
+		if (i != MAX1600_GPIO_0VPP) {
+			m->gpio[i] = gpiod_get(dev, name, GPIOD_OUT_LOW);
+		} else {
+			m->gpio[i] = gpiod_get_optional(dev, name, GPIOD_OUT_LOW);
+			if (!m->gpio[i])
+				break;
+		}
+		if (IS_ERR(m->gpio[i]))
+			return PTR_ERR(m->gpio[i]);
+	}
+
+	*ptr = m;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(max1600_init);
+
+int max1600_configure(struct max1600 *m, unsigned int vcc, unsigned int vpp)
+{
+	int values[MAX1600_GPIO_MAX], n = MAX1600_GPIO_0VPP;
+
+	if (m->gpio[MAX1600_GPIO_0VPP]) {
+		if (vpp == 0) {
+			values[MAX1600_GPIO_0VPP] = 0;
+			values[MAX1600_GPIO_1VPP] = 0;
+		} else if (vpp == 120) {
+			values[MAX1600_GPIO_0VPP] = 0;
+			values[MAX1600_GPIO_1VPP] = 1;
+		} else if (vpp == vcc) {
+			values[MAX1600_GPIO_0VPP] = 1;
+			values[MAX1600_GPIO_1VPP] = 0;
+		} else {
+			dev_err(m->dev, "unrecognised Vpp %u.%uV\n",
+				vpp / 10, vpp % 10);
+			return -EINVAL;
+		}
+		n = MAX1600_GPIO_MAX;
+	} else if (vpp != vcc && vpp != 0) {
+		dev_err(m->dev, "no VPP control\n");
+		return -EINVAL;
+	}
+
+	if (vcc == 0) {
+		values[MAX1600_GPIO_0VCC] = 0;
+		values[MAX1600_GPIO_1VCC] = 0;
+	} else if (vcc == 33) { /* VY */
+		values[MAX1600_GPIO_0VCC] = 1;
+		values[MAX1600_GPIO_1VCC] = 0;
+	} else if (vcc == 50) { /* VX */
+		values[MAX1600_GPIO_0VCC] = 0;
+		values[MAX1600_GPIO_1VCC] = 1;
+	} else {
+		dev_err(m->dev, "unrecognised Vcc %u.%uV\n",
+			vcc / 10, vcc % 10);
+		return -EINVAL;
+	}
+
+	if (m->code == MAX1600_CODE_HIGH) {
+		/*
+		 * Cirrus mode appears to be the same as Intel mode,
+		 * except the VCC pins are inverted.
+		 */
+		values[MAX1600_GPIO_0VCC] = !values[MAX1600_GPIO_0VCC];
+		values[MAX1600_GPIO_1VCC] = !values[MAX1600_GPIO_1VCC];
+	}
+
+	gpiod_set_array_value_cansleep(n, m->gpio, values);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(max1600_configure);
diff --git a/drivers/pcmcia/max1600.h b/drivers/pcmcia/max1600.h
new file mode 100644
index 000000000000..a674ddb5784b
--- /dev/null
+++ b/drivers/pcmcia/max1600.h
@@ -0,0 +1,31 @@
+#ifndef MAX1600_H
+#define MAX1600_H
+
+struct gpio_desc;
+
+enum {
+	MAX1600_GPIO_0VCC = 0,
+	MAX1600_GPIO_1VCC,
+	MAX1600_GPIO_0VPP,
+	MAX1600_GPIO_1VPP,
+	MAX1600_GPIO_MAX,
+
+	MAX1600_CHAN_A,
+	MAX1600_CHAN_B,
+
+	MAX1600_CODE_LOW,
+	MAX1600_CODE_HIGH,
+};
+
+struct max1600 {
+	struct gpio_desc *gpio[MAX1600_GPIO_MAX];
+	struct device *dev;
+	unsigned int code;
+};
+
+int max1600_init(struct device *dev, struct max1600 **ptr,
+	unsigned int channel, unsigned int code);
+
+int max1600_configure(struct max1600 *, unsigned int vcc, unsigned int vpp);
+
+#endif
-- 
2.1.0

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

* [PATCH 21/33] ARM: sa1100: provide infrastructure to support generic CF sockets
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Provide the SoC-level infrastructure to support the generic CF sockets.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/clock.c   |  2 ++
 arch/arm/mach-sa1100/generic.c | 14 +++++++++++++-
 arch/arm/mach-sa1100/generic.h |  3 +++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 0db46895c82a..f6f75c9325bf 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -137,6 +137,8 @@ static struct clk_lookup sa11xx_clkregs[] = {
 	CLKDEV_INIT("sa1100-rtc", NULL, NULL),
 	CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
 	CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
+	CLKDEV_INIT("sa11x0-pcmcia.0", NULL, &clk_cpu),
+	CLKDEV_INIT("sa11x0-pcmcia.1", NULL, &clk_cpu),
 	/* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
 	CLKDEV_INIT("1800", NULL, &clk_cpu),
 	CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3e09beddb6e8..a005eef1a24e 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -232,11 +233,19 @@ void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
 	sa11x0_register_device(&sa11x0fb_device, inf);
 }
 
+static bool sa11x0pcmcia_legacy = true;
 static struct platform_device sa11x0pcmcia_device = {
 	.name		= "sa11x0-pcmcia",
 	.id		= -1,
 };
 
+void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
+{
+	gpiod_add_lookup_table(table);
+	platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
+	sa11x0pcmcia_legacy = false;
+}
+
 static struct platform_device sa11x0mtd_device = {
 	.name		= "sa1100-mtd",
 	.id		= -1,
@@ -311,7 +320,6 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 	&sa11x0uart1_device,
 	&sa11x0uart3_device,
 	&sa11x0ssp_device,
-	&sa11x0pcmcia_device,
 	&sa11x0rtc_device,
 	&sa11x0dma_device,
 };
@@ -319,6 +327,10 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 static int __init sa1100_init(void)
 {
 	pm_power_off = sa1100_power_off;
+
+	if (sa11x0pcmcia_legacy)
+		platform_device_register(&sa11x0pcmcia_device);
+
 	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
 }
 
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 68199b603ff7..22c432979150 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -46,3 +46,6 @@ static inline int sa11x0_pm_init(void) { return 0; }
 #endif
 
 int sa11xx_clk_init(void);
+
+struct gpiod_lookup_table;
+void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *);
-- 
2.1.0


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

* [PATCH 21/33] ARM: sa1100: provide infrastructure to support generic CF sockets
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Provide the SoC-level infrastructure to support the generic CF sockets.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/clock.c   |  2 ++
 arch/arm/mach-sa1100/generic.c | 14 +++++++++++++-
 arch/arm/mach-sa1100/generic.h |  3 +++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 0db46895c82a..f6f75c9325bf 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -137,6 +137,8 @@ static struct clk_lookup sa11xx_clkregs[] = {
 	CLKDEV_INIT("sa1100-rtc", NULL, NULL),
 	CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
 	CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
+	CLKDEV_INIT("sa11x0-pcmcia.0", NULL, &clk_cpu),
+	CLKDEV_INIT("sa11x0-pcmcia.1", NULL, &clk_cpu),
 	/* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
 	CLKDEV_INIT("1800", NULL, &clk_cpu),
 	CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 3e09beddb6e8..a005eef1a24e 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -232,11 +233,19 @@ void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
 	sa11x0_register_device(&sa11x0fb_device, inf);
 }
 
+static bool sa11x0pcmcia_legacy = true;
 static struct platform_device sa11x0pcmcia_device = {
 	.name		= "sa11x0-pcmcia",
 	.id		= -1,
 };
 
+void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
+{
+	gpiod_add_lookup_table(table);
+	platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
+	sa11x0pcmcia_legacy = false;
+}
+
 static struct platform_device sa11x0mtd_device = {
 	.name		= "sa1100-mtd",
 	.id		= -1,
@@ -311,7 +320,6 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 	&sa11x0uart1_device,
 	&sa11x0uart3_device,
 	&sa11x0ssp_device,
-	&sa11x0pcmcia_device,
 	&sa11x0rtc_device,
 	&sa11x0dma_device,
 };
@@ -319,6 +327,10 @@ static struct platform_device *sa11x0_devices[] __initdata = {
 static int __init sa1100_init(void)
 {
 	pm_power_off = sa1100_power_off;
+
+	if (sa11x0pcmcia_legacy)
+		platform_device_register(&sa11x0pcmcia_device);
+
 	return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
 }
 
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 68199b603ff7..22c432979150 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -46,3 +46,6 @@ static inline int sa11x0_pm_init(void) { return 0; }
 #endif
 
 int sa11xx_clk_init(void);
+
+struct gpiod_lookup_table;
+void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *);
-- 
2.1.0

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

* [PATCH 22/33] ARM: sa1100/assabet: convert to generic CF sockets
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:25     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Convert Assabet to use the generic CF socket support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c              | 61 +++++++++++++++++-
 arch/arm/mach-sa1100/include/mach/assabet.h |  6 --
 drivers/pcmcia/Makefile                     |  1 -
 drivers/pcmcia/sa1100_assabet.c             | 99 -----------------------------
 drivers/pcmcia/sa1100_generic.c             |  3 -
 drivers/pcmcia/sa1100_generic.h             |  1 -
 6 files changed, 60 insertions(+), 111 deletions(-)
 delete mode 100644 drivers/pcmcia/sa1100_assabet.c

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 8f24c84042e0..5c9a1e115847 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio-reg.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/sa11x0-serial.h>
@@ -21,6 +22,8 @@
 #include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/leds.h>
@@ -445,6 +448,51 @@ static struct resource neponset_resources[] = {
 };
 #endif
 
+static struct gpiod_lookup_table assabet_cf_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.1",
+	.table = {
+		GPIO_LOOKUP("gpio", 21, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 22, "detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 24, "bvd2", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 25, "bvd1", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 1, "reset", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 7, "bus-enable", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct regulator_consumer_supply assabet_cf_vcc_consumers[] = {
+	REGULATOR_SUPPLY("vcc", "sa11x0-pcmcia.1"),
+};
+
+static struct fixed_voltage_config assabet_cf_vcc_pdata __initdata = {
+	.supply_name = "cf-power",
+//	.input_supply = "dc5p5v",
+	.microvolts = 3300000,
+	.enable_high = 1,
+};
+
+static int assabet_register_fixed_regulator(int n,
+	struct fixed_voltage_config *cfg,
+	struct regulator_consumer_supply *supplies, unsigned num_supplies)
+{
+	cfg->init_data = kzalloc(sizeof(*cfg->init_data), GFP_KERNEL);
+	if (!cfg->init_data)
+		return -ENOMEM;
+
+	cfg->init_data->constraints.name = cfg->supply_name;
+	cfg->init_data->constraints.min_uV = cfg->microvolts;
+	cfg->init_data->constraints.max_uV = cfg->microvolts;
+	cfg->init_data->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
+	cfg->init_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+	cfg->init_data->consumer_supplies = supplies;
+	cfg->init_data->num_consumer_supplies = num_supplies;
+
+	platform_device_register_resndata(NULL, "reg-fixed-voltage", n,
+					  NULL, 0, cfg, sizeof(*cfg));
+	return 0;
+}
+
 static void __init assabet_init(void)
 {
 	/*
@@ -490,6 +538,11 @@ static void __init assabet_init(void)
 		platform_device_register_simple("neponset", 0,
 			neponset_resources, ARRAY_SIZE(neponset_resources));
 #endif
+	} else {
+		assabet_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
+					 assabet_cf_vcc_consumers,
+					 ARRAY_SIZE(assabet_cf_vcc_consumers));
+
 	}
 
 #ifndef ASSABET_PAL_VIDEO
@@ -501,6 +554,9 @@ static void __init assabet_init(void)
 			    ARRAY_SIZE(assabet_flash_resources));
 	sa11x0_register_irda(&assabet_irda_data);
 	sa11x0_register_mcp(&assabet_mcp_data);
+
+	if (!machine_has_neponset())
+		sa11x0_register_pcmcia(1, &assabet_cf_gpio_table);
 }
 
 /*
@@ -768,6 +824,7 @@ fs_initcall(assabet_leds_init);
 
 void __init assabet_init_irq(void)
 {
+	unsigned int assabet_gpio_base;
 	u32 def_val;
 
 	sa1100_init_irq();
@@ -782,7 +839,9 @@ void __init assabet_init_irq(void)
 	 *
 	 * This must precede any driver calls to BCR_set() or BCR_clear().
 	 */
-	assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+	assabet_gpio_base = assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+
+	assabet_cf_vcc_pdata.gpio = assabet_gpio_base + 0;
 }
 
 MACHINE_START(ASSABET, "Intel-Assabet")
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
index c23fcdb047a5..11e6df79cfe6 100644
--- a/arch/arm/mach-sa1100/include/mach/assabet.h
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -95,10 +95,4 @@ extern void assabet_uda1341_reset(int set);
 #define ASSABET_GPIO_BATT_LOW		GPIO_GPIO (26)	/* Low battery */
 #define ASSABET_GPIO_RCLK		GPIO_GPIO (26)	/* CCLK/2  */
 
-/* These are gpiolib GPIO numbers, not bitmasks */
-#define ASSABET_GPIO_CF_IRQ		21	/* CF IRQ */
-#define ASSABET_GPIO_CF_CD		22	/* CF CD  */
-#define ASSABET_GPIO_CF_BVD2		24	/* CF BVD / IOSPKR */
-#define ASSABET_GPIO_CF_BVD1		25	/* CF BVD / IOSTSCHG */
-
 #endif
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 56880f354361..f2f614abc470 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -46,7 +46,6 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1111_jornada720.o
 sa1111_cs-$(CONFIG_ARCH_LUBBOCK)		+= sa1111_lubbock.o
 
 sa1100_cs-y					+= sa1100_generic.o
-sa1100_cs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
 sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
 sa1100_cs-$(CONFIG_SA1100_COLLIE)		+= pxa2xx_sharpsl.o
 sa1100_cs-$(CONFIG_SA1100_H3100)		+= sa1100_h3600.o
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
deleted file mode 100644
index 71ace6910d7e..000000000000
--- a/drivers/pcmcia/sa1100_assabet.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_assabet.c
- *
- * PCMCIA implementation routines for Assabet
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-
-#include <asm/mach-types.h>
-#include <mach/assabet.h>
-
-#include "sa1100_generic.h"
-
-static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
-	skt->stat[SOC_STAT_CD].name = "CF CD";
-	skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1;
-	skt->stat[SOC_STAT_BVD1].name = "CF BVD1";
-	skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2;
-	skt->stat[SOC_STAT_BVD2].name = "CF BVD2";
-	skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ;
-	skt->stat[SOC_STAT_RDY].name = "CF RDY";
-
-	return 0;
-}
-
-static int
-assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	unsigned int mask;
-
-	switch (state->Vcc) {
-	case 0:
-		mask = 0;
-		break;
-
-	case 50:
-		printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
-			__func__);
-
-	case 33:  /* Can only apply 3.3V to the CF slot. */
-		mask = ASSABET_BCR_CF_PWR;
-		break;
-
-	default:
-		printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__,
-			state->Vcc);
-		return -1;
-	}
-
-	/* Silently ignore Vpp, speaker enable. */
-
-	if (state->flags & SS_RESET)
-		mask |= ASSABET_BCR_CF_RST;
-	if (!(state->flags & SS_OUTPUT_ENA))
-		mask |= ASSABET_BCR_CF_BUS_OFF;
-
-	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
-			ASSABET_BCR_CF_BUS_OFF, mask);
-
-	return 0;
-}
-
-/*
- * Disable card status IRQs on suspend.
- */
-static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	/*
-	 * Tristate the CF bus signals.  Also assert CF
-	 * reset as per user guide page 4-11.
-	 */
-	ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST);
-}
-
-static struct pcmcia_low_level assabet_pcmcia_ops = { 
-	.owner			= THIS_MODULE,
-	.hw_init		= assabet_pcmcia_hw_init,
-	.socket_state		= soc_common_cf_socket_state,
-	.configure_socket	= assabet_pcmcia_configure_socket,
-	.socket_suspend		= assabet_pcmcia_socket_suspend,
-};
-
-int pcmcia_assabet_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_assabet() && !machine_has_neponset())
-		ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1);
-
-	return ret;
-}
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 21ccf6360b3e..00746fef4453 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -115,9 +115,6 @@ static struct pcmcia_low_level sa11x0_ops = {
 int __init pcmcia_collie_init(struct device *dev);
 
 static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
-#ifdef CONFIG_SA1100_ASSABET
-	pcmcia_assabet_init,
-#endif
 #ifdef CONFIG_SA1100_CERF
 	pcmcia_cerf_init,
 #endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index adb08dbc723f..92e0010b4ded 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -5,7 +5,6 @@
  * Declaration for all machine specific init/exit functions.
  */
 extern int pcmcia_adsbitsy_init(struct device *);
-extern int pcmcia_assabet_init(struct device *);
 extern int pcmcia_badge4_init(struct device *);
 extern int pcmcia_cerf_init(struct device *);
 extern int pcmcia_flexanet_init(struct device *);
-- 
2.1.0


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

* [PATCH 22/33] ARM: sa1100/assabet: convert to generic CF sockets
@ 2016-08-29 10:25     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Convert Assabet to use the generic CF socket support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c              | 61 +++++++++++++++++-
 arch/arm/mach-sa1100/include/mach/assabet.h |  6 --
 drivers/pcmcia/Makefile                     |  1 -
 drivers/pcmcia/sa1100_assabet.c             | 99 -----------------------------
 drivers/pcmcia/sa1100_generic.c             |  3 -
 drivers/pcmcia/sa1100_generic.h             |  1 -
 6 files changed, 60 insertions(+), 111 deletions(-)
 delete mode 100644 drivers/pcmcia/sa1100_assabet.c

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 8f24c84042e0..5c9a1e115847 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio-reg.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/sa11x0-serial.h>
@@ -21,6 +22,8 @@
 #include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/leds.h>
@@ -445,6 +448,51 @@ static struct resource neponset_resources[] = {
 };
 #endif
 
+static struct gpiod_lookup_table assabet_cf_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.1",
+	.table = {
+		GPIO_LOOKUP("gpio", 21, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 22, "detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 24, "bvd2", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 25, "bvd1", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 1, "reset", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 7, "bus-enable", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct regulator_consumer_supply assabet_cf_vcc_consumers[] = {
+	REGULATOR_SUPPLY("vcc", "sa11x0-pcmcia.1"),
+};
+
+static struct fixed_voltage_config assabet_cf_vcc_pdata __initdata = {
+	.supply_name = "cf-power",
+//	.input_supply = "dc5p5v",
+	.microvolts = 3300000,
+	.enable_high = 1,
+};
+
+static int assabet_register_fixed_regulator(int n,
+	struct fixed_voltage_config *cfg,
+	struct regulator_consumer_supply *supplies, unsigned num_supplies)
+{
+	cfg->init_data = kzalloc(sizeof(*cfg->init_data), GFP_KERNEL);
+	if (!cfg->init_data)
+		return -ENOMEM;
+
+	cfg->init_data->constraints.name = cfg->supply_name;
+	cfg->init_data->constraints.min_uV = cfg->microvolts;
+	cfg->init_data->constraints.max_uV = cfg->microvolts;
+	cfg->init_data->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
+	cfg->init_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+	cfg->init_data->consumer_supplies = supplies;
+	cfg->init_data->num_consumer_supplies = num_supplies;
+
+	platform_device_register_resndata(NULL, "reg-fixed-voltage", n,
+					  NULL, 0, cfg, sizeof(*cfg));
+	return 0;
+}
+
 static void __init assabet_init(void)
 {
 	/*
@@ -490,6 +538,11 @@ static void __init assabet_init(void)
 		platform_device_register_simple("neponset", 0,
 			neponset_resources, ARRAY_SIZE(neponset_resources));
 #endif
+	} else {
+		assabet_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
+					 assabet_cf_vcc_consumers,
+					 ARRAY_SIZE(assabet_cf_vcc_consumers));
+
 	}
 
 #ifndef ASSABET_PAL_VIDEO
@@ -501,6 +554,9 @@ static void __init assabet_init(void)
 			    ARRAY_SIZE(assabet_flash_resources));
 	sa11x0_register_irda(&assabet_irda_data);
 	sa11x0_register_mcp(&assabet_mcp_data);
+
+	if (!machine_has_neponset())
+		sa11x0_register_pcmcia(1, &assabet_cf_gpio_table);
 }
 
 /*
@@ -768,6 +824,7 @@ fs_initcall(assabet_leds_init);
 
 void __init assabet_init_irq(void)
 {
+	unsigned int assabet_gpio_base;
 	u32 def_val;
 
 	sa1100_init_irq();
@@ -782,7 +839,9 @@ void __init assabet_init_irq(void)
 	 *
 	 * This must precede any driver calls to BCR_set() or BCR_clear().
 	 */
-	assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+	assabet_gpio_base = assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+
+	assabet_cf_vcc_pdata.gpio = assabet_gpio_base + 0;
 }
 
 MACHINE_START(ASSABET, "Intel-Assabet")
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
index c23fcdb047a5..11e6df79cfe6 100644
--- a/arch/arm/mach-sa1100/include/mach/assabet.h
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -95,10 +95,4 @@ extern void assabet_uda1341_reset(int set);
 #define ASSABET_GPIO_BATT_LOW		GPIO_GPIO (26)	/* Low battery */
 #define ASSABET_GPIO_RCLK		GPIO_GPIO (26)	/* CCLK/2  */
 
-/* These are gpiolib GPIO numbers, not bitmasks */
-#define ASSABET_GPIO_CF_IRQ		21	/* CF IRQ */
-#define ASSABET_GPIO_CF_CD		22	/* CF CD  */
-#define ASSABET_GPIO_CF_BVD2		24	/* CF BVD / IOSPKR */
-#define ASSABET_GPIO_CF_BVD1		25	/* CF BVD / IOSTSCHG */
-
 #endif
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 56880f354361..f2f614abc470 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -46,7 +46,6 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1111_jornada720.o
 sa1111_cs-$(CONFIG_ARCH_LUBBOCK)		+= sa1111_lubbock.o
 
 sa1100_cs-y					+= sa1100_generic.o
-sa1100_cs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
 sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
 sa1100_cs-$(CONFIG_SA1100_COLLIE)		+= pxa2xx_sharpsl.o
 sa1100_cs-$(CONFIG_SA1100_H3100)		+= sa1100_h3600.o
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
deleted file mode 100644
index 71ace6910d7e..000000000000
--- a/drivers/pcmcia/sa1100_assabet.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_assabet.c
- *
- * PCMCIA implementation routines for Assabet
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-
-#include <asm/mach-types.h>
-#include <mach/assabet.h>
-
-#include "sa1100_generic.h"
-
-static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
-	skt->stat[SOC_STAT_CD].name = "CF CD";
-	skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1;
-	skt->stat[SOC_STAT_BVD1].name = "CF BVD1";
-	skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2;
-	skt->stat[SOC_STAT_BVD2].name = "CF BVD2";
-	skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ;
-	skt->stat[SOC_STAT_RDY].name = "CF RDY";
-
-	return 0;
-}
-
-static int
-assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	unsigned int mask;
-
-	switch (state->Vcc) {
-	case 0:
-		mask = 0;
-		break;
-
-	case 50:
-		printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n",
-			__func__);
-
-	case 33:  /* Can only apply 3.3V to the CF slot. */
-		mask = ASSABET_BCR_CF_PWR;
-		break;
-
-	default:
-		printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__,
-			state->Vcc);
-		return -1;
-	}
-
-	/* Silently ignore Vpp, speaker enable. */
-
-	if (state->flags & SS_RESET)
-		mask |= ASSABET_BCR_CF_RST;
-	if (!(state->flags & SS_OUTPUT_ENA))
-		mask |= ASSABET_BCR_CF_BUS_OFF;
-
-	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
-			ASSABET_BCR_CF_BUS_OFF, mask);
-
-	return 0;
-}
-
-/*
- * Disable card status IRQs on suspend.
- */
-static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	/*
-	 * Tristate the CF bus signals.  Also assert CF
-	 * reset as per user guide page 4-11.
-	 */
-	ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST);
-}
-
-static struct pcmcia_low_level assabet_pcmcia_ops = { 
-	.owner			= THIS_MODULE,
-	.hw_init		= assabet_pcmcia_hw_init,
-	.socket_state		= soc_common_cf_socket_state,
-	.configure_socket	= assabet_pcmcia_configure_socket,
-	.socket_suspend		= assabet_pcmcia_socket_suspend,
-};
-
-int pcmcia_assabet_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_assabet() && !machine_has_neponset())
-		ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1);
-
-	return ret;
-}
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 21ccf6360b3e..00746fef4453 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -115,9 +115,6 @@ static struct pcmcia_low_level sa11x0_ops = {
 int __init pcmcia_collie_init(struct device *dev);
 
 static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
-#ifdef CONFIG_SA1100_ASSABET
-	pcmcia_assabet_init,
-#endif
 #ifdef CONFIG_SA1100_CERF
 	pcmcia_cerf_init,
 #endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index adb08dbc723f..92e0010b4ded 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -5,7 +5,6 @@
  * Declaration for all machine specific init/exit functions.
  */
 extern int pcmcia_adsbitsy_init(struct device *);
-extern int pcmcia_assabet_init(struct device *);
 extern int pcmcia_badge4_init(struct device *);
 extern int pcmcia_cerf_init(struct device *);
 extern int pcmcia_flexanet_init(struct device *);
-- 
2.1.0

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

* [PATCH 23/33] ARM: sa1100/cerf: convert to generic CF sockets
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Convert Cerf to use the generic CF socket support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/cerf.c     | 18 +++++++--
 drivers/pcmcia/Makefile         |  1 -
 drivers/pcmcia/sa1100_cerf.c    | 85 -----------------------------------------
 drivers/pcmcia/sa1100_generic.c |  3 --
 drivers/pcmcia/sa1100_generic.h |  1 -
 5 files changed, 15 insertions(+), 93 deletions(-)
 delete mode 100644 drivers/pcmcia/sa1100_cerf.c

diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 2d25ececb415..b2a4b41626ef 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/platform_data/sa11x0-serial.h>
@@ -45,6 +46,19 @@ static struct platform_device cerfuart2_device = {
 	.resource	= cerfuart2_resources,
 };
 
+/* Compact Flash */
+static struct gpiod_lookup_table cerf_cf_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.1",
+	.table = {
+		GPIO_LOOKUP("gpio", 19, "bvd2", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 20, "bvd1", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 21, "reset", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 22, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 23, "detect", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /* LEDs */
 struct gpio_led cerf_gpio_leds[] = {
 	{
@@ -151,9 +165,6 @@ static void __init cerf_map_io(void)
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 2); /* disable this and the uart2 device for sa1100_fir */
 	sa1100_register_uart(2, 1);
-
-	/* set some GPDR bits here while it's safe */
-	GPDR |= CERF_GPIO_CF_RESET;
 }
 
 static struct mcp_plat_data cerf_mcp_data = {
@@ -167,6 +178,7 @@ static void __init cerf_init(void)
 	platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
 	sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
 	sa11x0_register_mcp(&cerf_mcp_data);
+	sa11x0_register_pcmcia(1, &cerf_cf_gpio_table);
 }
 
 MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index f2f614abc470..dc6a568e7967 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -46,7 +46,6 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1111_jornada720.o
 sa1111_cs-$(CONFIG_ARCH_LUBBOCK)		+= sa1111_lubbock.o
 
 sa1100_cs-y					+= sa1100_generic.o
-sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
 sa1100_cs-$(CONFIG_SA1100_COLLIE)		+= pxa2xx_sharpsl.o
 sa1100_cs-$(CONFIG_SA1100_H3100)		+= sa1100_h3600.o
 sa1100_cs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
deleted file mode 100644
index c3f67363f6a1..000000000000
--- a/drivers/pcmcia/sa1100_cerf.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_cerf.c
- *
- * PCMCIA implementation routines for CerfBoard
- * Based off the Assabet.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-#include <mach/cerf.h>
-#include "sa1100_generic.h"
-
-#define CERF_SOCKET	1
-
-static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	int ret;
-
-	ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET");
-	if (ret)
-		return ret;
-
-	skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD;
-	skt->stat[SOC_STAT_CD].name = "CF_CD";
-	skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1;
-	skt->stat[SOC_STAT_BVD1].name = "CF_BVD1";
-	skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2;
-	skt->stat[SOC_STAT_BVD2].name = "CF_BVD2";
-	skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ;
-	skt->stat[SOC_STAT_RDY].name = "CF_IRQ";
-
-	return 0;
-}
-
-static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	gpio_free(CERF_GPIO_CF_RESET);
-}
-
-static int
-cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
-			     const socket_state_t *state)
-{
-	switch (state->Vcc) {
-	case 0:
-	case 50:
-	case 33:
-		break;
-
-	default:
-		printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			__func__, state->Vcc);
-		return -1;
-	}
-
-	gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));
-
-	return 0;
-}
-
-static struct pcmcia_low_level cerf_pcmcia_ops = { 
-	.owner			= THIS_MODULE,
-	.hw_init		= cerf_pcmcia_hw_init,
-	.hw_shutdown		= cerf_pcmcia_hw_shutdown,
-	.socket_state		= soc_common_cf_socket_state,
-	.configure_socket	= cerf_pcmcia_configure_socket,
-};
-
-int pcmcia_cerf_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_cerf())
-		ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1);
-
-	return ret;
-}
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 00746fef4453..83b365f060ea 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -115,9 +115,6 @@ static struct pcmcia_low_level sa11x0_ops = {
 int __init pcmcia_collie_init(struct device *dev);
 
 static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
-#ifdef CONFIG_SA1100_CERF
-	pcmcia_cerf_init,
-#endif
 #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
 	pcmcia_h3600_init,
 #endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index 92e0010b4ded..3f5495957ca5 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -6,7 +6,6 @@
  */
 extern int pcmcia_adsbitsy_init(struct device *);
 extern int pcmcia_badge4_init(struct device *);
-extern int pcmcia_cerf_init(struct device *);
 extern int pcmcia_flexanet_init(struct device *);
 extern int pcmcia_freebird_init(struct device *);
 extern int pcmcia_gcplus_init(struct device *);
-- 
2.1.0


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

* [PATCH 23/33] ARM: sa1100/cerf: convert to generic CF sockets
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Convert Cerf to use the generic CF socket support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/cerf.c     | 18 +++++++--
 drivers/pcmcia/Makefile         |  1 -
 drivers/pcmcia/sa1100_cerf.c    | 85 -----------------------------------------
 drivers/pcmcia/sa1100_generic.c |  3 --
 drivers/pcmcia/sa1100_generic.h |  1 -
 5 files changed, 15 insertions(+), 93 deletions(-)
 delete mode 100644 drivers/pcmcia/sa1100_cerf.c

diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 2d25ececb415..b2a4b41626ef 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/platform_data/sa11x0-serial.h>
@@ -45,6 +46,19 @@ static struct platform_device cerfuart2_device = {
 	.resource	= cerfuart2_resources,
 };
 
+/* Compact Flash */
+static struct gpiod_lookup_table cerf_cf_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.1",
+	.table = {
+		GPIO_LOOKUP("gpio", 19, "bvd2", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 20, "bvd1", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 21, "reset", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 22, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 23, "detect", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /* LEDs */
 struct gpio_led cerf_gpio_leds[] = {
 	{
@@ -151,9 +165,6 @@ static void __init cerf_map_io(void)
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 2); /* disable this and the uart2 device for sa1100_fir */
 	sa1100_register_uart(2, 1);
-
-	/* set some GPDR bits here while it's safe */
-	GPDR |= CERF_GPIO_CF_RESET;
 }
 
 static struct mcp_plat_data cerf_mcp_data = {
@@ -167,6 +178,7 @@ static void __init cerf_init(void)
 	platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
 	sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
 	sa11x0_register_mcp(&cerf_mcp_data);
+	sa11x0_register_pcmcia(1, &cerf_cf_gpio_table);
 }
 
 MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index f2f614abc470..dc6a568e7967 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -46,7 +46,6 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1111_jornada720.o
 sa1111_cs-$(CONFIG_ARCH_LUBBOCK)		+= sa1111_lubbock.o
 
 sa1100_cs-y					+= sa1100_generic.o
-sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
 sa1100_cs-$(CONFIG_SA1100_COLLIE)		+= pxa2xx_sharpsl.o
 sa1100_cs-$(CONFIG_SA1100_H3100)		+= sa1100_h3600.o
 sa1100_cs-$(CONFIG_SA1100_H3600)		+= sa1100_h3600.o
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
deleted file mode 100644
index c3f67363f6a1..000000000000
--- a/drivers/pcmcia/sa1100_cerf.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_cerf.c
- *
- * PCMCIA implementation routines for CerfBoard
- * Based off the Assabet.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-#include <mach/cerf.h>
-#include "sa1100_generic.h"
-
-#define CERF_SOCKET	1
-
-static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	int ret;
-
-	ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET");
-	if (ret)
-		return ret;
-
-	skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD;
-	skt->stat[SOC_STAT_CD].name = "CF_CD";
-	skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1;
-	skt->stat[SOC_STAT_BVD1].name = "CF_BVD1";
-	skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2;
-	skt->stat[SOC_STAT_BVD2].name = "CF_BVD2";
-	skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ;
-	skt->stat[SOC_STAT_RDY].name = "CF_IRQ";
-
-	return 0;
-}
-
-static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	gpio_free(CERF_GPIO_CF_RESET);
-}
-
-static int
-cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
-			     const socket_state_t *state)
-{
-	switch (state->Vcc) {
-	case 0:
-	case 50:
-	case 33:
-		break;
-
-	default:
-		printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			__func__, state->Vcc);
-		return -1;
-	}
-
-	gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));
-
-	return 0;
-}
-
-static struct pcmcia_low_level cerf_pcmcia_ops = { 
-	.owner			= THIS_MODULE,
-	.hw_init		= cerf_pcmcia_hw_init,
-	.hw_shutdown		= cerf_pcmcia_hw_shutdown,
-	.socket_state		= soc_common_cf_socket_state,
-	.configure_socket	= cerf_pcmcia_configure_socket,
-};
-
-int pcmcia_cerf_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_cerf())
-		ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1);
-
-	return ret;
-}
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 00746fef4453..83b365f060ea 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -115,9 +115,6 @@ static struct pcmcia_low_level sa11x0_ops = {
 int __init pcmcia_collie_init(struct device *dev);
 
 static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
-#ifdef CONFIG_SA1100_CERF
-	pcmcia_cerf_init,
-#endif
 #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
 	pcmcia_h3600_init,
 #endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index 92e0010b4ded..3f5495957ca5 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -6,7 +6,6 @@
  */
 extern int pcmcia_adsbitsy_init(struct device *);
 extern int pcmcia_badge4_init(struct device *);
-extern int pcmcia_cerf_init(struct device *);
 extern int pcmcia_flexanet_init(struct device *);
 extern int pcmcia_freebird_init(struct device *);
 extern int pcmcia_gcplus_init(struct device *);
-- 
2.1.0

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

* [PATCH 24/33] ARM: sa1100/h3xxx: switch h3xxx PCMCIA to use gpiod APIs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Switch h3xxx's PCMCIA implementation to use the gpiod APIs where
possible.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/h3xxx.c  | 17 +++++++++++++++++
 drivers/pcmcia/sa1100_h3600.c | 16 +++++++---------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index b1d4faa12f9a..31035ab3c095 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
@@ -264,8 +265,24 @@ static struct platform_device *h3xxx_devices[] = {
 	&h3xxx_micro_asic,
 };
 
+static struct gpiod_lookup_table h3xxx_pcmcia_gpio_table = {
+	.dev_id = "sa11x0-pcmcia",
+	.table = {
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD0,
+			    "pcmcia0-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ0,
+			    "pcmcia0-ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD1,
+			    "pcmcia1-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ1,
+			    "pcmcia1-ready", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 void __init h3xxx_mach_init(void)
 {
+	gpiod_add_lookup_table(&h3xxx_pcmcia_gpio_table);
 	sa1100_register_uart_fns(&h3xxx_port_fns);
 	sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
 	platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index 431d8b07cbaf..5a1ebcc1ee22 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -23,13 +23,15 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int err;
 
+	skt->stat[SOC_STAT_CD].name = skt->nr ? "pcmcia1-detect" : "pcmcia0-detect";
+	skt->stat[SOC_STAT_RDY].name = skt->nr ? "pcmcia1-ready" : "pcmcia0-ready";
+
+	err = soc_pcmcia_request_gpiods(skt);
+	if (err)
+		return err;
+
 	switch (skt->nr) {
 	case 0:
-		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA CD0";
-		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";
-
 		err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
 		if (err)
 			goto err01;
@@ -56,10 +58,6 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 			goto err06;
 		break;
 	case 1:
-		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA CD1";
-		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";
 		break;
 	}
 	return 0;
-- 
2.1.0


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

* [PATCH 24/33] ARM: sa1100/h3xxx: switch h3xxx PCMCIA to use gpiod APIs
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Switch h3xxx's PCMCIA implementation to use the gpiod APIs where
possible.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/h3xxx.c  | 17 +++++++++++++++++
 drivers/pcmcia/sa1100_h3600.c | 16 +++++++---------
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index b1d4faa12f9a..31035ab3c095 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -11,6 +11,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
@@ -264,8 +265,24 @@ static struct platform_device *h3xxx_devices[] = {
 	&h3xxx_micro_asic,
 };
 
+static struct gpiod_lookup_table h3xxx_pcmcia_gpio_table = {
+	.dev_id = "sa11x0-pcmcia",
+	.table = {
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD0,
+			    "pcmcia0-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ0,
+			    "pcmcia0-ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD1,
+			    "pcmcia1-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ1,
+			    "pcmcia1-ready", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 void __init h3xxx_mach_init(void)
 {
+	gpiod_add_lookup_table(&h3xxx_pcmcia_gpio_table);
 	sa1100_register_uart_fns(&h3xxx_port_fns);
 	sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
 	platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index 431d8b07cbaf..5a1ebcc1ee22 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -23,13 +23,15 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int err;
 
+	skt->stat[SOC_STAT_CD].name = skt->nr ? "pcmcia1-detect" : "pcmcia0-detect";
+	skt->stat[SOC_STAT_RDY].name = skt->nr ? "pcmcia1-ready" : "pcmcia0-ready";
+
+	err = soc_pcmcia_request_gpiods(skt);
+	if (err)
+		return err;
+
 	switch (skt->nr) {
 	case 0:
-		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA CD0";
-		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";
-
 		err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
 		if (err)
 			goto err01;
@@ -56,10 +58,6 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 			goto err06;
 		break;
 	case 1:
-		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA CD1";
-		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";
 		break;
 	}
 	return 0;
-- 
2.1.0

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

* [PATCH 25/33] ARM: sa1100/nanoengine: convert to generic CF sockets
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Convert nanoengine to use the generic CF socket support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/nanoengine.c  |  23 +++++++
 drivers/pcmcia/sa1100_generic.c    |   3 -
 drivers/pcmcia/sa1100_generic.h    |   1 -
 drivers/pcmcia/sa1100_nanoengine.c | 133 -------------------------------------
 4 files changed, 23 insertions(+), 137 deletions(-)
 delete mode 100644 drivers/pcmcia/sa1100_nanoengine.c

diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index f1cb3784d525..4d35258a7b32 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/mtd/mtd.h>
@@ -99,8 +100,30 @@ static void __init nanoengine_map_io(void)
 	Ser2HSCR0 = 0;
 }
 
+static struct gpiod_lookup_table nanoengine_pcmcia0_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.0",
+	.table = {
+		GPIO_LOOKUP("gpio", 11, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 13, "detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 15, "reset", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table nanoengine_pcmcia1_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.1",
+	.table = {
+		GPIO_LOOKUP("gpio", 12, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 14, "detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 16, "reset", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void __init nanoengine_init(void)
 {
+	sa11x0_register_pcmcia(0, &nanoengine_pcmcia0_gpio_table);
+	sa11x0_register_pcmcia(1, &nanoengine_pcmcia1_gpio_table);
 	sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
 		ARRAY_SIZE(nanoengine_flash_resources));
 }
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 83b365f060ea..a8290973538b 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -118,9 +118,6 @@ static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
 #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
 	pcmcia_h3600_init,
 #endif
-#ifdef CONFIG_SA1100_NANOENGINE
-	pcmcia_nanoengine_init,
-#endif
 #ifdef CONFIG_SA1100_SHANNON
 	pcmcia_shannon_init,
 #endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index 3f5495957ca5..f74b269e87d3 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -11,7 +11,6 @@ extern int pcmcia_freebird_init(struct device *);
 extern int pcmcia_gcplus_init(struct device *);
 extern int pcmcia_graphicsmaster_init(struct device *);
 extern int pcmcia_h3600_init(struct device *);
-extern int pcmcia_nanoengine_init(struct device *);
 extern int pcmcia_pangolin_init(struct device *);
 extern int pcmcia_pfs168_init(struct device *);
 extern int pcmcia_shannon_init(struct device *);
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
deleted file mode 100644
index 35c30ff41e81..000000000000
--- a/drivers/pcmcia/sa1100_nanoengine.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_nanoengine.c
- *
- * PCMCIA implementation routines for BSI nanoEngine.
- *
- * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine
- * board you should carefully read this:
- * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/
- *
- * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
- *
- * Based on original work for kernel 2.4 by
- * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/nanoengine.h>
-
-#include "sa1100_generic.h"
-
-struct nanoengine_pins {
-	unsigned output_pins;
-	unsigned clear_outputs;
-	int gpio_rst;
-	int gpio_cd;
-	int gpio_rdy;
-};
-
-static struct nanoengine_pins nano_skts[] = {
-	{
-		.gpio_rst		= GPIO_PC_RESET0,
-		.gpio_cd		= GPIO_PC_CD0,
-		.gpio_rdy		= GPIO_PC_READY0,
-	}, {
-		.gpio_rst		= GPIO_PC_RESET1,
-		.gpio_cd		= GPIO_PC_CD1,
-		.gpio_rdy		= GPIO_PC_READY1,
-	}
-};
-
-unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
-
-static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	unsigned i = skt->nr;
-	int ret;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return -ENXIO;
-
-	ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW,
-		i ? "PC RST1" : "PC RST0");
-	if (ret)
-		return ret;
-
-	skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd;
-	skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0";
-	skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy;
-	skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0";
-
-	return 0;
-}
-
-static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	gpio_free(nano_skts[skt->nr].gpio_rst);
-}
-
-static int nanoengine_pcmcia_configure_socket(
-	struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return -ENXIO;
-
-	gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));
-
-	return 0;
-}
-
-static void nanoengine_pcmcia_socket_state(
-	struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return;
-
-	state->bvd1 = 1;
-	state->bvd2 = 1;
-	state->vs_3v = 1; /* Can only apply 3.3V */
-	state->vs_Xv = 0;
-}
-
-static struct pcmcia_low_level nanoengine_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-
-	.hw_init		= nanoengine_pcmcia_hw_init,
-	.hw_shutdown		= nanoengine_pcmcia_hw_shutdown,
-
-	.configure_socket	= nanoengine_pcmcia_configure_socket,
-	.socket_state		= nanoengine_pcmcia_socket_state,
-};
-
-int pcmcia_nanoengine_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_nanoengine())
-		ret = sa11xx_drv_pcmcia_probe(
-			dev, &nanoengine_pcmcia_ops, 0, 2);
-
-	return ret;
-}
-
-- 
2.1.0


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

* [PATCH 25/33] ARM: sa1100/nanoengine: convert to generic CF sockets
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Convert nanoengine to use the generic CF socket support.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/nanoengine.c  |  23 +++++++
 drivers/pcmcia/sa1100_generic.c    |   3 -
 drivers/pcmcia/sa1100_generic.h    |   1 -
 drivers/pcmcia/sa1100_nanoengine.c | 133 -------------------------------------
 4 files changed, 23 insertions(+), 137 deletions(-)
 delete mode 100644 drivers/pcmcia/sa1100_nanoengine.c

diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index f1cb3784d525..4d35258a7b32 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/mtd/mtd.h>
@@ -99,8 +100,30 @@ static void __init nanoengine_map_io(void)
 	Ser2HSCR0 = 0;
 }
 
+static struct gpiod_lookup_table nanoengine_pcmcia0_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.0",
+	.table = {
+		GPIO_LOOKUP("gpio", 11, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 13, "detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 15, "reset", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table nanoengine_pcmcia1_gpio_table = {
+	.dev_id = "sa11x0-pcmcia.1",
+	.table = {
+		GPIO_LOOKUP("gpio", 12, "ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 14, "detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 16, "reset", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void __init nanoengine_init(void)
 {
+	sa11x0_register_pcmcia(0, &nanoengine_pcmcia0_gpio_table);
+	sa11x0_register_pcmcia(1, &nanoengine_pcmcia1_gpio_table);
 	sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
 		ARRAY_SIZE(nanoengine_flash_resources));
 }
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index 83b365f060ea..a8290973538b 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -118,9 +118,6 @@ static int (*sa11x0_pcmcia_legacy_hw_init[])(struct device *dev) = {
 #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
 	pcmcia_h3600_init,
 #endif
-#ifdef CONFIG_SA1100_NANOENGINE
-	pcmcia_nanoengine_init,
-#endif
 #ifdef CONFIG_SA1100_SHANNON
 	pcmcia_shannon_init,
 #endif
diff --git a/drivers/pcmcia/sa1100_generic.h b/drivers/pcmcia/sa1100_generic.h
index 3f5495957ca5..f74b269e87d3 100644
--- a/drivers/pcmcia/sa1100_generic.h
+++ b/drivers/pcmcia/sa1100_generic.h
@@ -11,7 +11,6 @@ extern int pcmcia_freebird_init(struct device *);
 extern int pcmcia_gcplus_init(struct device *);
 extern int pcmcia_graphicsmaster_init(struct device *);
 extern int pcmcia_h3600_init(struct device *);
-extern int pcmcia_nanoengine_init(struct device *);
 extern int pcmcia_pangolin_init(struct device *);
 extern int pcmcia_pfs168_init(struct device *);
 extern int pcmcia_shannon_init(struct device *);
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
deleted file mode 100644
index 35c30ff41e81..000000000000
--- a/drivers/pcmcia/sa1100_nanoengine.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_nanoengine.c
- *
- * PCMCIA implementation routines for BSI nanoEngine.
- *
- * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine
- * board you should carefully read this:
- * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/
- *
- * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
- *
- * Based on original work for kernel 2.4 by
- * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/nanoengine.h>
-
-#include "sa1100_generic.h"
-
-struct nanoengine_pins {
-	unsigned output_pins;
-	unsigned clear_outputs;
-	int gpio_rst;
-	int gpio_cd;
-	int gpio_rdy;
-};
-
-static struct nanoengine_pins nano_skts[] = {
-	{
-		.gpio_rst		= GPIO_PC_RESET0,
-		.gpio_cd		= GPIO_PC_CD0,
-		.gpio_rdy		= GPIO_PC_READY0,
-	}, {
-		.gpio_rst		= GPIO_PC_RESET1,
-		.gpio_cd		= GPIO_PC_CD1,
-		.gpio_rdy		= GPIO_PC_READY1,
-	}
-};
-
-unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
-
-static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	unsigned i = skt->nr;
-	int ret;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return -ENXIO;
-
-	ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW,
-		i ? "PC RST1" : "PC RST0");
-	if (ret)
-		return ret;
-
-	skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd;
-	skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0";
-	skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy;
-	skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0";
-
-	return 0;
-}
-
-static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	gpio_free(nano_skts[skt->nr].gpio_rst);
-}
-
-static int nanoengine_pcmcia_configure_socket(
-	struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return -ENXIO;
-
-	gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));
-
-	return 0;
-}
-
-static void nanoengine_pcmcia_socket_state(
-	struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
-{
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return;
-
-	state->bvd1 = 1;
-	state->bvd2 = 1;
-	state->vs_3v = 1; /* Can only apply 3.3V */
-	state->vs_Xv = 0;
-}
-
-static struct pcmcia_low_level nanoengine_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-
-	.hw_init		= nanoengine_pcmcia_hw_init,
-	.hw_shutdown		= nanoengine_pcmcia_hw_shutdown,
-
-	.configure_socket	= nanoengine_pcmcia_configure_socket,
-	.socket_state		= nanoengine_pcmcia_socket_state,
-};
-
-int pcmcia_nanoengine_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_nanoengine())
-		ret = sa11xx_drv_pcmcia_probe(
-			dev, &nanoengine_pcmcia_ops, 0, 2);
-
-	return ret;
-}
-
-- 
2.1.0

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

* [PATCH 26/33] ARM: sa1100/shannon: switch shannon PCMCIA to use gpiod APIs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Switch shannon's PCMCIA implementation to use the gpiod APIs.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/shannon.c  | 13 +++++++++++++
 drivers/pcmcia/sa1100_shannon.c | 25 ++++++-------------------
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index c8866bce7386..f2cc896e582f 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -4,6 +4,7 @@
 
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/tty.h>
@@ -71,8 +72,20 @@ static struct sa1100fb_mach_info shannon_lcd_info = {
 	.lccr3		= LCCR3_ACBsDiv(512),
 };
 
+static struct gpiod_lookup_table shannon_pcmcia_gpio_table = {
+	.dev_id = "sa11x0-pcmcia",
+	.table = {
+		GPIO_LOOKUP("gpio", 24, "pcmcia0-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 25, "pcmcia1-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 26, "pcmcia0-ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 27, "pcmcia1-ready", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void __init shannon_init(void)
 {
+	gpiod_add_lookup_table(&shannon_pcmcia_gpio_table);
 	sa11x0_ppc_configure_mcp();
 	sa11x0_register_lcd(&shannon_lcd_info);
 	sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index b07a2dc3296e..51985c8ba830 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -8,35 +8,22 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/init.h>
-#include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/shannon.h>
-#include <asm/irq.h>
+
 #include "sa1100_generic.h"
 
 static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	/* All those are inputs */
-	GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) |
-		  GPIO_GPIO(SHANNON_GPIO_EJECT_1) |
-		  GPIO_GPIO(SHANNON_GPIO_RDY_0) |
-		  GPIO_GPIO(SHANNON_GPIO_RDY_1));
-
 	if (skt->nr == 0) {
-		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0";
-		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0";
+		skt->stat[SOC_STAT_CD].name = "pcmcia0-detect";
+		skt->stat[SOC_STAT_RDY].name = "pcmcia0-ready";
 	} else {
-		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1";
-		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1";
+		skt->stat[SOC_STAT_CD].name = "pcmcia1-detect";
+		skt->stat[SOC_STAT_RDY].name = "pcmcia1-ready";
 	}
 
-	return 0;
+	return soc_pcmcia_request_gpiods(skt);
 }
 
 static void
-- 
2.1.0


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

* [PATCH 26/33] ARM: sa1100/shannon: switch shannon PCMCIA to use gpiod APIs
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Switch shannon's PCMCIA implementation to use the gpiod APIs.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/shannon.c  | 13 +++++++++++++
 drivers/pcmcia/sa1100_shannon.c | 25 ++++++-------------------
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index c8866bce7386..f2cc896e582f 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -4,6 +4,7 @@
 
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/tty.h>
@@ -71,8 +72,20 @@ static struct sa1100fb_mach_info shannon_lcd_info = {
 	.lccr3		= LCCR3_ACBsDiv(512),
 };
 
+static struct gpiod_lookup_table shannon_pcmcia_gpio_table = {
+	.dev_id = "sa11x0-pcmcia",
+	.table = {
+		GPIO_LOOKUP("gpio", 24, "pcmcia0-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 25, "pcmcia1-detect", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", 26, "pcmcia0-ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 27, "pcmcia1-ready", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void __init shannon_init(void)
 {
+	gpiod_add_lookup_table(&shannon_pcmcia_gpio_table);
 	sa11x0_ppc_configure_mcp();
 	sa11x0_register_lcd(&shannon_lcd_info);
 	sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index b07a2dc3296e..51985c8ba830 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -8,35 +8,22 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/init.h>
-#include <linux/io.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/shannon.h>
-#include <asm/irq.h>
+
 #include "sa1100_generic.h"
 
 static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	/* All those are inputs */
-	GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) |
-		  GPIO_GPIO(SHANNON_GPIO_EJECT_1) |
-		  GPIO_GPIO(SHANNON_GPIO_RDY_0) |
-		  GPIO_GPIO(SHANNON_GPIO_RDY_1));
-
 	if (skt->nr == 0) {
-		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0";
-		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0";
+		skt->stat[SOC_STAT_CD].name = "pcmcia0-detect";
+		skt->stat[SOC_STAT_RDY].name = "pcmcia0-ready";
 	} else {
-		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1;
-		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1";
-		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1;
-		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1";
+		skt->stat[SOC_STAT_CD].name = "pcmcia1-detect";
+		skt->stat[SOC_STAT_RDY].name = "pcmcia1-ready";
 	}
 
-	return 0;
+	return soc_pcmcia_request_gpiods(skt);
 }
 
 static void
-- 
2.1.0

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

* [PATCH 27/33] ARM: sa1100/simpad: switch simpad CF to use gpiod APIs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Switch simpad's CF implementation to use the gpiod APIs.  The inverted
detection is handled using gpiolib's native inversion abilities.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/simpad.c  | 12 ++++++++++++
 drivers/pcmcia/sa1100_simpad.c | 12 +++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index bb3ca9c763de..5301a3036212 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -3,6 +3,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
@@ -354,12 +355,23 @@ static struct platform_device *devices[] __initdata = {
 	&simpad_i2c,
 };
 
+/* Compact Flash */
+static struct gpiod_lookup_table simpad_cf_gpio_table = {
+	.dev_id = "sa11x0-pcmcia",
+	.table = {
+		GPIO_LOOKUP("gpio", GPIO_CF_IRQ, "cf-ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", GPIO_CF_CD, "cf-detect", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
 
 
 static int __init simpad_init(void)
 {
 	int ret;
 
+	gpiod_add_lookup_table(&simpad_cf_gpio_table);
+
 	spin_lock_init(&cs3_lock);
 
 	cs3_gpio.label = "simpad_cs3";
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 73fd37968b6a..e14b2f5a18bb 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -11,7 +11,6 @@
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <mach/simpad.h>
 #include "sa1100_generic.h"
  
@@ -20,12 +19,10 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
 	simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-	skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD;
-	skt->stat[SOC_STAT_CD].name = "CF_CD";
-	skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ;
-	skt->stat[SOC_STAT_RDY].name = "CF_RDY";
+	skt->stat[SOC_STAT_CD].name = "cf-detect";
+	skt->stat[SOC_STAT_RDY].name = "cf-ready";
 
-	return 0;
+	return soc_pcmcia_request_gpiods(skt);
 }
 
 static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
@@ -41,9 +38,6 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	long cs3reg = simpad_get_cs3_ro();
 
-	/* the detect signal is inverted - fix that up here */
-	state->detect = !state->detect;
-
 	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
 	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
 
-- 
2.1.0


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

* [PATCH 27/33] ARM: sa1100/simpad: switch simpad CF to use gpiod APIs
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Switch simpad's CF implementation to use the gpiod APIs.  The inverted
detection is handled using gpiolib's native inversion abilities.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/simpad.c  | 12 ++++++++++++
 drivers/pcmcia/sa1100_simpad.c | 12 +++---------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index bb3ca9c763de..5301a3036212 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -3,6 +3,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/gpio/machine.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
@@ -354,12 +355,23 @@ static struct platform_device *devices[] __initdata = {
 	&simpad_i2c,
 };
 
+/* Compact Flash */
+static struct gpiod_lookup_table simpad_cf_gpio_table = {
+	.dev_id = "sa11x0-pcmcia",
+	.table = {
+		GPIO_LOOKUP("gpio", GPIO_CF_IRQ, "cf-ready", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", GPIO_CF_CD, "cf-detect", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
 
 
 static int __init simpad_init(void)
 {
 	int ret;
 
+	gpiod_add_lookup_table(&simpad_cf_gpio_table);
+
 	spin_lock_init(&cs3_lock);
 
 	cs3_gpio.label = "simpad_cs3";
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 73fd37968b6a..e14b2f5a18bb 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -11,7 +11,6 @@
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <mach/simpad.h>
 #include "sa1100_generic.h"
  
@@ -20,12 +19,10 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
 	simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-	skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD;
-	skt->stat[SOC_STAT_CD].name = "CF_CD";
-	skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ;
-	skt->stat[SOC_STAT_RDY].name = "CF_RDY";
+	skt->stat[SOC_STAT_CD].name = "cf-detect";
+	skt->stat[SOC_STAT_RDY].name = "cf-ready";
 
-	return 0;
+	return soc_pcmcia_request_gpiods(skt);
 }
 
 static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
@@ -41,9 +38,6 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	long cs3reg = simpad_get_cs3_ro();
 
-	/* the detect signal is inverted - fix that up here */
-	state->detect = !state->detect;
-
 	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
 	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
 
-- 
2.1.0

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

* [PATCH 28/33] ARM: sa1100/neponset: add GPIOs for PCMCIA
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Add the gpiod table for Neponset PCMCIA power control.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 75d758ca6799..790d8da233da 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -3,6 +3,7 @@
  */
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio-reg.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -95,6 +96,19 @@ struct neponset_drvdata {
 	struct gpio_chip *gpio[4];
 };
 
+static struct gpiod_lookup_table neponset_pcmcia_table = {
+	.dev_id = "1800",
+	.table = {
+		GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static struct neponset_drvdata *nep;
 
 void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -370,6 +384,8 @@ static int neponset_probe(struct platform_device *dev)
 			   d->base + AUD_CTL, AUD_NGPIO, false,
 			   neponset_aud_names);
 
+	gpiod_add_lookup_table(&neponset_pcmcia_table);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -423,6 +439,9 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->sa1111);
 	if (!IS_ERR(d->smc91x))
 		platform_device_unregister(d->smc91x);
+
+	gpiod_remove_lookup_table(&neponset_pcmcia_table);
+
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
 	nep = NULL;
-- 
2.1.0


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

* [PATCH 28/33] ARM: sa1100/neponset: add GPIOs for PCMCIA
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Add the gpiod table for Neponset PCMCIA power control.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 75d758ca6799..790d8da233da 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -3,6 +3,7 @@
  */
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
 #include <linux/gpio-reg.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -95,6 +96,19 @@ struct neponset_drvdata {
 	struct gpio_chip *gpio[4];
 };
 
+static struct gpiod_lookup_table neponset_pcmcia_table = {
+	.dev_id = "1800",
+	.table = {
+		GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static struct neponset_drvdata *nep;
 
 void neponset_ncr_frob(unsigned int mask, unsigned int val)
@@ -370,6 +384,8 @@ static int neponset_probe(struct platform_device *dev)
 			   d->base + AUD_CTL, AUD_NGPIO, false,
 			   neponset_aud_names);
 
+	gpiod_add_lookup_table(&neponset_pcmcia_table);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -423,6 +439,9 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->sa1111);
 	if (!IS_ERR(d->smc91x))
 		platform_device_unregister(d->smc91x);
+
+	gpiod_remove_lookup_table(&neponset_pcmcia_table);
+
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
 	nep = NULL;
-- 
2.1.0

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

* [PATCH 29/33] pcmcia: sa1111/neponset: convert to use MAX1600 power driver
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Use the MAX1600 power switch driver for Neponset.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/Kconfig           |  1 +
 drivers/pcmcia/sa1111_neponset.c | 79 ++++++++++------------------------------
 2 files changed, 20 insertions(+), 60 deletions(-)

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 8ac7f9f270c8..1441c1945088 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -194,6 +194,7 @@ config PCMCIA_SA1111
 	select PCMCIA_SOC_COMMON
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
+	select PCMCIA_MAX1600 if ASSABET_NEPONSET
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index 1d78739c4c07..30a1602dd984 100644
--- a/drivers/pcmcia/sa1111_neponset.c
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -9,12 +9,10 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/neponset.h>
-#include <asm/hardware/sa1111.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
 
 /*
  * Neponset uses the Maxim MAX1600, with the following connections:
@@ -39,70 +37,38 @@
  * "Standard Intel code" mode. Refer to the Maxim data sheet for
  * the corresponding truth table.
  */
-
-static int
-neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+	struct max1600 *m;
 	int ret;
 
-	switch (skt->nr) {
-	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1;
-		ncr_mask = NCR_A0VPP | NCR_A1VPP;
-
-		if (state->Vpp == 0)
-			ncr_set = 0;
-		else if (state->Vpp == 120)
-			ncr_set = NCR_A1VPP;
-		else if (state->Vpp == state->Vcc)
-			ncr_set = NCR_A0VPP;
-		else {
-			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
+	ret = max1600_init(skt->socket.dev.parent, &m,
+			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+			   MAX1600_CODE_LOW);
+	if (ret == 0)
+		s->driver_data = m;
 
-	case 1:
-		pa_dwr_mask = GPIO_A2 | GPIO_A3;
-		ncr_mask = 0;
-		ncr_set = 0;
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
-
-	default:
-		return -1;
-	}
+	return ret;
+}
 
-	/*
-	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
-	 * pa_dwr_mask selects which bits (and therefore socket) we change.
-	 */
-	switch (state->Vcc) {
-	default:
-	case 0:  pa_dwr_set = 0;		break;
-	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
-	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
-	}
+static int
+neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	struct max1600 *m = s->driver_data;
+	int ret;
 
 	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		neponset_ncr_frob(ncr_mask, ncr_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
+	if (ret == 0)
+		ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 	return ret;
 }
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= neponset_pcmcia_hw_init,
 	.configure_socket	= neponset_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -113,13 +79,6 @@ int pcmcia_neponset_init(struct sa1111_dev *sadev)
 	int ret = -ENODEV;
 
 	if (machine_is_assabet()) {
-		/*
-		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-		 * and switch to standby mode.
-		 */
-		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
 		sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
 		ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
 				sa11xx_drv_pcmcia_add_one);
-- 
2.1.0


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

* [PATCH 29/33] pcmcia: sa1111/neponset: convert to use MAX1600 power driver
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Use the MAX1600 power switch driver for Neponset.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/Kconfig           |  1 +
 drivers/pcmcia/sa1111_neponset.c | 79 ++++++++++------------------------------
 2 files changed, 20 insertions(+), 60 deletions(-)

diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 8ac7f9f270c8..1441c1945088 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -194,6 +194,7 @@ config PCMCIA_SA1111
 	select PCMCIA_SOC_COMMON
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
+	select PCMCIA_MAX1600 if ASSABET_NEPONSET
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
index 1d78739c4c07..30a1602dd984 100644
--- a/drivers/pcmcia/sa1111_neponset.c
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -9,12 +9,10 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/neponset.h>
-#include <asm/hardware/sa1111.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
 
 /*
  * Neponset uses the Maxim MAX1600, with the following connections:
@@ -39,70 +37,38 @@
  * "Standard Intel code" mode. Refer to the Maxim data sheet for
  * the corresponding truth table.
  */
-
-static int
-neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+static int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+	struct max1600 *m;
 	int ret;
 
-	switch (skt->nr) {
-	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1;
-		ncr_mask = NCR_A0VPP | NCR_A1VPP;
-
-		if (state->Vpp == 0)
-			ncr_set = 0;
-		else if (state->Vpp == 120)
-			ncr_set = NCR_A1VPP;
-		else if (state->Vpp == state->Vcc)
-			ncr_set = NCR_A0VPP;
-		else {
-			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
+	ret = max1600_init(skt->socket.dev.parent, &m,
+			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+			   MAX1600_CODE_LOW);
+	if (ret == 0)
+		s->driver_data = m;
 
-	case 1:
-		pa_dwr_mask = GPIO_A2 | GPIO_A3;
-		ncr_mask = 0;
-		ncr_set = 0;
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
-
-	default:
-		return -1;
-	}
+	return ret;
+}
 
-	/*
-	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
-	 * pa_dwr_mask selects which bits (and therefore socket) we change.
-	 */
-	switch (state->Vcc) {
-	default:
-	case 0:  pa_dwr_set = 0;		break;
-	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
-	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
-	}
+static int
+neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	struct max1600 *m = s->driver_data;
+	int ret;
 
 	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		neponset_ncr_frob(ncr_mask, ncr_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
+	if (ret == 0)
+		ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 	return ret;
 }
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= neponset_pcmcia_hw_init,
 	.configure_socket	= neponset_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -113,13 +79,6 @@ int pcmcia_neponset_init(struct sa1111_dev *sadev)
 	int ret = -ENODEV;
 
 	if (machine_is_assabet()) {
-		/*
-		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-		 * and switch to standby mode.
-		 */
-		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
 		sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
 		ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
 				sa11xx_drv_pcmcia_add_one);
-- 
2.1.0

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

* [PATCH 30/33] ARM: sa1100/jornada720: switch jornada720 PCMCIA to gpiod APIs
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Convert the low level PCMCIA driver to gpiod APIs for controlling
the socket power.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/jornada720.c  | 12 ++++++
 drivers/pcmcia/sa1111_jornada720.c | 81 +++++++++++++++++++++++++-------------
 2 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 0a2ca9be00e6..6298bad09ef3 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -190,6 +190,17 @@ static struct platform_device s1d13xxxfb_device = {
 	.resource	= s1d13xxxfb_resources,
 };
 
+static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
+	.dev_id = "1800",
+	.table = {
+		GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static struct resource sa1111_resources[] = {
 	[0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
 	[1] = DEFINE_RES_IRQ(IRQ_GPIO1),
@@ -265,6 +276,7 @@ static int __init jornada720_init(void)
 		udelay(20);		/* give it some time to restart */
 
 		gpiod_add_lookup_table(&jornada_ts_gpiod_table);
+		gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index c2c30580c83f..bfcb9fd43352 100644
--- a/drivers/pcmcia/sa1111_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -5,29 +5,64 @@
  *
  */
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
 
 #include "sa1111_generic.h"
 
-/* Does SOCKET1_3V actually do anything? */
-#define SOCKET0_POWER	GPIO_GPIO0
-#define SOCKET0_3V	GPIO_GPIO2
-#define SOCKET1_POWER	(GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V	GPIO_GPIO3
+/*
+ * Socket 0 power: GPIO A0
+ * Socket 0 3V: GPIO A2
+ * Socket 1 power: GPIO A1 & GPIO A3
+ * Socket 1 3V: GPIO A3
+ * Does Socket 1 3V actually do anything?
+ */
+enum {
+	J720_GPIO_PWR,
+	J720_GPIO_3V,
+	J720_GPIO_MAX,
+};
+struct jornada720_data {
+	struct gpio_desc *gpio[J720_GPIO_MAX];
+};
+
+static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	struct device *dev = skt->socket.dev.parent;
+	struct jornada720_data *j;
+
+	j = devm_kzalloc(dev, sizeof(*j), GFP_KERNEL);
+	if (!j)
+		return -ENOMEM;
+
+	j->gpio[J720_GPIO_PWR] = devm_gpiod_get(dev, skt->nr ? "s1-power" :
+						"s0-power", GPIOD_OUT_LOW);
+	if (IS_ERR(j->gpio[J720_GPIO_PWR]))
+		return PTR_ERR(j->gpio[J720_GPIO_PWR]);
+
+	j->gpio[J720_GPIO_3V] = devm_gpiod_get(dev, skt->nr ? "s1-3v" :
+					       "s0-3v", GPIOD_OUT_LOW);
+	if (IS_ERR(j->gpio[J720_GPIO_3V]))
+		return PTR_ERR(j->gpio[J720_GPIO_3V]);
+
+	s->driver_data = j;
+
+	return 0;
+}
 
 static int
 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set;
+	struct jornada720_data *j = s->driver_data;
+	int values[J720_GPIO_MAX];
 	int ret;
 
 	printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
@@ -35,35 +70,32 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 	switch (skt->nr) {
 	case 0:
-		pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
 		switch (state->Vcc) {
 		default:
 		case  0:
-			pa_dwr_set = 0;
+			values[J720_GPIO_PWR] = 0;
+			values[J720_GPIO_3V] = 0;
 			break;
 		case 33:
-			pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+			values[J720_GPIO_3V] = 1;
 			break;
 		case 50:
-			pa_dwr_set = SOCKET0_POWER;
+			values[J720_GPIO_PWR] = 1;
 			break;
 		}
 		break;
 
 	case 1:
-		pa_dwr_mask = SOCKET1_POWER;
-
 		switch (state->Vcc) {
 		default:
 		case 0:
-			pa_dwr_set = 0;
+			values[J720_GPIO_PWR] = 0;
+			values[J720_GPIO_3V] = 0;
 			break;
 		case 33:
-			pa_dwr_set = SOCKET1_POWER;
-			break;
 		case 50:
-			pa_dwr_set = SOCKET1_POWER;
+			values[J720_GPIO_PWR] = 1;
+			values[J720_GPIO_3V] = 1;
 			break;
 		}
 		break;
@@ -80,13 +112,14 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 	ret = sa1111_pcmcia_configure_socket(skt, state);
 	if (ret == 0)
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+		gpiod_set_array_value(J720_GPIO_MAX, j->gpio, values);
 
 	return ret;
 }
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= jornada720_pcmcia_hw_init,
 	.configure_socket	= jornada720_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -97,15 +130,9 @@ int pcmcia_jornada720_init(struct sa1111_dev *sadev)
 	int ret = -ENODEV;
 
 	if (machine_is_jornada720()) {
-		unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
+		/* Fixme: why messing around with SA11x0's GPIO1? */
 		GRER |= 0x00000002;
 
-		/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-		sa1111_set_io_dir(sadev, pin, 0, 0);
-		sa1111_set_io(sadev, pin, 0);
-		sa1111_set_sleep_io(sadev, pin, 0);
-
 		sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
 		ret = sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
 				sa11xx_drv_pcmcia_add_one);
-- 
2.1.0


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

* [PATCH 30/33] ARM: sa1100/jornada720: switch jornada720 PCMCIA to gpiod APIs
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the low level PCMCIA driver to gpiod APIs for controlling
the socket power.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/jornada720.c  | 12 ++++++
 drivers/pcmcia/sa1111_jornada720.c | 81 +++++++++++++++++++++++++-------------
 2 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 0a2ca9be00e6..6298bad09ef3 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -190,6 +190,17 @@ static struct platform_device s1d13xxxfb_device = {
 	.resource	= s1d13xxxfb_resources,
 };
 
+static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
+	.dev_id = "1800",
+	.table = {
+		GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static struct resource sa1111_resources[] = {
 	[0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
 	[1] = DEFINE_RES_IRQ(IRQ_GPIO1),
@@ -265,6 +276,7 @@ static int __init jornada720_init(void)
 		udelay(20);		/* give it some time to restart */
 
 		gpiod_add_lookup_table(&jornada_ts_gpiod_table);
+		gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
index c2c30580c83f..bfcb9fd43352 100644
--- a/drivers/pcmcia/sa1111_jornada720.c
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -5,29 +5,64 @@
  *
  */
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/init.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
 
 #include "sa1111_generic.h"
 
-/* Does SOCKET1_3V actually do anything? */
-#define SOCKET0_POWER	GPIO_GPIO0
-#define SOCKET0_3V	GPIO_GPIO2
-#define SOCKET1_POWER	(GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V	GPIO_GPIO3
+/*
+ * Socket 0 power: GPIO A0
+ * Socket 0 3V: GPIO A2
+ * Socket 1 power: GPIO A1 & GPIO A3
+ * Socket 1 3V: GPIO A3
+ * Does Socket 1 3V actually do anything?
+ */
+enum {
+	J720_GPIO_PWR,
+	J720_GPIO_3V,
+	J720_GPIO_MAX,
+};
+struct jornada720_data {
+	struct gpio_desc *gpio[J720_GPIO_MAX];
+};
+
+static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	struct device *dev = skt->socket.dev.parent;
+	struct jornada720_data *j;
+
+	j = devm_kzalloc(dev, sizeof(*j), GFP_KERNEL);
+	if (!j)
+		return -ENOMEM;
+
+	j->gpio[J720_GPIO_PWR] = devm_gpiod_get(dev, skt->nr ? "s1-power" :
+						"s0-power", GPIOD_OUT_LOW);
+	if (IS_ERR(j->gpio[J720_GPIO_PWR]))
+		return PTR_ERR(j->gpio[J720_GPIO_PWR]);
+
+	j->gpio[J720_GPIO_3V] = devm_gpiod_get(dev, skt->nr ? "s1-3v" :
+					       "s0-3v", GPIOD_OUT_LOW);
+	if (IS_ERR(j->gpio[J720_GPIO_3V]))
+		return PTR_ERR(j->gpio[J720_GPIO_3V]);
+
+	s->driver_data = j;
+
+	return 0;
+}
 
 static int
 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set;
+	struct jornada720_data *j = s->driver_data;
+	int values[J720_GPIO_MAX];
 	int ret;
 
 	printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
@@ -35,35 +70,32 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 	switch (skt->nr) {
 	case 0:
-		pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
 		switch (state->Vcc) {
 		default:
 		case  0:
-			pa_dwr_set = 0;
+			values[J720_GPIO_PWR] = 0;
+			values[J720_GPIO_3V] = 0;
 			break;
 		case 33:
-			pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+			values[J720_GPIO_3V] = 1;
 			break;
 		case 50:
-			pa_dwr_set = SOCKET0_POWER;
+			values[J720_GPIO_PWR] = 1;
 			break;
 		}
 		break;
 
 	case 1:
-		pa_dwr_mask = SOCKET1_POWER;
-
 		switch (state->Vcc) {
 		default:
 		case 0:
-			pa_dwr_set = 0;
+			values[J720_GPIO_PWR] = 0;
+			values[J720_GPIO_3V] = 0;
 			break;
 		case 33:
-			pa_dwr_set = SOCKET1_POWER;
-			break;
 		case 50:
-			pa_dwr_set = SOCKET1_POWER;
+			values[J720_GPIO_PWR] = 1;
+			values[J720_GPIO_3V] = 1;
 			break;
 		}
 		break;
@@ -80,13 +112,14 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 	ret = sa1111_pcmcia_configure_socket(skt, state);
 	if (ret == 0)
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+		gpiod_set_array_value(J720_GPIO_MAX, j->gpio, values);
 
 	return ret;
 }
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= jornada720_pcmcia_hw_init,
 	.configure_socket	= jornada720_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -97,15 +130,9 @@ int pcmcia_jornada720_init(struct sa1111_dev *sadev)
 	int ret = -ENODEV;
 
 	if (machine_is_jornada720()) {
-		unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
+		/* Fixme: why messing around with SA11x0's GPIO1? */
 		GRER |= 0x00000002;
 
-		/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-		sa1111_set_io_dir(sadev, pin, 0, 0);
-		sa1111_set_io(sadev, pin, 0);
-		sa1111_set_sleep_io(sadev, pin, 0);
-
 		sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
 		ret = sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops,
 				sa11xx_drv_pcmcia_add_one);
-- 
2.1.0

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

* [PATCH 31/33] ARM: pxa/lubbock: convert PCMCIA to use MAX1600 driver
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

As Lubbock now provides GPIOs via gpiolib for controlling the socket
power, we can use the MAX1600 driver.  Switch Lubbock to use this
driver, which simplifies the code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/lubbock.c     |  16 ++++++
 drivers/pcmcia/Kconfig          |   1 +
 drivers/pcmcia/sa1111_lubbock.c | 110 ++++++++--------------------------------
 3 files changed, 38 insertions(+), 89 deletions(-)

diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index e974d1eb0f88..8686c5d0dc3b 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -136,6 +136,20 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
 	// no D+ pullup; lubbock can't connect/disconnect in software
 };
 
+/* GPIOs for SA1111 PCMCIA */
+static struct gpiod_lookup_table sa1111_pcmcia_gpio_table = {
+	.dev_id = "1800",
+	.table = {
+		{ "sa1111", 0, "a0vpp", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 1, "a1vpp", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 2, "a0vcc", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 3, "a1vcc", GPIO_ACTIVE_HIGH },
+		{ "lubbock", 14, "b0vcc", GPIO_ACTIVE_HIGH },
+		{ "lubbock", 15, "b1vcc", GPIO_ACTIVE_HIGH },
+		{ },
+	},
+};
+
 static struct resource sa1111_resources[] = {
 	[0] = {
 		.start	= 0x10000000,
@@ -475,6 +489,8 @@ static void __init lubbock_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
+	gpiod_add_lookup_table(&sa1111_pcmcia_gpio_table);
+
 	clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_fb_info(NULL, &sharp_lm8v31);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1441c1945088..1b4b641a1e04 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -195,6 +195,7 @@ config PCMCIA_SA1111
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
 	select PCMCIA_MAX1600 if ASSABET_NEPONSET
+	select PCMCIA_MAX1600 if ARCH_LUBBOCK && SA1111
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index c5caf5790451..9d5ffc71ae51 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -24,20 +24,33 @@
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
-#include <mach/lubbock.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
+
+static int lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	struct max1600 *m;
+	int ret;
+
+	ret = max1600_init(skt->socket.dev.parent, &m,
+			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+			   MAX1600_CODE_HIGH);
+	if (ret == 0)
+		s->driver_data = m;
+
+	return ret;
+}
 
 static int
 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 				const socket_state_t *state)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
+	struct max1600 *m = s->driver_data;
 	int ret = 0;
 
-	pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
-
 	/* Lubbock uses the Maxim MAX1602, with the following connections:
 	 *
 	 * Socket 0 (PCMCIA):
@@ -71,74 +84,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  again:
 	switch (skt->nr) {
 	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			pa_dwr_set |= GPIO_A3;
-			break;
-
-		case 50: /* VX */
-			pa_dwr_set |= GPIO_A2;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-		}
-
-		switch (state->Vpp) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 120: /* 12IN */
-			pa_dwr_set |= GPIO_A1;
-			break;
-
-		default: /* VCC */
-			if (state->Vpp == state->Vcc)
-				pa_dwr_set |= GPIO_A0;
-			else {
-				printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-				       __func__, state->Vpp);
-				ret = -1;
-				break;
-			}
-		}
-		break;
-
 	case 1:
-		misc_mask = (1 << 15) | (1 << 14);
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			misc_set |= 1 << 15;
-			break;
-
-		case 50: /* VX */
-			misc_set |= 1 << 14;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-			break;
-		}
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-			       __func__, state->Vpp);
-			ret = -1;
-			break;
-		}
 		break;
 
 	default:
@@ -147,11 +93,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 	if (ret == 0)
 		ret = sa1111_pcmcia_configure_socket(skt, state);
-
-	if (ret == 0) {
-		lubbock_set_misc_wr(misc_mask, misc_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
+	if (ret == 0)
+		ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 #if 1
 	if (ret == 0 && state->Vcc == 33) {
@@ -175,8 +118,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 			/*
 			 * Switch to 5V,  Configure socket with 5V voltage
 			 */
-			lubbock_set_misc_wr(misc_mask, 0);
-			sa1111_set_io(s->dev, pa_dwr_mask, 0);
+			max1600_configure(m, 0, 0);
 
 			/*
 			 * It takes about 100ms to turn off Vcc.
@@ -201,6 +143,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 static struct pcmcia_low_level lubbock_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= lubbock_pcmcia_hw_init,
 	.configure_socket	= lubbock_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -213,17 +156,6 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 	int ret = -ENODEV;
 
 	if (machine_is_lubbock()) {
-		/*
-		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-		 * and switch to standby mode.
-		 */
-		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
-		/* Set CF Socket 1 power to standby mode. */
-		lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
-
 		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
 		pxa2xx_configure_sockets(&sadev->dev);
 		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
-- 
2.1.0


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

* [PATCH 31/33] ARM: pxa/lubbock: convert PCMCIA to use MAX1600 driver
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

As Lubbock now provides GPIOs via gpiolib for controlling the socket
power, we can use the MAX1600 driver.  Switch Lubbock to use this
driver, which simplifies the code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/lubbock.c     |  16 ++++++
 drivers/pcmcia/Kconfig          |   1 +
 drivers/pcmcia/sa1111_lubbock.c | 110 ++++++++--------------------------------
 3 files changed, 38 insertions(+), 89 deletions(-)

diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index e974d1eb0f88..8686c5d0dc3b 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -136,6 +136,20 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = {
 	// no D+ pullup; lubbock can't connect/disconnect in software
 };
 
+/* GPIOs for SA1111 PCMCIA */
+static struct gpiod_lookup_table sa1111_pcmcia_gpio_table = {
+	.dev_id = "1800",
+	.table = {
+		{ "sa1111", 0, "a0vpp", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 1, "a1vpp", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 2, "a0vcc", GPIO_ACTIVE_HIGH },
+		{ "sa1111", 3, "a1vcc", GPIO_ACTIVE_HIGH },
+		{ "lubbock", 14, "b0vcc", GPIO_ACTIVE_HIGH },
+		{ "lubbock", 15, "b1vcc", GPIO_ACTIVE_HIGH },
+		{ },
+	},
+};
+
 static struct resource sa1111_resources[] = {
 	[0] = {
 		.start	= 0x10000000,
@@ -475,6 +489,8 @@ static void __init lubbock_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
+	gpiod_add_lookup_table(&sa1111_pcmcia_gpio_table);
+
 	clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_fb_info(NULL, &sharp_lm8v31);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1441c1945088..1b4b641a1e04 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -195,6 +195,7 @@ config PCMCIA_SA1111
 	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	select PCMCIA_PXA2XX if ARCH_LUBBOCK && SA1111
 	select PCMCIA_MAX1600 if ASSABET_NEPONSET
+	select PCMCIA_MAX1600 if ARCH_LUBBOCK && SA1111
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index c5caf5790451..9d5ffc71ae51 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -24,20 +24,33 @@
 #include <mach/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/mach-types.h>
-#include <mach/lubbock.h>
 
 #include "sa1111_generic.h"
+#include "max1600.h"
+
+static int lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	struct max1600 *m;
+	int ret;
+
+	ret = max1600_init(skt->socket.dev.parent, &m,
+			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
+			   MAX1600_CODE_HIGH);
+	if (ret == 0)
+		s->driver_data = m;
+
+	return ret;
+}
 
 static int
 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 				const socket_state_t *state)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
+	struct max1600 *m = s->driver_data;
 	int ret = 0;
 
-	pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
-
 	/* Lubbock uses the Maxim MAX1602, with the following connections:
 	 *
 	 * Socket 0 (PCMCIA):
@@ -71,74 +84,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
  again:
 	switch (skt->nr) {
 	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			pa_dwr_set |= GPIO_A3;
-			break;
-
-		case 50: /* VX */
-			pa_dwr_set |= GPIO_A2;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-		}
-
-		switch (state->Vpp) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 120: /* 12IN */
-			pa_dwr_set |= GPIO_A1;
-			break;
-
-		default: /* VCC */
-			if (state->Vpp == state->Vcc)
-				pa_dwr_set |= GPIO_A0;
-			else {
-				printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-				       __func__, state->Vpp);
-				ret = -1;
-				break;
-			}
-		}
-		break;
-
 	case 1:
-		misc_mask = (1 << 15) | (1 << 14);
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			misc_set |= 1 << 15;
-			break;
-
-		case 50: /* VX */
-			misc_set |= 1 << 14;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-			break;
-		}
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-			       __func__, state->Vpp);
-			ret = -1;
-			break;
-		}
 		break;
 
 	default:
@@ -147,11 +93,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 	if (ret == 0)
 		ret = sa1111_pcmcia_configure_socket(skt, state);
-
-	if (ret == 0) {
-		lubbock_set_misc_wr(misc_mask, misc_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
+	if (ret == 0)
+		ret = max1600_configure(m, state->Vcc, state->Vpp);
 
 #if 1
 	if (ret == 0 && state->Vcc == 33) {
@@ -175,8 +118,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 			/*
 			 * Switch to 5V,  Configure socket with 5V voltage
 			 */
-			lubbock_set_misc_wr(misc_mask, 0);
-			sa1111_set_io(s->dev, pa_dwr_mask, 0);
+			max1600_configure(m, 0, 0);
 
 			/*
 			 * It takes about 100ms to turn off Vcc.
@@ -201,6 +143,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 static struct pcmcia_low_level lubbock_pcmcia_ops = {
 	.owner			= THIS_MODULE,
+	.hw_init		= lubbock_pcmcia_hw_init,
 	.configure_socket	= lubbock_pcmcia_configure_socket,
 	.first			= 0,
 	.nr			= 2,
@@ -213,17 +156,6 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 	int ret = -ENODEV;
 
 	if (machine_is_lubbock()) {
-		/*
-		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-		 * and switch to standby mode.
-		 */
-		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
-		/* Set CF Socket 1 power to standby mode. */
-		lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
-
 		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
 		pxa2xx_configure_sockets(&sadev->dev);
 		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
-- 
2.1.0

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

* [PATCH 32/33] pcmcia: sa1100*: remove redundant bvd1/bvd2 setting
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

bvd1 and bvd2 both default to 1 in the generic soc_common code, so
having a driver repeat this is redundant.  Remove it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_shannon.c | 4 ----
 drivers/pcmcia/sa1100_simpad.c  | 4 ++--
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 51985c8ba830..7409cb36083b 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -32,15 +32,11 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	switch (skt->nr) {
 	case 0:
-		state->bvd1   = 1; 
-		state->bvd2   = 1; 
 		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
 		state->vs_Xv  = 0;
 		break;
 
 	case 1:
-		state->bvd1   = 1; 
-		state->bvd2   = 1; 
 		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
 		state->vs_Xv  = 0;
 		break;
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index e14b2f5a18bb..b59bbe68c6d7 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -38,8 +38,8 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	long cs3reg = simpad_get_cs3_ro();
 
-	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
-	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
+	/* bvd1 might be cs3reg & PCMCIA_BVD1 */
+	/* bvd2 might be cs3reg & PCMCIA_BVD2 */
 
 	if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
 			(PCMCIA_VS1|PCMCIA_VS2)) {
-- 
2.1.0


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

* [PATCH 32/33] pcmcia: sa1100*: remove redundant bvd1/bvd2 setting
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

bvd1 and bvd2 both default to 1 in the generic soc_common code, so
having a driver repeat this is redundant.  Remove it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/pcmcia/sa1100_shannon.c | 4 ----
 drivers/pcmcia/sa1100_simpad.c  | 4 ++--
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 51985c8ba830..7409cb36083b 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -32,15 +32,11 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	switch (skt->nr) {
 	case 0:
-		state->bvd1   = 1; 
-		state->bvd2   = 1; 
 		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
 		state->vs_Xv  = 0;
 		break;
 
 	case 1:
-		state->bvd1   = 1; 
-		state->bvd2   = 1; 
 		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
 		state->vs_Xv  = 0;
 		break;
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index e14b2f5a18bb..b59bbe68c6d7 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -38,8 +38,8 @@ simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 {
 	long cs3reg = simpad_get_cs3_ro();
 
-	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
-	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
+	/* bvd1 might be cs3reg & PCMCIA_BVD1 */
+	/* bvd2 might be cs3reg & PCMCIA_BVD2 */
 
 	if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
 			(PCMCIA_VS1|PCMCIA_VS2)) {
-- 
2.1.0

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

* [PATCH 33/33] ARM: sa1111: remove legacy GPIO interfaces
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-29 10:26     ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel, linux-gpio, linux-pcmcia
  Cc: Alexandre Courbot, Daniel Mack, Haojian Zhuang,
	Kristoffer Ericson, Linus Walleij, Robert Jarzmik

Now that we have migrated all users of the legacy private SA1111 gpio
interfaces, we can remove these redundant interfaces.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/common/sa1111.c               | 59 ----------------------------------
 arch/arm/include/asm/hardware/sa1111.h |  4 ---
 2 files changed, 63 deletions(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ac19dca4c258..e23db31fdd29 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1334,65 +1334,6 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
 }
 EXPORT_SYMBOL(sa1111_get_audio_rate);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev,
-		       unsigned int bits, unsigned int dir,
-		       unsigned int sleep_dir)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-#define MODIFY_BITS(port, mask, dir)		\
-	if (mask) {				\
-		val = sa1111_readl(port);	\
-		val &= ~(mask);			\
-		val |= (dir) & (mask);		\
-		sa1111_writel(val, port);	\
-	}
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16);
-
-	MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io_dir);
-
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io);
-
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_sleep_io);
-
 /*
  * Individual device operations.
  */
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 7c2bbc7f0be1..cbb29c9c6457 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -460,10 +460,6 @@ int sa1111_check_dma_bug(dma_addr_t addr);
 int sa1111_driver_register(struct sa1111_driver *);
 void sa1111_driver_unregister(struct sa1111_driver *);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir);
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-
 struct sa1111_platform_data {
 	int	irq_base;	/* base for cascaded on-chip IRQs */
 	unsigned disable_devs;
-- 
2.1.0


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

* [PATCH 33/33] ARM: sa1111: remove legacy GPIO interfaces
@ 2016-08-29 10:26     ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have migrated all users of the legacy private SA1111 gpio
interfaces, we can remove these redundant interfaces.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/common/sa1111.c               | 59 ----------------------------------
 arch/arm/include/asm/hardware/sa1111.h |  4 ---
 2 files changed, 63 deletions(-)

diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ac19dca4c258..e23db31fdd29 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1334,65 +1334,6 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
 }
 EXPORT_SYMBOL(sa1111_get_audio_rate);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev,
-		       unsigned int bits, unsigned int dir,
-		       unsigned int sleep_dir)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-#define MODIFY_BITS(port, mask, dir)		\
-	if (mask) {				\
-		val = sa1111_readl(port);	\
-		val &= ~(mask);			\
-		val |= (dir) & (mask);		\
-		sa1111_writel(val, port);	\
-	}
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16);
-
-	MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io_dir);
-
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_io);
-
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
-{
-	struct sa1111 *sachip = sa1111_chip_driver(sadev);
-	unsigned long flags;
-	unsigned int val;
-	void __iomem *gpio = sachip->base + SA1111_GPIO;
-
-	spin_lock_irqsave(&sachip->lock, flags);
-	MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
-	MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8);
-	MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
-	spin_unlock_irqrestore(&sachip->lock, flags);
-}
-EXPORT_SYMBOL(sa1111_set_sleep_io);
-
 /*
  * Individual device operations.
  */
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 7c2bbc7f0be1..cbb29c9c6457 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -460,10 +460,6 @@ int sa1111_check_dma_bug(dma_addr_t addr);
 int sa1111_driver_register(struct sa1111_driver *);
 void sa1111_driver_unregister(struct sa1111_driver *);
 
-void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir);
-void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
-
 struct sa1111_platform_data {
 	int	irq_base;	/* base for cascaded on-chip IRQs */
 	unsigned disable_devs;
-- 
2.1.0

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

* [PATCH 0/3] SA11x0 gpio keys/leds
  2016-08-29 10:23   ` Russell King - ARM Linux
                     ` (33 preceding siblings ...)
  (?)
@ 2016-08-29 11:01   ` Russell King - ARM Linux
  2016-08-29 11:03     ` [PATCH 1/3] ARM: sa1100/assabet: add gpio keys support for right-hand two buttons Russell King
                       ` (3 more replies)
  -1 siblings, 4 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

These patches:

* convert Assabet LEDs to use the gpiolib LED driver, now that we have
  the assabet board control register modelled as a gpiolib driver.
* adds gpiokeys support for the buttons connected to GPIO0/1, which
  are used to wake up the system after putting it to S2R sleep.  Without
  this, it's hard to test S2R.
* convert Cerf to ues the gpioleds registration API.

 arch/arm/mach-sa1100/Kconfig   |   2 +
 arch/arm/mach-sa1100/assabet.c | 139 ++++++++++++++++-------------------------
 arch/arm/mach-sa1100/cerf.c    |  11 +---
 3 files changed, 57 insertions(+), 95 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 1/3] ARM: sa1100/assabet: add gpio keys support for right-hand two buttons
  2016-08-29 11:01   ` [PATCH 0/3] SA11x0 gpio keys/leds Russell King - ARM Linux
@ 2016-08-29 11:03     ` Russell King
  2016-08-29 11:03     ` [PATCH 2/3] ARM: sa1100/assabet: switch to using gpio leds Russell King
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpio keys support for the right-hand two buttons on the Assabet,
which can be used to wake up the CPU after PM.  This facilities S2R
testing.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 5c9a1e115847..0d473aa23a6c 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/gpio/machine.h>
+#include <linux/gpio_keys.h>
 #include <linux/gpio-reg.h>
 #include <linux/ioport.h>
 #include <linux/platform_data/sa11x0-serial.h>
@@ -493,6 +494,30 @@ static int assabet_register_fixed_regulator(int n,
 	return 0;
 }
 
+static struct gpio_keys_button assabet_keys_buttons[] = {
+	{
+		.gpio = 0,
+		.irq = IRQ_GPIO0,
+		.desc = "gpio0",
+		.wakeup = 1,
+		.can_disable = 1,
+		.debounce_interval = 5,
+	}, {
+		.gpio = 1,
+		.irq = IRQ_GPIO1,
+		.desc = "gpio1",
+		.wakeup = 1,
+		.can_disable = 1,
+		.debounce_interval = 5,
+	},
+};
+
+static const struct gpio_keys_platform_data assabet_keys_pdata = {
+	.buttons = assabet_keys_buttons,
+	.nbuttons = ARRAY_SIZE(assabet_keys_buttons),
+	.rep = 0,
+};
+
 static void __init assabet_init(void)
 {
 	/*
@@ -539,6 +564,11 @@ static void __init assabet_init(void)
 			neponset_resources, ARRAY_SIZE(neponset_resources));
 #endif
 	} else {
+		platform_device_register_resndata(NULL, "gpio-keys", 0,
+						  NULL, 0,
+						  &assabet_keys_pdata,
+						  sizeof(assabet_keys_pdata));
+
 		assabet_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
 					 assabet_cf_vcc_consumers,
 					 ARRAY_SIZE(assabet_cf_vcc_consumers));
-- 
2.1.0

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

* [PATCH 2/3] ARM: sa1100/assabet: switch to using gpio leds
  2016-08-29 11:01   ` [PATCH 0/3] SA11x0 gpio keys/leds Russell King - ARM Linux
  2016-08-29 11:03     ` [PATCH 1/3] ARM: sa1100/assabet: add gpio keys support for right-hand two buttons Russell King
@ 2016-08-29 11:03     ` Russell King
  2016-08-29 11:03     ` [PATCH 3/3] ARM: sa1100/cerf: switch to using gpio_led_register_device() Russell King
  2016-08-29 11:25       ` Russell King - ARM Linux
  3 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

Switch over to using gpio leds now that we have the gpio driver for
the assabet board register in place.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/Kconfig   |   1 +
 arch/arm/mach-sa1100/assabet.c | 109 +++++++++--------------------------------
 2 files changed, 25 insertions(+), 85 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 07df3a59b13f..b34f229fbfb4 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -6,6 +6,7 @@ config SA1100_ASSABET
 	bool "Assabet"
 	select ARM_SA1110_CPUFREQ
 	select GPIO_REG
+	select LEDS_GPIO_REGISTER
 	help
 	  Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
 	  Microprocessor Development Board (also known as the Assabet).
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 0d473aa23a6c..af5cea464a10 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -494,6 +494,25 @@ static int assabet_register_fixed_regulator(int n,
 	return 0;
 }
 
+static struct gpio_led assabet_leds[] __initdata = {
+	{
+		.name = "assabet:red",
+		.default_trigger = "cpu0",
+		.active_low = 1,
+		.default_state = LEDS_GPIO_DEFSTATE_KEEP,
+	}, {
+		.name = "assabet:green",
+		.default_trigger = "heartbeat",
+		.active_low = 1,
+		.default_state = LEDS_GPIO_DEFSTATE_KEEP,
+	},
+};
+
+static const struct gpio_led_platform_data assabet_leds_pdata __initconst = {
+	.num_leds = ARRAY_SIZE(assabet_leds),
+	.leds = assabet_leds,
+};
+
 static struct gpio_keys_button assabet_keys_buttons[] = {
 	{
 		.gpio = 0,
@@ -572,9 +591,10 @@ static void __init assabet_init(void)
 		assabet_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
 					 assabet_cf_vcc_consumers,
 					 ARRAY_SIZE(assabet_cf_vcc_consumers));
-
 	}
 
+	gpio_led_register_device(-1, &assabet_leds_pdata);
+
 #ifndef ASSABET_PAL_VIDEO
 	sa11x0_register_lcd(&lq039q2ds54_info);
 #else
@@ -768,90 +788,6 @@ static void __init assabet_map_io(void)
 	sa1100_register_uart(2, 3);
 }
 
-/* LEDs */
-#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
-struct assabet_led {
-	struct led_classdev cdev;
-	u32 mask;
-};
-
-/*
- * The triggers lines up below will only be used if the
- * LED triggers are compiled in.
- */
-static const struct {
-	const char *name;
-	const char *trigger;
-} assabet_leds[] = {
-	{ "assabet:red", "cpu0",},
-	{ "assabet:green", "heartbeat", },
-};
-
-/*
- * The LED control in Assabet is reversed:
- *  - setting bit means turn off LED
- *  - clearing bit means turn on LED
- */
-static void assabet_led_set(struct led_classdev *cdev,
-		enum led_brightness b)
-{
-	struct assabet_led *led = container_of(cdev,
-			struct assabet_led, cdev);
-
-	if (b != LED_OFF)
-		ASSABET_BCR_clear(led->mask);
-	else
-		ASSABET_BCR_set(led->mask);
-}
-
-static enum led_brightness assabet_led_get(struct led_classdev *cdev)
-{
-	struct assabet_led *led = container_of(cdev,
-			struct assabet_led, cdev);
-
-	return (ASSABET_BCR & led->mask) ? LED_OFF : LED_FULL;
-}
-
-static int __init assabet_leds_init(void)
-{
-	int i;
-
-	if (!machine_is_assabet())
-		return -ENODEV;
-
-	for (i = 0; i < ARRAY_SIZE(assabet_leds); i++) {
-		struct assabet_led *led;
-
-		led = kzalloc(sizeof(*led), GFP_KERNEL);
-		if (!led)
-			break;
-
-		led->cdev.name = assabet_leds[i].name;
-		led->cdev.brightness_set = assabet_led_set;
-		led->cdev.brightness_get = assabet_led_get;
-		led->cdev.default_trigger = assabet_leds[i].trigger;
-
-		if (!i)
-			led->mask = ASSABET_BCR_LED_RED;
-		else
-			led->mask = ASSABET_BCR_LED_GREEN;
-
-		if (led_classdev_register(NULL, &led->cdev) < 0) {
-			kfree(led);
-			break;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * Since we may have triggers on any subsystem, defer registration
- * until after subsystem_init.
- */
-fs_initcall(assabet_leds_init);
-#endif
-
 void __init assabet_init_irq(void)
 {
 	unsigned int assabet_gpio_base;
@@ -872,6 +808,9 @@ void __init assabet_init_irq(void)
 	assabet_gpio_base = assabet_init_gpio((void *)&ASSABET_BCR, def_val);
 
 	assabet_cf_vcc_pdata.gpio = assabet_gpio_base + 0;
+
+	assabet_leds[0].gpio = assabet_gpio_base + 13;
+	assabet_leds[1].gpio = assabet_gpio_base + 14;
 }
 
 MACHINE_START(ASSABET, "Intel-Assabet")
-- 
2.1.0

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

* [PATCH 3/3] ARM: sa1100/cerf: switch to using gpio_led_register_device()
  2016-08-29 11:01   ` [PATCH 0/3] SA11x0 gpio keys/leds Russell King - ARM Linux
  2016-08-29 11:03     ` [PATCH 1/3] ARM: sa1100/assabet: add gpio keys support for right-hand two buttons Russell King
  2016-08-29 11:03     ` [PATCH 2/3] ARM: sa1100/assabet: switch to using gpio leds Russell King
@ 2016-08-29 11:03     ` Russell King
  2016-08-29 11:25       ` Russell King - ARM Linux
  3 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

Rather than statically declaring the leds-gpio device, use the helper
function provided.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/Kconfig |  1 +
 arch/arm/mach-sa1100/cerf.c  | 11 +----------
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index b34f229fbfb4..d186d8c5029b 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -23,6 +23,7 @@ config ASSABET_NEPONSET
 config SA1100_CERF
 	bool "CerfBoard"
 	select ARM_SA1110_CPUFREQ
+	select LEDS_GPIO_REGISTER
 	help
 	  The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
 	  More information is available at:
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index b2a4b41626ef..88e526561a24 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -89,18 +89,8 @@ static struct gpio_led_platform_data cerf_gpio_led_info = {
 	.num_leds	= ARRAY_SIZE(cerf_gpio_leds),
 };
 
-static struct platform_device cerf_leds = {
-	.name	= "leds-gpio",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &cerf_gpio_led_info,
-	}
-};
-
-
 static struct platform_device *cerf_devices[] __initdata = {
 	&cerfuart2_device,
-	&cerf_leds,
 };
 
 #ifdef CONFIG_SA1100_CERF_FLASH_32MB
@@ -176,6 +166,7 @@ static void __init cerf_init(void)
 {
 	sa11x0_ppc_configure_mcp();
 	platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
+	gpio_led_register_device(-1, &cerf_gpio_led_info);
 	sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
 	sa11x0_register_mcp(&cerf_mcp_data);
 	sa11x0_register_pcmcia(1, &cerf_cf_gpio_table);
-- 
2.1.0

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

* [PATCH 0/8] SA11x0 DMA engine/IrDA updates
  2016-08-29 11:01   ` [PATCH 0/3] SA11x0 gpio keys/leds Russell King - ARM Linux
@ 2016-08-29 11:25       ` Russell King - ARM Linux
  2016-08-29 11:03     ` [PATCH 2/3] ARM: sa1100/assabet: switch to using gpio leds Russell King
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 11:25 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Following on from the previous series of patches, this updates the
SA11x0 DMA engine code to use the modern method of lookup up DMA
channels, and converts the SA11x0 IrDA driver to use this.  We then
convert the SA11x0 IrDA driver to use gpiolib APIs to manipulate the
transceiver FIR mode select, power and range signals.

Obviously, as this is part of a larger series (and has dependencies
on the previous series) this can not be applied to individual
subsystem maintainer trees.

 arch/arm/mach-sa1100/assabet.c            | 44 ++++-----------
 arch/arm/mach-sa1100/collie.c             | 42 ++++----------
 arch/arm/mach-sa1100/generic.c            |  4 +-
 arch/arm/mach-sa1100/generic.h            |  3 +-
 arch/arm/mach-sa1100/h3100.c              | 48 ++++------------
 arch/arm/mach-sa1100/h3600.c              | 48 ++++------------
 drivers/dma/sa11x0-dma.c                  | 32 ++++++-----
 drivers/net/irda/sa1100_ir.c              | 91 ++++++++++++++++++++-----------
 include/linux/platform_data/irda-sa11x0.h | 20 -------
 include/linux/sa11x0-dma.h                | 24 --------
 10 files changed, 127 insertions(+), 229 deletions(-)
 delete mode 100644 include/linux/platform_data/irda-sa11x0.h
 delete mode 100644 include/linux/sa11x0-dma.h

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 0/8] SA11x0 DMA engine/IrDA updates
@ 2016-08-29 11:25       ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 11:25 UTC (permalink / raw)
  To: linux-arm-kernel

Following on from the previous series of patches, this updates the
SA11x0 DMA engine code to use the modern method of lookup up DMA
channels, and converts the SA11x0 IrDA driver to use this.  We then
convert the SA11x0 IrDA driver to use gpiolib APIs to manipulate the
transceiver FIR mode select, power and range signals.

Obviously, as this is part of a larger series (and has dependencies
on the previous series) this can not be applied to individual
subsystem maintainer trees.

 arch/arm/mach-sa1100/assabet.c            | 44 ++++-----------
 arch/arm/mach-sa1100/collie.c             | 42 ++++----------
 arch/arm/mach-sa1100/generic.c            |  4 +-
 arch/arm/mach-sa1100/generic.h            |  3 +-
 arch/arm/mach-sa1100/h3100.c              | 48 ++++------------
 arch/arm/mach-sa1100/h3600.c              | 48 ++++------------
 drivers/dma/sa11x0-dma.c                  | 32 ++++++-----
 drivers/net/irda/sa1100_ir.c              | 91 ++++++++++++++++++++-----------
 include/linux/platform_data/irda-sa11x0.h | 20 -------
 include/linux/sa11x0-dma.h                | 24 --------
 10 files changed, 127 insertions(+), 229 deletions(-)
 delete mode 100644 include/linux/platform_data/irda-sa11x0.h
 delete mode 100644 include/linux/sa11x0-dma.h

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 1/8] dmaengine: sa11x0: add DMA filters
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Add DMA filters for the sa11x0 DMA channels.  This will allow us to
migrate away from directly using the DMA filter function in drivers.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/dma/sa11x0-dma.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 43db255050d2..565bc67fac7e 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -823,6 +823,13 @@ static const struct sa11x0_dma_channel_desc chan_desc[] = {
 	CD(Ser4SSPRc, DDAR_RW),
 };
 
+static const struct dma_slave_map sa11x0_dma_map[] = {
+	{ "sa11x0-ir", "tx", "Ser2ICPTr" },
+	{ "sa11x0-ir", "rx", "Ser2ICPRc" },
+	{ "sa11x0-ssp", "tx", "Ser4SSPTr" },
+	{ "sa11x0-ssp", "rx", "Ser4SSPRc" },
+};
+
 static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
 	struct device *dev)
 {
@@ -909,6 +916,10 @@ static int sa11x0_dma_probe(struct platform_device *pdev)
 	spin_lock_init(&d->lock);
 	INIT_LIST_HEAD(&d->chan_pending);
 
+	d->slave.filter.fn = sa11x0_dma_filter_fn;
+	d->slave.filter.mapcnt = ARRAY_SIZE(sa11x0_dma_map);
+	d->slave.filter.map = sa11x0_dma_map;
+
 	d->base = ioremap(res->start, resource_size(res));
 	if (!d->base) {
 		ret = -ENOMEM;
-- 
2.1.0

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

* [PATCH 1/8] dmaengine: sa11x0: add DMA filters
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

Add DMA filters for the sa11x0 DMA channels.  This will allow us to
migrate away from directly using the DMA filter function in drivers.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/dma/sa11x0-dma.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 43db255050d2..565bc67fac7e 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -823,6 +823,13 @@ static const struct sa11x0_dma_channel_desc chan_desc[] = {
 	CD(Ser4SSPRc, DDAR_RW),
 };
 
+static const struct dma_slave_map sa11x0_dma_map[] = {
+	{ "sa11x0-ir", "tx", "Ser2ICPTr" },
+	{ "sa11x0-ir", "rx", "Ser2ICPRc" },
+	{ "sa11x0-ssp", "tx", "Ser4SSPTr" },
+	{ "sa11x0-ssp", "rx", "Ser4SSPRc" },
+};
+
 static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
 	struct device *dev)
 {
@@ -909,6 +916,10 @@ static int sa11x0_dma_probe(struct platform_device *pdev)
 	spin_lock_init(&d->lock);
 	INIT_LIST_HEAD(&d->chan_pending);
 
+	d->slave.filter.fn = sa11x0_dma_filter_fn;
+	d->slave.filter.mapcnt = ARRAY_SIZE(sa11x0_dma_map);
+	d->slave.filter.map = sa11x0_dma_map;
+
 	d->base = ioremap(res->start, resource_size(res));
 	if (!d->base) {
 		ret = -ENOMEM;
-- 
2.1.0

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

* [PATCH 2/8] net: irda/sa1100_ir: convert to dma_request_slave_channel()
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Convert the sa11x0 irda driver to use the more modern
dma_request_slave_channel() method to get the DMA channel, rather than
using dma_request_channel() with a filter function exported by DMA
driver.  This allows us to get rid of the sa11x0-dma.h include.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/irda/sa1100_ir.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index b6e44ff4e373..7bc9c2955d4b 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -31,7 +31,6 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/sa11x0-dma.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
@@ -124,7 +123,7 @@ static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf,
 	dma_cap_zero(m);
 	dma_cap_set(DMA_SLAVE, m);
 
-	buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name);
+	buf->chan = dma_request_slave_channel(dev, name);
 	if (!buf->chan) {
 		dev_err(dev, "unable to request DMA channel for %s\n",
 			name);
@@ -797,12 +796,12 @@ static int sa1100_irda_start(struct net_device *dev)
 
 	si->speed = 9600;
 
-	err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc",
+	err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "rx",
 				&sa1100_irda_fir_rx);
 	if (err)
 		goto err_rx_dma;
 
-	err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr",
+	err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "tx",
 				&sa1100_irda_sir_tx);
 	if (err)
 		goto err_tx_dma;
-- 
2.1.0

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

* [PATCH 2/8] net: irda/sa1100_ir: convert to dma_request_slave_channel()
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the sa11x0 irda driver to use the more modern
dma_request_slave_channel() method to get the DMA channel, rather than
using dma_request_channel() with a filter function exported by DMA
driver.  This allows us to get rid of the sa11x0-dma.h include.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/irda/sa1100_ir.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index b6e44ff4e373..7bc9c2955d4b 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -31,7 +31,6 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/sa11x0-dma.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
@@ -124,7 +123,7 @@ static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf,
 	dma_cap_zero(m);
 	dma_cap_set(DMA_SLAVE, m);
 
-	buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name);
+	buf->chan = dma_request_slave_channel(dev, name);
 	if (!buf->chan) {
 		dev_err(dev, "unable to request DMA channel for %s\n",
 			name);
@@ -797,12 +796,12 @@ static int sa1100_irda_start(struct net_device *dev)
 
 	si->speed = 9600;
 
-	err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc",
+	err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "rx",
 				&sa1100_irda_fir_rx);
 	if (err)
 		goto err_rx_dma;
 
-	err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr",
+	err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "tx",
 				&sa1100_irda_sir_tx);
 	if (err)
 		goto err_tx_dma;
-- 
2.1.0

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

* [PATCH 3/8] net: irda/sa1100_ir: add gpiod APIs for controlling IrDA transceiver
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Add GPIO support using the gpiod APIs for controlling the IrDA
transceiver modes (FIR vs SIR), power and range.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/irda/sa1100_ir.c | 58 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 7bc9c2955d4b..25c63c9ff33c 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
@@ -72,6 +73,10 @@ struct sa1100_irda {
 
 	int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *);
 	irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *);
+
+	struct gpio_desc	*fsel_gpio;
+	struct gpio_desc	*pwr_gpio;
+	struct gpio_desc	*md_gpio[2];
 };
 
 static int sa1100_irda_set_speed(struct sa1100_irda *, int);
@@ -574,6 +579,8 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 
 		if (si->pdata->set_speed)
 			si->pdata->set_speed(si->dev, speed);
+		if (si->fsel_gpio)
+			gpiod_set_value(si->fsel_gpio, 0);
 
 		si->speed = speed;
 		si->tx_start = sa1100_irda_sir_tx_start;
@@ -600,6 +607,8 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 
 		if (si->pdata->set_speed)
 			si->pdata->set_speed(si->dev, speed);
+		if (si->fsel_gpio)
+			gpiod_set_value(si->fsel_gpio, 1);
 
 		sa1100_irda_rx_alloc(si);
 		sa1100_irda_rx_dma_start(si);
@@ -629,9 +638,19 @@ static int
 __sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
 {
 	int ret = 0;
-	if (si->pdata->set_power)
+	if (si->pdata->set_power) {
 		ret = si->pdata->set_power(si->dev, state);
-	return ret;
+	} else if (si->pwr_gpio) {
+		gpiod_set_value_cansleep(si->pwr_gpio, state);
+	} else if (si->md_gpio[0] && si->md_gpio[1]) {
+		int vals[2];
+
+		vals[0] = state < 2;
+		vals[1] = state == 1 || state == 2;
+
+		gpiod_set_array_value_cansleep(2, si->md_gpio, vals);
+	}
+	return 0;
 }
 
 static inline int
@@ -914,6 +933,21 @@ static const struct net_device_ops sa1100_irda_netdev_ops = {
 	.ndo_do_ioctl		= sa1100_irda_ioctl,
 };
 
+static int sa1100_irda_get_gpio(struct device *dev, struct gpio_desc **descp,
+	const char *name, enum gpiod_flags flags)
+{
+	struct gpio_desc *desc = devm_gpiod_get_optional(dev, name, flags);
+
+	if (IS_ERR(desc)) {
+		int err = PTR_ERR(desc);
+		dev_err(dev, "unable to get %s gpio: %d\n", name, err);
+		return err;
+	}
+
+	*descp = desc;
+	return 0;
+}
+
 static int sa1100_irda_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
@@ -950,6 +984,26 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 	si->dev = &pdev->dev;
 	si->pdata = pdev->dev.platform_data;
 
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->fsel_gpio, "ir-fsel",
+				   GPIOD_OUT_LOW);
+	if (err)
+		goto err_mem_5;
+
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->pwr_gpio, "ir-power",
+				   GPIOD_OUT_LOW);
+	if (err)
+		goto err_mem_5;
+
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->md_gpio[0], "ir-md0",
+				   GPIOD_OUT_HIGH);
+	if (err)
+		goto err_mem_5;
+
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->md_gpio[1], "ir-md1",
+				   GPIOD_OUT_LOW);
+	if (err)
+		goto err_mem_5;
+
 	sg_init_table(&si->dma_rx.sg, 1);
 	sg_init_table(&si->dma_tx.sg, 1);
 
-- 
2.1.0

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

* [PATCH 3/8] net: irda/sa1100_ir: add gpiod APIs for controlling IrDA transceiver
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

Add GPIO support using the gpiod APIs for controlling the IrDA
transceiver modes (FIR vs SIR), power and range.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/irda/sa1100_ir.c | 58 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 7bc9c2955d4b..25c63c9ff33c 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
@@ -72,6 +73,10 @@ struct sa1100_irda {
 
 	int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *);
 	irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *);
+
+	struct gpio_desc	*fsel_gpio;
+	struct gpio_desc	*pwr_gpio;
+	struct gpio_desc	*md_gpio[2];
 };
 
 static int sa1100_irda_set_speed(struct sa1100_irda *, int);
@@ -574,6 +579,8 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 
 		if (si->pdata->set_speed)
 			si->pdata->set_speed(si->dev, speed);
+		if (si->fsel_gpio)
+			gpiod_set_value(si->fsel_gpio, 0);
 
 		si->speed = speed;
 		si->tx_start = sa1100_irda_sir_tx_start;
@@ -600,6 +607,8 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 
 		if (si->pdata->set_speed)
 			si->pdata->set_speed(si->dev, speed);
+		if (si->fsel_gpio)
+			gpiod_set_value(si->fsel_gpio, 1);
 
 		sa1100_irda_rx_alloc(si);
 		sa1100_irda_rx_dma_start(si);
@@ -629,9 +638,19 @@ static int
 __sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
 {
 	int ret = 0;
-	if (si->pdata->set_power)
+	if (si->pdata->set_power) {
 		ret = si->pdata->set_power(si->dev, state);
-	return ret;
+	} else if (si->pwr_gpio) {
+		gpiod_set_value_cansleep(si->pwr_gpio, state);
+	} else if (si->md_gpio[0] && si->md_gpio[1]) {
+		int vals[2];
+
+		vals[0] = state < 2;
+		vals[1] = state == 1 || state == 2;
+
+		gpiod_set_array_value_cansleep(2, si->md_gpio, vals);
+	}
+	return 0;
 }
 
 static inline int
@@ -914,6 +933,21 @@ static const struct net_device_ops sa1100_irda_netdev_ops = {
 	.ndo_do_ioctl		= sa1100_irda_ioctl,
 };
 
+static int sa1100_irda_get_gpio(struct device *dev, struct gpio_desc **descp,
+	const char *name, enum gpiod_flags flags)
+{
+	struct gpio_desc *desc = devm_gpiod_get_optional(dev, name, flags);
+
+	if (IS_ERR(desc)) {
+		int err = PTR_ERR(desc);
+		dev_err(dev, "unable to get %s gpio: %d\n", name, err);
+		return err;
+	}
+
+	*descp = desc;
+	return 0;
+}
+
 static int sa1100_irda_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
@@ -950,6 +984,26 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 	si->dev = &pdev->dev;
 	si->pdata = pdev->dev.platform_data;
 
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->fsel_gpio, "ir-fsel",
+				   GPIOD_OUT_LOW);
+	if (err)
+		goto err_mem_5;
+
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->pwr_gpio, "ir-power",
+				   GPIOD_OUT_LOW);
+	if (err)
+		goto err_mem_5;
+
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->md_gpio[0], "ir-md0",
+				   GPIOD_OUT_HIGH);
+	if (err)
+		goto err_mem_5;
+
+	err = sa1100_irda_get_gpio(&pdev->dev, &si->md_gpio[1], "ir-md1",
+				   GPIOD_OUT_LOW);
+	if (err)
+		goto err_mem_5;
+
 	sg_init_table(&si->dma_rx.sg, 1);
 	sg_init_table(&si->dma_tx.sg, 1);
 
-- 
2.1.0

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

* [PATCH 4/8] dmaengine: sa11x0: unexport sa11x0_dma_filter_fn and clean up
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

As we now have no users of sa11x0_dma_filter_fn() in the tree, we can
unexport this function, and remove the now unused header file.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/dma/sa11x0-dma.c   | 21 ++++++++-------------
 include/linux/sa11x0-dma.h | 24 ------------------------
 2 files changed, 8 insertions(+), 37 deletions(-)
 delete mode 100644 include/linux/sa11x0-dma.h

diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 565bc67fac7e..6d942b8c4097 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/sa11x0-dma.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
@@ -830,6 +829,14 @@ static const struct dma_slave_map sa11x0_dma_map[] = {
 	{ "sa11x0-ssp", "rx", "Ser4SSPRc" },
 };
 
+static bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	const char *p = param;
+
+	return !strcmp(c->name, p);
+}
+
 static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
 	struct device *dev)
 {
@@ -1087,18 +1094,6 @@ static struct platform_driver sa11x0_dma_driver = {
 	.remove		= sa11x0_dma_remove,
 };
 
-bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
-{
-	if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {
-		struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
-		const char *p = param;
-
-		return !strcmp(c->name, p);
-	}
-	return false;
-}
-EXPORT_SYMBOL(sa11x0_dma_filter_fn);
-
 static int __init sa11x0_dma_init(void)
 {
 	return platform_driver_register(&sa11x0_dma_driver);
diff --git a/include/linux/sa11x0-dma.h b/include/linux/sa11x0-dma.h
deleted file mode 100644
index 65839a58b8e5..000000000000
--- a/include/linux/sa11x0-dma.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SA11x0 DMA Engine support
- *
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __LINUX_SA11X0_DMA_H
-#define __LINUX_SA11X0_DMA_H
-
-struct dma_chan;
-
-#if defined(CONFIG_DMA_SA11X0) || defined(CONFIG_DMA_SA11X0_MODULE)
-bool sa11x0_dma_filter_fn(struct dma_chan *, void *);
-#else
-static inline bool sa11x0_dma_filter_fn(struct dma_chan *c, void *d)
-{
-	return false;
-}
-#endif
-
-#endif
-- 
2.1.0

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

* [PATCH 4/8] dmaengine: sa11x0: unexport sa11x0_dma_filter_fn and clean up
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

As we now have no users of sa11x0_dma_filter_fn() in the tree, we can
unexport this function, and remove the now unused header file.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/dma/sa11x0-dma.c   | 21 ++++++++-------------
 include/linux/sa11x0-dma.h | 24 ------------------------
 2 files changed, 8 insertions(+), 37 deletions(-)
 delete mode 100644 include/linux/sa11x0-dma.h

diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 565bc67fac7e..6d942b8c4097 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/sa11x0-dma.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
@@ -830,6 +829,14 @@ static const struct dma_slave_map sa11x0_dma_map[] = {
 	{ "sa11x0-ssp", "rx", "Ser4SSPRc" },
 };
 
+static bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	const char *p = param;
+
+	return !strcmp(c->name, p);
+}
+
 static int sa11x0_dma_init_dmadev(struct dma_device *dmadev,
 	struct device *dev)
 {
@@ -1087,18 +1094,6 @@ static struct platform_driver sa11x0_dma_driver = {
 	.remove		= sa11x0_dma_remove,
 };
 
-bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
-{
-	if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {
-		struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
-		const char *p = param;
-
-		return !strcmp(c->name, p);
-	}
-	return false;
-}
-EXPORT_SYMBOL(sa11x0_dma_filter_fn);
-
 static int __init sa11x0_dma_init(void)
 {
 	return platform_driver_register(&sa11x0_dma_driver);
diff --git a/include/linux/sa11x0-dma.h b/include/linux/sa11x0-dma.h
deleted file mode 100644
index 65839a58b8e5..000000000000
--- a/include/linux/sa11x0-dma.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * SA11x0 DMA Engine support
- *
- * Copyright (C) 2012 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __LINUX_SA11X0_DMA_H
-#define __LINUX_SA11X0_DMA_H
-
-struct dma_chan;
-
-#if defined(CONFIG_DMA_SA11X0) || defined(CONFIG_DMA_SA11X0_MODULE)
-bool sa11x0_dma_filter_fn(struct dma_chan *, void *);
-#else
-static inline bool sa11x0_dma_filter_fn(struct dma_chan *c, void *d)
-{
-	return false;
-}
-#endif
-
-#endif
-- 
2.1.0

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

* [PATCH 5/8] ARM: sa1100/assabet: switch assabet IrDA to use gpiod APIs
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Switch the IrDA code to use the gpiod APIs rather than platform data
with function callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c | 42 +++++++++++++-----------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index af5cea464a10..ba180eebd6ab 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -303,36 +303,18 @@ static struct resource assabet_flash_resources[] = {
 };
 
 
-/*
- * Assabet IrDA support code.
- */
-
-static int assabet_irda_set_power(struct device *dev, unsigned int state)
-{
-	static unsigned int bcr_state[4] = {
-		ASSABET_BCR_IRDA_MD0,
-		ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0,
-		ASSABET_BCR_IRDA_MD1,
-		0
-	};
-
-	if (state < 4)
-		ASSABET_BCR_frob(ASSABET_BCR_IRDA_MD1 | ASSABET_BCR_IRDA_MD0,
-				 bcr_state[state]);
-	return 0;
-}
-
-static void assabet_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	if (speed < 4000000)
-		ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
-	else
-		ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
-}
-
 static struct irda_platform_data assabet_irda_data = {
-	.set_power	= assabet_irda_set_power,
-	.set_speed	= assabet_irda_set_speed,
+};
+
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table assabet_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("assabet", 3, "ir-fsel", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 4, "ir-md0", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 5, "ir-md1", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static struct ucb1x00_plat_data assabet_ucb1x00_data = {
@@ -539,6 +521,8 @@ static const struct gpio_keys_platform_data assabet_keys_pdata = {
 
 static void __init assabet_init(void)
 {
+	gpiod_add_lookup_table(&assabet_irda_gpio_table);
+
 	/*
 	 * Ensure that the power supply is in "high power" mode.
 	 */
-- 
2.1.0

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

* [PATCH 5/8] ARM: sa1100/assabet: switch assabet IrDA to use gpiod APIs
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

Switch the IrDA code to use the gpiod APIs rather than platform data
with function callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c | 42 +++++++++++++-----------------------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index af5cea464a10..ba180eebd6ab 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -303,36 +303,18 @@ static struct resource assabet_flash_resources[] = {
 };
 
 
-/*
- * Assabet IrDA support code.
- */
-
-static int assabet_irda_set_power(struct device *dev, unsigned int state)
-{
-	static unsigned int bcr_state[4] = {
-		ASSABET_BCR_IRDA_MD0,
-		ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0,
-		ASSABET_BCR_IRDA_MD1,
-		0
-	};
-
-	if (state < 4)
-		ASSABET_BCR_frob(ASSABET_BCR_IRDA_MD1 | ASSABET_BCR_IRDA_MD0,
-				 bcr_state[state]);
-	return 0;
-}
-
-static void assabet_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	if (speed < 4000000)
-		ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
-	else
-		ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
-}
-
 static struct irda_platform_data assabet_irda_data = {
-	.set_power	= assabet_irda_set_power,
-	.set_speed	= assabet_irda_set_speed,
+};
+
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table assabet_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("assabet", 3, "ir-fsel", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 4, "ir-md0", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("assabet", 5, "ir-md1", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static struct ucb1x00_plat_data assabet_ucb1x00_data = {
@@ -539,6 +521,8 @@ static const struct gpio_keys_platform_data assabet_keys_pdata = {
 
 static void __init assabet_init(void)
 {
+	gpiod_add_lookup_table(&assabet_irda_gpio_table);
+
 	/*
 	 * Ensure that the power supply is in "high power" mode.
 	 */
-- 
2.1.0

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

* [PATCH 6/8] ARM: sa1100/collie: switch collie IrDA to use gpiod APIs
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Switch the IrDA code to use the gpiod APIs rather than platform data
with function callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/collie.c | 40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 3cc2b71e16f0..8ed0cbfaa0f4 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/delay.h>
+#include <linux/gpio/machine.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ucb1x00.h>
@@ -97,35 +98,16 @@ static struct mcp_plat_data collie_mcp_data = {
 	.codec_pdata	= &collie_ucb1x00_data,
 };
 
-static int collie_ir_startup(struct device *dev)
-{
-	int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
-	if (rc)
-		return rc;
-	rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);
-
-	if (!rc)
-		return 0;
-
-	gpio_free(COLLIE_GPIO_IR_ON);
-	return rc;
-}
-
-static void collie_ir_shutdown(struct device *dev)
-{
-	gpio_free(COLLIE_GPIO_IR_ON);
-}
-
-static int collie_ir_set_power(struct device *dev, unsigned int state)
-{
-	gpio_set_value(COLLIE_GPIO_IR_ON, !state);
-	return 0;
-}
-
 static struct irda_platform_data collie_ir_data = {
-	.startup = collie_ir_startup,
-	.shutdown = collie_ir_shutdown,
-	.set_power = collie_ir_set_power,
+};
+
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table collie_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("ucb1x00", 3, "ir-power", GPIO_ACTIVE_LOW),
+		{ },
+	},
 };
 
 /*
@@ -357,6 +339,8 @@ static void __init collie_init(void)
 {
 	int ret = 0;
 
+	gpiod_add_lookup_table(&collie_irda_gpio_table);
+
 	/* cpu initialize */
 	GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK |
 		GPIO_MCP_CLK | GPIO_32_768kHz;
-- 
2.1.0

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

* [PATCH 6/8] ARM: sa1100/collie: switch collie IrDA to use gpiod APIs
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

Switch the IrDA code to use the gpiod APIs rather than platform data
with function callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/collie.c | 40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)

diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 3cc2b71e16f0..8ed0cbfaa0f4 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/delay.h>
+#include <linux/gpio/machine.h>
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ucb1x00.h>
@@ -97,35 +98,16 @@ static struct mcp_plat_data collie_mcp_data = {
 	.codec_pdata	= &collie_ucb1x00_data,
 };
 
-static int collie_ir_startup(struct device *dev)
-{
-	int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
-	if (rc)
-		return rc;
-	rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);
-
-	if (!rc)
-		return 0;
-
-	gpio_free(COLLIE_GPIO_IR_ON);
-	return rc;
-}
-
-static void collie_ir_shutdown(struct device *dev)
-{
-	gpio_free(COLLIE_GPIO_IR_ON);
-}
-
-static int collie_ir_set_power(struct device *dev, unsigned int state)
-{
-	gpio_set_value(COLLIE_GPIO_IR_ON, !state);
-	return 0;
-}
-
 static struct irda_platform_data collie_ir_data = {
-	.startup = collie_ir_startup,
-	.shutdown = collie_ir_shutdown,
-	.set_power = collie_ir_set_power,
+};
+
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table collie_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("ucb1x00", 3, "ir-power", GPIO_ACTIVE_LOW),
+		{ },
+	},
 };
 
 /*
@@ -357,6 +339,8 @@ static void __init collie_init(void)
 {
 	int ret = 0;
 
+	gpiod_add_lookup_table(&collie_irda_gpio_table);
+
 	/* cpu initialize */
 	GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK |
 		GPIO_MCP_CLK | GPIO_32_768kHz;
-- 
2.1.0

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

* [PATCH 7/8] ARM: sa1100/h3xxx: switch h3xxx IrDA to use gpiod APIs
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

Switch the IrDA code to use the gpiod APIs rather than platform data
with function callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/h3100.c | 44 ++++++++++++--------------------------------
 arch/arm/mach-sa1100/h3600.c | 44 ++++++++++++--------------------------------
 2 files changed, 24 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index c6b412054a3c..9930e8a6cd43 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 
 #include <video/sa1100fb.h>
 
@@ -86,44 +87,23 @@ static void __init h3100_map_io(void)
 	GAFR &= ~0x000001fb;
 }
 
-/*
- * This turns the IRDA power on or off on the Compaq H3100
- */
-static struct gpio h3100_irda_gpio[] = {
-	{ H3100_GPIO_IR_ON,	GPIOF_OUT_INIT_LOW, "IrDA power" },
-	{ H3100_GPIO_IR_FSEL,	GPIOF_OUT_INIT_LOW, "IrDA fsel" },
+static struct irda_platform_data h3100_irda_data = {
 };
 
-static int h3100_irda_set_power(struct device *dev, unsigned int state)
-{
-	gpio_set_value(H3100_GPIO_IR_ON, state);
-	return 0;
-}
-
-static void h3100_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000));
-}
-
-static int h3100_irda_startup(struct device *dev)
-{
-	return gpio_request_array(h3100_irda_gpio, sizeof(h3100_irda_gpio));
-}
-
-static void h3100_irda_shutdown(struct device *dev)
-{
-	return gpio_free_array(h3100_irda_gpio, sizeof(h3100_irda_gpio));
-}
-
-static struct irda_platform_data h3100_irda_data = {
-	.set_power	= h3100_irda_set_power,
-	.set_speed	= h3100_irda_set_speed,
-	.startup	= h3100_irda_startup,
-	.shutdown	= h3100_irda_shutdown,
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table h3100_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("gpio", 8, "ir-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 9, "ir-fsel", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init h3100_mach_init(void)
 {
+	gpiod_add_lookup_table(&h3100_irda_gpio_table);
+
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3100_lcd_info);
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 118338efd790..1a925ab9aa51 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 
 #include <video/sa1100fb.h>
 
@@ -94,44 +95,23 @@ static void __init h3600_map_io(void)
 	h3xxx_map_io();
 }
 
-/*
- * This turns the IRDA power on or off on the Compaq H3600
- */
-static struct gpio h3600_irda_gpio[] = {
-	{ H3600_EGPIO_IR_ON,	GPIOF_OUT_INIT_LOW, "IrDA power" },
-	{ H3600_EGPIO_IR_FSEL,	GPIOF_OUT_INIT_LOW, "IrDA fsel" },
+static struct irda_platform_data h3600_irda_data = {
 };
 
-static int h3600_irda_set_power(struct device *dev, unsigned int state)
-{
-	gpio_set_value(H3600_EGPIO_IR_ON, state);
-	return 0;
-}
-
-static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	gpio_set_value(H3600_EGPIO_IR_FSEL, !(speed < 4000000));
-}
-
-static int h3600_irda_startup(struct device *dev)
-{
-	return gpio_request_array(h3600_irda_gpio, sizeof(h3600_irda_gpio));
-}
-
-static void h3600_irda_shutdown(struct device *dev)
-{
-	return gpio_free_array(h3600_irda_gpio, sizeof(h3600_irda_gpio));
-}
-
-static struct irda_platform_data h3600_irda_data = {
-	.set_power	= h3600_irda_set_power,
-	.set_speed	= h3600_irda_set_speed,
-	.startup	= h3600_irda_startup,
-	.shutdown	= h3600_irda_shutdown,
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table h3600_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("htc-egpio", 9, "ir-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("htc-egpio", 13, "ir-fsel", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init h3600_mach_init(void)
 {
+	gpiod_add_lookup_table(&h3600_irda_gpio_table);
+
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3600_lcd_info);
-- 
2.1.0

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

* [PATCH 7/8] ARM: sa1100/h3xxx: switch h3xxx IrDA to use gpiod APIs
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

Switch the IrDA code to use the gpiod APIs rather than platform data
with function callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/h3100.c | 44 ++++++++++++--------------------------------
 arch/arm/mach-sa1100/h3600.c | 44 ++++++++++++--------------------------------
 2 files changed, 24 insertions(+), 64 deletions(-)

diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index c6b412054a3c..9930e8a6cd43 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 
 #include <video/sa1100fb.h>
 
@@ -86,44 +87,23 @@ static void __init h3100_map_io(void)
 	GAFR &= ~0x000001fb;
 }
 
-/*
- * This turns the IRDA power on or off on the Compaq H3100
- */
-static struct gpio h3100_irda_gpio[] = {
-	{ H3100_GPIO_IR_ON,	GPIOF_OUT_INIT_LOW, "IrDA power" },
-	{ H3100_GPIO_IR_FSEL,	GPIOF_OUT_INIT_LOW, "IrDA fsel" },
+static struct irda_platform_data h3100_irda_data = {
 };
 
-static int h3100_irda_set_power(struct device *dev, unsigned int state)
-{
-	gpio_set_value(H3100_GPIO_IR_ON, state);
-	return 0;
-}
-
-static void h3100_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000));
-}
-
-static int h3100_irda_startup(struct device *dev)
-{
-	return gpio_request_array(h3100_irda_gpio, sizeof(h3100_irda_gpio));
-}
-
-static void h3100_irda_shutdown(struct device *dev)
-{
-	return gpio_free_array(h3100_irda_gpio, sizeof(h3100_irda_gpio));
-}
-
-static struct irda_platform_data h3100_irda_data = {
-	.set_power	= h3100_irda_set_power,
-	.set_speed	= h3100_irda_set_speed,
-	.startup	= h3100_irda_startup,
-	.shutdown	= h3100_irda_shutdown,
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table h3100_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("gpio", 8, "ir-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio", 9, "ir-fsel", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init h3100_mach_init(void)
 {
+	gpiod_add_lookup_table(&h3100_irda_gpio_table);
+
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3100_lcd_info);
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 118338efd790..1a925ab9aa51 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 
 #include <video/sa1100fb.h>
 
@@ -94,44 +95,23 @@ static void __init h3600_map_io(void)
 	h3xxx_map_io();
 }
 
-/*
- * This turns the IRDA power on or off on the Compaq H3600
- */
-static struct gpio h3600_irda_gpio[] = {
-	{ H3600_EGPIO_IR_ON,	GPIOF_OUT_INIT_LOW, "IrDA power" },
-	{ H3600_EGPIO_IR_FSEL,	GPIOF_OUT_INIT_LOW, "IrDA fsel" },
+static struct irda_platform_data h3600_irda_data = {
 };
 
-static int h3600_irda_set_power(struct device *dev, unsigned int state)
-{
-	gpio_set_value(H3600_EGPIO_IR_ON, state);
-	return 0;
-}
-
-static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
-{
-	gpio_set_value(H3600_EGPIO_IR_FSEL, !(speed < 4000000));
-}
-
-static int h3600_irda_startup(struct device *dev)
-{
-	return gpio_request_array(h3600_irda_gpio, sizeof(h3600_irda_gpio));
-}
-
-static void h3600_irda_shutdown(struct device *dev)
-{
-	return gpio_free_array(h3600_irda_gpio, sizeof(h3600_irda_gpio));
-}
-
-static struct irda_platform_data h3600_irda_data = {
-	.set_power	= h3600_irda_set_power,
-	.set_speed	= h3600_irda_set_speed,
-	.startup	= h3600_irda_startup,
-	.shutdown	= h3600_irda_shutdown,
+/* IrDA GPIO mappings */
+static struct gpiod_lookup_table h3600_irda_gpio_table = {
+	.dev_id = "sa11x0-ir",
+	.table = {
+		GPIO_LOOKUP("htc-egpio", 9, "ir-power", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("htc-egpio", 13, "ir-fsel", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init h3600_mach_init(void)
 {
+	gpiod_add_lookup_table(&h3600_irda_gpio_table);
+
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3600_lcd_info);
-- 
2.1.0

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

* [PATCH 8/8] net: irda/sa1100_ir: remove sa11x0 irda platform data
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 11:26         ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: dmaengine, linux-arm-kernel, netdev
  Cc: Dan Williams, Samuel Ortiz, Vinod Koul

There is now no need for the sa11x0 IrDA platform data, so remove
the header file and all locations that include it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c            |  6 +-----
 arch/arm/mach-sa1100/collie.c             |  6 +-----
 arch/arm/mach-sa1100/generic.c            |  4 ++--
 arch/arm/mach-sa1100/generic.h            |  3 +--
 arch/arm/mach-sa1100/h3100.c              |  6 +-----
 arch/arm/mach-sa1100/h3600.c              |  6 +-----
 drivers/net/irda/sa1100_ir.c              | 30 +-----------------------------
 include/linux/platform_data/irda-sa11x0.h | 20 --------------------
 8 files changed, 8 insertions(+), 73 deletions(-)
 delete mode 100644 include/linux/platform_data/irda-sa11x0.h

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index ba180eebd6ab..14a75735e9d0 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -42,7 +42,6 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <linux/platform_data/irda-sa11x0.h>
 #include <asm/mach/map.h>
 #include <mach/assabet.h>
 #include <linux/platform_data/mfd-mcp-sa11x0.h>
@@ -303,9 +302,6 @@ static struct resource assabet_flash_resources[] = {
 };
 
 
-static struct irda_platform_data assabet_irda_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table assabet_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -586,7 +582,7 @@ static void __init assabet_init(void)
 #endif
 	sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
 			    ARRAY_SIZE(assabet_flash_resources));
-	sa11x0_register_irda(&assabet_irda_data);
+	sa11x0_register_irda();
 	sa11x0_register_mcp(&assabet_mcp_data);
 
 	if (!machine_has_neponset())
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 8ed0cbfaa0f4..5f1549ed19d2 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -44,7 +44,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
@@ -98,9 +97,6 @@ static struct mcp_plat_data collie_mcp_data = {
 	.codec_pdata	= &collie_ucb1x00_data,
 };
 
-static struct irda_platform_data collie_ir_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table collie_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -379,7 +375,7 @@ static void __init collie_init(void)
 	sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
 			    ARRAY_SIZE(collie_flash_resources));
 	sa11x0_register_mcp(&collie_mcp_data);
-	sa11x0_register_irda(&collie_ir_data);
+	sa11x0_register_irda();
 
 	sharpsl_save_param();
 }
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index a005eef1a24e..5d2e68984303 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -274,9 +274,9 @@ static struct platform_device sa11x0ir_device = {
 	.resource	= sa11x0ir_resources,
 };
 
-void sa11x0_register_irda(struct irda_platform_data *irda)
+void sa11x0_register_irda(void)
 {
-	sa11x0_register_device(&sa11x0ir_device, irda);
+	sa11x0_register_device(&sa11x0ir_device, NULL);
 }
 
 static struct resource sa1100_rtc_resources[] = {
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 22c432979150..b733c98214bd 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -29,8 +29,7 @@ struct resource;
 void sa11x0_register_mtd(struct flash_platform_data *flash,
 			 struct resource *res, int nr);
 
-struct irda_platform_data;
-void sa11x0_register_irda(struct irda_platform_data *irda);
+void sa11x0_register_irda(void);
 
 struct mcp_plat_data;
 void sa11x0_ppc_configure_mcp(void);
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index 9930e8a6cd43..8c1a105ba2d1 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -19,7 +19,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 #include <mach/h3xxx.h>
 #include <mach/irqs.h>
@@ -87,9 +86,6 @@ static void __init h3100_map_io(void)
 	GAFR &= ~0x000001fb;
 }
 
-static struct irda_platform_data h3100_irda_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table h3100_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -107,7 +103,7 @@ static void __init h3100_mach_init(void)
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3100_lcd_info);
-	sa11x0_register_irda(&h3100_irda_data);
+	sa11x0_register_irda();
 }
 
 MACHINE_START(H3100, "Compaq iPAQ H3100")
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 1a925ab9aa51..14a7ad77b076 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -19,7 +19,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 #include <mach/h3xxx.h>
 #include <mach/irqs.h>
@@ -95,9 +94,6 @@ static void __init h3600_map_io(void)
 	h3xxx_map_io();
 }
 
-static struct irda_platform_data h3600_irda_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table h3600_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -115,7 +111,7 @@ static void __init h3600_mach_init(void)
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3600_lcd_info);
-	sa11x0_register_irda(&h3600_irda_data);
+	sa11x0_register_irda();
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 25c63c9ff33c..3a8b9d5d61d1 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -38,7 +38,6 @@
 #include <net/irda/irda_device.h>
 
 #include <mach/hardware.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 static int power_level = 3;
 static int tx_lpm;
@@ -64,7 +63,6 @@ struct sa1100_irda {
 	struct sa1100_buf	dma_tx;
 
 	struct device		*dev;
-	struct irda_platform_data *pdata;
 	struct irlap_cb		*irlap;
 	struct qos_info		qos;
 
@@ -577,8 +575,6 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 		Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
 		Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
 
-		if (si->pdata->set_speed)
-			si->pdata->set_speed(si->dev, speed);
 		if (si->fsel_gpio)
 			gpiod_set_value(si->fsel_gpio, 0);
 
@@ -605,8 +601,6 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 		si->tx_start = sa1100_irda_fir_tx_start;
 		si->irq = sa1100_irda_fir_irq;
 
-		if (si->pdata->set_speed)
-			si->pdata->set_speed(si->dev, speed);
 		if (si->fsel_gpio)
 			gpiod_set_value(si->fsel_gpio, 1);
 
@@ -637,10 +631,7 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 static int
 __sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
 {
-	int ret = 0;
-	if (si->pdata->set_power) {
-		ret = si->pdata->set_power(si->dev, state);
-	} else if (si->pwr_gpio) {
+	if (si->pwr_gpio) {
 		gpiod_set_value_cansleep(si->pwr_gpio, state);
 	} else if (si->md_gpio[0] && si->md_gpio[1]) {
 		int vals[2];
@@ -750,15 +741,6 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
 	int ret;
 
 	/*
-	 * Ensure that the ports for this device are setup correctly.
-	 */
-	if (si->pdata->startup)	{
-		ret = si->pdata->startup(si->dev);
-		if (ret)
-			return ret;
-	}
-
-	/*
 	 * Configure PPC for IRDA - we want to drive TXD2 low.
 	 * We also want to drive this pin low during sleep.
 	 */
@@ -784,9 +766,6 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
 	if (ret) {
 		Ser2UTCR3 = 0;
 		Ser2HSCR0 = 0;
-
-		if (si->pdata->shutdown)
-			si->pdata->shutdown(si->dev);
 	}
 
 	return ret;
@@ -803,9 +782,6 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
 	/* Disable the port. */
 	Ser2UTCR3 = 0;
 	Ser2HSCR0 = 0;
-
-	if (si->pdata->shutdown)
-		si->pdata->shutdown(si->dev);
 }
 
 static int sa1100_irda_start(struct net_device *dev)
@@ -955,9 +931,6 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 	unsigned int baudrate_mask;
 	int err, irq;
 
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq <= 0)
 		return irq < 0 ? irq : -ENXIO;
@@ -982,7 +955,6 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 
 	si = netdev_priv(dev);
 	si->dev = &pdev->dev;
-	si->pdata = pdev->dev.platform_data;
 
 	err = sa1100_irda_get_gpio(&pdev->dev, &si->fsel_gpio, "ir-fsel",
 				   GPIOD_OUT_LOW);
diff --git a/include/linux/platform_data/irda-sa11x0.h b/include/linux/platform_data/irda-sa11x0.h
deleted file mode 100644
index 38f77b5e56cf..000000000000
--- a/include/linux/platform_data/irda-sa11x0.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *  arch/arm/include/asm/mach/irda.h
- *
- *  Copyright (C) 2004 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARM_MACH_IRDA_H
-#define __ASM_ARM_MACH_IRDA_H
-
-struct irda_platform_data {
-	int (*startup)(struct device *);
-	void (*shutdown)(struct device *);
-	int (*set_power)(struct device *, unsigned int state);
-	void (*set_speed)(struct device *, unsigned int speed);
-};
-
-#endif
-- 
2.1.0

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

* [PATCH 8/8] net: irda/sa1100_ir: remove sa11x0 irda platform data
@ 2016-08-29 11:26         ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 11:26 UTC (permalink / raw)
  To: linux-arm-kernel

There is now no need for the sa11x0 IrDA platform data, so remove
the header file and all locations that include it.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c            |  6 +-----
 arch/arm/mach-sa1100/collie.c             |  6 +-----
 arch/arm/mach-sa1100/generic.c            |  4 ++--
 arch/arm/mach-sa1100/generic.h            |  3 +--
 arch/arm/mach-sa1100/h3100.c              |  6 +-----
 arch/arm/mach-sa1100/h3600.c              |  6 +-----
 drivers/net/irda/sa1100_ir.c              | 30 +-----------------------------
 include/linux/platform_data/irda-sa11x0.h | 20 --------------------
 8 files changed, 8 insertions(+), 73 deletions(-)
 delete mode 100644 include/linux/platform_data/irda-sa11x0.h

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index ba180eebd6ab..14a75735e9d0 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -42,7 +42,6 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
-#include <linux/platform_data/irda-sa11x0.h>
 #include <asm/mach/map.h>
 #include <mach/assabet.h>
 #include <linux/platform_data/mfd-mcp-sa11x0.h>
@@ -303,9 +302,6 @@ static struct resource assabet_flash_resources[] = {
 };
 
 
-static struct irda_platform_data assabet_irda_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table assabet_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -586,7 +582,7 @@ static void __init assabet_init(void)
 #endif
 	sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
 			    ARRAY_SIZE(assabet_flash_resources));
-	sa11x0_register_irda(&assabet_irda_data);
+	sa11x0_register_irda();
 	sa11x0_register_mcp(&assabet_mcp_data);
 
 	if (!machine_has_neponset())
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 8ed0cbfaa0f4..5f1549ed19d2 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -44,7 +44,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
@@ -98,9 +97,6 @@ static struct mcp_plat_data collie_mcp_data = {
 	.codec_pdata	= &collie_ucb1x00_data,
 };
 
-static struct irda_platform_data collie_ir_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table collie_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -379,7 +375,7 @@ static void __init collie_init(void)
 	sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
 			    ARRAY_SIZE(collie_flash_resources));
 	sa11x0_register_mcp(&collie_mcp_data);
-	sa11x0_register_irda(&collie_ir_data);
+	sa11x0_register_irda();
 
 	sharpsl_save_param();
 }
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index a005eef1a24e..5d2e68984303 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -274,9 +274,9 @@ static struct platform_device sa11x0ir_device = {
 	.resource	= sa11x0ir_resources,
 };
 
-void sa11x0_register_irda(struct irda_platform_data *irda)
+void sa11x0_register_irda(void)
 {
-	sa11x0_register_device(&sa11x0ir_device, irda);
+	sa11x0_register_device(&sa11x0ir_device, NULL);
 }
 
 static struct resource sa1100_rtc_resources[] = {
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 22c432979150..b733c98214bd 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -29,8 +29,7 @@ struct resource;
 void sa11x0_register_mtd(struct flash_platform_data *flash,
 			 struct resource *res, int nr);
 
-struct irda_platform_data;
-void sa11x0_register_irda(struct irda_platform_data *irda);
+void sa11x0_register_irda(void);
 
 struct mcp_plat_data;
 void sa11x0_ppc_configure_mcp(void);
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index 9930e8a6cd43..8c1a105ba2d1 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -19,7 +19,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 #include <mach/h3xxx.h>
 #include <mach/irqs.h>
@@ -87,9 +86,6 @@ static void __init h3100_map_io(void)
 	GAFR &= ~0x000001fb;
 }
 
-static struct irda_platform_data h3100_irda_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table h3100_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -107,7 +103,7 @@ static void __init h3100_mach_init(void)
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3100_lcd_info);
-	sa11x0_register_irda(&h3100_irda_data);
+	sa11x0_register_irda();
 }
 
 MACHINE_START(H3100, "Compaq iPAQ H3100")
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 1a925ab9aa51..14a7ad77b076 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -19,7 +19,6 @@
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 #include <mach/h3xxx.h>
 #include <mach/irqs.h>
@@ -95,9 +94,6 @@ static void __init h3600_map_io(void)
 	h3xxx_map_io();
 }
 
-static struct irda_platform_data h3600_irda_data = {
-};
-
 /* IrDA GPIO mappings */
 static struct gpiod_lookup_table h3600_irda_gpio_table = {
 	.dev_id = "sa11x0-ir",
@@ -115,7 +111,7 @@ static void __init h3600_mach_init(void)
 	h3xxx_mach_init();
 
 	sa11x0_register_lcd(&h3600_lcd_info);
-	sa11x0_register_irda(&h3600_irda_data);
+	sa11x0_register_irda();
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 25c63c9ff33c..3a8b9d5d61d1 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -38,7 +38,6 @@
 #include <net/irda/irda_device.h>
 
 #include <mach/hardware.h>
-#include <linux/platform_data/irda-sa11x0.h>
 
 static int power_level = 3;
 static int tx_lpm;
@@ -64,7 +63,6 @@ struct sa1100_irda {
 	struct sa1100_buf	dma_tx;
 
 	struct device		*dev;
-	struct irda_platform_data *pdata;
 	struct irlap_cb		*irlap;
 	struct qos_info		qos;
 
@@ -577,8 +575,6 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 		Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
 		Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
 
-		if (si->pdata->set_speed)
-			si->pdata->set_speed(si->dev, speed);
 		if (si->fsel_gpio)
 			gpiod_set_value(si->fsel_gpio, 0);
 
@@ -605,8 +601,6 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 		si->tx_start = sa1100_irda_fir_tx_start;
 		si->irq = sa1100_irda_fir_irq;
 
-		if (si->pdata->set_speed)
-			si->pdata->set_speed(si->dev, speed);
 		if (si->fsel_gpio)
 			gpiod_set_value(si->fsel_gpio, 1);
 
@@ -637,10 +631,7 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 static int
 __sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
 {
-	int ret = 0;
-	if (si->pdata->set_power) {
-		ret = si->pdata->set_power(si->dev, state);
-	} else if (si->pwr_gpio) {
+	if (si->pwr_gpio) {
 		gpiod_set_value_cansleep(si->pwr_gpio, state);
 	} else if (si->md_gpio[0] && si->md_gpio[1]) {
 		int vals[2];
@@ -750,15 +741,6 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
 	int ret;
 
 	/*
-	 * Ensure that the ports for this device are setup correctly.
-	 */
-	if (si->pdata->startup)	{
-		ret = si->pdata->startup(si->dev);
-		if (ret)
-			return ret;
-	}
-
-	/*
 	 * Configure PPC for IRDA - we want to drive TXD2 low.
 	 * We also want to drive this pin low during sleep.
 	 */
@@ -784,9 +766,6 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
 	if (ret) {
 		Ser2UTCR3 = 0;
 		Ser2HSCR0 = 0;
-
-		if (si->pdata->shutdown)
-			si->pdata->shutdown(si->dev);
 	}
 
 	return ret;
@@ -803,9 +782,6 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
 	/* Disable the port. */
 	Ser2UTCR3 = 0;
 	Ser2HSCR0 = 0;
-
-	if (si->pdata->shutdown)
-		si->pdata->shutdown(si->dev);
 }
 
 static int sa1100_irda_start(struct net_device *dev)
@@ -955,9 +931,6 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 	unsigned int baudrate_mask;
 	int err, irq;
 
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq <= 0)
 		return irq < 0 ? irq : -ENXIO;
@@ -982,7 +955,6 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 
 	si = netdev_priv(dev);
 	si->dev = &pdev->dev;
-	si->pdata = pdev->dev.platform_data;
 
 	err = sa1100_irda_get_gpio(&pdev->dev, &si->fsel_gpio, "ir-fsel",
 				   GPIOD_OUT_LOW);
diff --git a/include/linux/platform_data/irda-sa11x0.h b/include/linux/platform_data/irda-sa11x0.h
deleted file mode 100644
index 38f77b5e56cf..000000000000
--- a/include/linux/platform_data/irda-sa11x0.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *  arch/arm/include/asm/mach/irda.h
- *
- *  Copyright (C) 2004 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARM_MACH_IRDA_H
-#define __ASM_ARM_MACH_IRDA_H
-
-struct irda_platform_data {
-	int (*startup)(struct device *);
-	void (*shutdown)(struct device *);
-	int (*set_power)(struct device *, unsigned int state);
-	void (*set_speed)(struct device *, unsigned int speed);
-};
-
-#endif
-- 
2.1.0

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

* Re: [PATCH 0/6] SA11x0 serial updates
  2016-08-29 11:25       ` Russell King - ARM Linux
@ 2016-08-29 12:05         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 12:05 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

This series converts SA11x0 serial to make use of the mctrl helpers
where appropriate.  This allows us to remove several board-specific
callbacks.

As serial is critical for console output, we report but otherwise
ignore any error except probe deferral from mctrl initialisation.

Obviously, as this is part of a larger series (and has dependencies
on the previous series) this can not be applied to individual
subsystem maintainer trees.  Please ack.

 arch/arm/mach-sa1100/assabet.c  |  91 +++++++++++----------------------
 arch/arm/mach-sa1100/badge4.c   |   2 -
 arch/arm/mach-sa1100/h3xxx.c    |  64 ++++-------------------
 arch/arm/mach-sa1100/hackkit.c  |  48 ------------------
 arch/arm/mach-sa1100/neponset.c | 109 +++++++++++-----------------------------
 drivers/tty/serial/Kconfig      |   1 +
 drivers/tty/serial/sa1100.c     |  42 ++++++++++++++--
 7 files changed, 106 insertions(+), 251 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 0/6] SA11x0 serial updates
@ 2016-08-29 12:05         ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 12:05 UTC (permalink / raw)
  To: linux-arm-kernel

This series converts SA11x0 serial to make use of the mctrl helpers
where appropriate.  This allows us to remove several board-specific
callbacks.

As serial is critical for console output, we report but otherwise
ignore any error except probe deferral from mctrl initialisation.

Obviously, as this is part of a larger series (and has dependencies
on the previous series) this can not be applied to individual
subsystem maintainer trees.  Please ack.

 arch/arm/mach-sa1100/assabet.c  |  91 +++++++++++----------------------
 arch/arm/mach-sa1100/badge4.c   |   2 -
 arch/arm/mach-sa1100/h3xxx.c    |  64 ++++-------------------
 arch/arm/mach-sa1100/hackkit.c  |  48 ------------------
 arch/arm/mach-sa1100/neponset.c | 109 +++++++++++-----------------------------
 drivers/tty/serial/Kconfig      |   1 +
 drivers/tty/serial/sa1100.c     |  42 ++++++++++++++--
 7 files changed, 106 insertions(+), 251 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 1/6] serial: sa1100: add support for mctrl gpios
  2016-08-29 12:05         ` Russell King - ARM Linux
@ 2016-08-29 12:05           ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:05 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

Add support for the generic mctrl gpio helper.  This will allow us to
convert several board files to use the gpiod tables to assign GPIOs to
serial ports, rather than needing to have private function callbacks.

If the generic mctrl gpio helper fails, ignore the mctrl gpios rather
than preventing the (possibly console) serial port from being created.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/tty/serial/Kconfig  |  1 +
 drivers/tty/serial/sa1100.c | 42 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 518db24a5b36..528d2ea3c7e7 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -464,6 +464,7 @@ config SERIAL_SA1100
 	bool "SA1100 serial port support"
 	depends on ARCH_SA1100
 	select SERIAL_CORE
+	select SERIAL_MCTRL_GPIO if GPIOLIB
 	help
 	  If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
 	  can enable its onboard serial port by enabling this option.
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c
index fd3d1329d48c..ce1f9a3fb36d 100644
--- a/drivers/tty/serial/sa1100.c
+++ b/drivers/tty/serial/sa1100.c
@@ -41,6 +41,8 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+#include "serial_mctrl_gpio.h"
+
 /* We've been assigned a range on the "Low-density serial ports" major */
 #define SERIAL_SA1100_MAJOR	204
 #define MINOR_START		5
@@ -90,6 +92,7 @@ struct sa1100_port {
 	struct uart_port	port;
 	struct timer_list	timer;
 	unsigned int		old_status;
+	struct mctrl_gpios	*gpios;
 };
 
 /*
@@ -187,6 +190,8 @@ static void sa1100_enable_ms(struct uart_port *port)
 		container_of(port, struct sa1100_port, port);
 
 	mod_timer(&sport->timer, jiffies);
+
+	mctrl_gpio_enable_ms(sport->gpios);
 }
 
 static void
@@ -335,11 +340,21 @@ static unsigned int sa1100_tx_empty(struct uart_port *port)
 
 static unsigned int sa1100_get_mctrl(struct uart_port *port)
 {
-	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+	struct sa1100_port *sport =
+		container_of(port, struct sa1100_port, port);
+	int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+	mctrl_gpio_get(sport->gpios, &ret);
+
+	return ret;
 }
 
 static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
+	struct sa1100_port *sport =
+		container_of(port, struct sa1100_port, port);
+
+	mctrl_gpio_set(sport->gpios, mctrl);
 }
 
 /*
@@ -857,6 +872,27 @@ static int sa1100_serial_resume(struct platform_device *dev)
 	return 0;
 }
 
+static int sa1100_serial_add_one_port(struct sa1100_port *sport, struct platform_device *dev)
+{
+	sport->port.dev = &dev->dev;
+	sport->gpios = mctrl_gpio_init_noauto(sport->port.dev, 0);
+	if (IS_ERR(sport->gpios)) {
+		int err = PTR_ERR(sport->gpios);
+
+		dev_err(sport->port.dev, "failed to get mctrl gpios: %d\n",
+			err);
+
+		if (err == -EPROBE_DEFER)
+			return err;
+
+		sport->gpios = NULL;
+	}
+
+	platform_set_drvdata(dev, sport);
+
+	return uart_add_one_port(&sa1100_reg, &sport->port);
+}
+
 static int sa1100_serial_probe(struct platform_device *dev)
 {
 	struct resource *res = dev->resource;
@@ -871,9 +907,7 @@ static int sa1100_serial_probe(struct platform_device *dev)
 			if (sa1100_ports[i].port.mapbase != res->start)
 				continue;
 
-			sa1100_ports[i].port.dev = &dev->dev;
-			uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
-			platform_set_drvdata(dev, &sa1100_ports[i]);
+			sa1100_serial_add_one_port(&sa1100_ports[i], dev);
 			break;
 		}
 	}
-- 
2.1.0

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

* [PATCH 1/6] serial: sa1100: add support for mctrl gpios
@ 2016-08-29 12:05           ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:05 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for the generic mctrl gpio helper.  This will allow us to
convert several board files to use the gpiod tables to assign GPIOs to
serial ports, rather than needing to have private function callbacks.

If the generic mctrl gpio helper fails, ignore the mctrl gpios rather
than preventing the (possibly console) serial port from being created.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/tty/serial/Kconfig  |  1 +
 drivers/tty/serial/sa1100.c | 42 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 518db24a5b36..528d2ea3c7e7 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -464,6 +464,7 @@ config SERIAL_SA1100
 	bool "SA1100 serial port support"
 	depends on ARCH_SA1100
 	select SERIAL_CORE
+	select SERIAL_MCTRL_GPIO if GPIOLIB
 	help
 	  If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you
 	  can enable its onboard serial port by enabling this option.
diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c
index fd3d1329d48c..ce1f9a3fb36d 100644
--- a/drivers/tty/serial/sa1100.c
+++ b/drivers/tty/serial/sa1100.c
@@ -41,6 +41,8 @@
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 
+#include "serial_mctrl_gpio.h"
+
 /* We've been assigned a range on the "Low-density serial ports" major */
 #define SERIAL_SA1100_MAJOR	204
 #define MINOR_START		5
@@ -90,6 +92,7 @@ struct sa1100_port {
 	struct uart_port	port;
 	struct timer_list	timer;
 	unsigned int		old_status;
+	struct mctrl_gpios	*gpios;
 };
 
 /*
@@ -187,6 +190,8 @@ static void sa1100_enable_ms(struct uart_port *port)
 		container_of(port, struct sa1100_port, port);
 
 	mod_timer(&sport->timer, jiffies);
+
+	mctrl_gpio_enable_ms(sport->gpios);
 }
 
 static void
@@ -335,11 +340,21 @@ static unsigned int sa1100_tx_empty(struct uart_port *port)
 
 static unsigned int sa1100_get_mctrl(struct uart_port *port)
 {
-	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+	struct sa1100_port *sport =
+		container_of(port, struct sa1100_port, port);
+	int ret = TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+	mctrl_gpio_get(sport->gpios, &ret);
+
+	return ret;
 }
 
 static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
+	struct sa1100_port *sport =
+		container_of(port, struct sa1100_port, port);
+
+	mctrl_gpio_set(sport->gpios, mctrl);
 }
 
 /*
@@ -857,6 +872,27 @@ static int sa1100_serial_resume(struct platform_device *dev)
 	return 0;
 }
 
+static int sa1100_serial_add_one_port(struct sa1100_port *sport, struct platform_device *dev)
+{
+	sport->port.dev = &dev->dev;
+	sport->gpios = mctrl_gpio_init_noauto(sport->port.dev, 0);
+	if (IS_ERR(sport->gpios)) {
+		int err = PTR_ERR(sport->gpios);
+
+		dev_err(sport->port.dev, "failed to get mctrl gpios: %d\n",
+			err);
+
+		if (err == -EPROBE_DEFER)
+			return err;
+
+		sport->gpios = NULL;
+	}
+
+	platform_set_drvdata(dev, sport);
+
+	return uart_add_one_port(&sa1100_reg, &sport->port);
+}
+
 static int sa1100_serial_probe(struct platform_device *dev)
 {
 	struct resource *res = dev->resource;
@@ -871,9 +907,7 @@ static int sa1100_serial_probe(struct platform_device *dev)
 			if (sa1100_ports[i].port.mapbase != res->start)
 				continue;
 
-			sa1100_ports[i].port.dev = &dev->dev;
-			uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
-			platform_set_drvdata(dev, &sa1100_ports[i]);
+			sa1100_serial_add_one_port(&sa1100_ports[i], dev);
 			break;
 		}
 	}
-- 
2.1.0

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

* [PATCH 2/6] ARM: sa1100/assabet: convert serial to gpiod APIs
  2016-08-29 12:05         ` Russell King - ARM Linux
@ 2016-08-29 12:05           ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:05 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

Convert the Assabet serial modem control signals to use the gpiod APIs
rather than custom callbacks into platform code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c | 91 +++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 63 deletions(-)

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 14a75735e9d0..a841f6845701 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -515,6 +515,29 @@ static const struct gpio_keys_platform_data assabet_keys_pdata = {
 	.rep = 0,
 };
 
+static struct gpiod_lookup_table assabet_uart1_gpio_table = {
+	.dev_id = "sa11x0-uart.1",
+	.table = {
+		GPIO_LOOKUP("assabet", 16, "dtr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 17, "rts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 25, "dcd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 26, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 27, "dsr", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table assabet_uart3_gpio_table = {
+	.dev_id = "sa11x0-uart.3",
+	.table = {
+		GPIO_LOOKUP("assabet", 28, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 29, "dsr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 30, "dcd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 31, "rng", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init assabet_init(void)
 {
 	gpiod_add_lookup_table(&assabet_irda_gpio_table);
@@ -568,6 +591,9 @@ static void __init assabet_init(void)
 						  &assabet_keys_pdata,
 						  sizeof(assabet_keys_pdata));
 
+		gpiod_add_lookup_table(&assabet_uart1_gpio_table);
+		gpiod_add_lookup_table(&assabet_uart3_gpio_table);
+
 		assabet_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
 					 assabet_cf_vcc_consumers,
 					 ARRAY_SIZE(assabet_cf_vcc_consumers));
@@ -650,74 +676,13 @@ static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		if (state)
-			ASSABET_BCR_clear(ASSABET_BCR_RS232EN |
-					  ASSABET_BCR_COM_RTS |
-					  ASSABET_BCR_COM_DTR);
-		else
-			ASSABET_BCR_set(ASSABET_BCR_RS232EN |
-					ASSABET_BCR_COM_RTS |
-					ASSABET_BCR_COM_DTR);
-	}
-}
-
-/*
- * Assabet uses COM_RTS and COM_DTR for both UART1 (com port)
- * and UART3 (radio module).  We only handle them for UART1 here.
- */
-static void assabet_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	if (port->mapbase == _Ser1UTCR0) {
-		u_int set = 0, clear = 0;
-
-		if (mctrl & TIOCM_RTS)
-			clear |= ASSABET_BCR_COM_RTS;
+			ASSABET_BCR_clear(ASSABET_BCR_RS232EN);
 		else
-			set |= ASSABET_BCR_COM_RTS;
-
-		if (mctrl & TIOCM_DTR)
-			clear |= ASSABET_BCR_COM_DTR;
-		else
-			set |= ASSABET_BCR_COM_DTR;
-
-		ASSABET_BCR_clear(clear);
-		ASSABET_BCR_set(set);
-	}
-}
-
-static u_int assabet_get_mctrl(struct uart_port *port)
-{
-	u_int ret = 0;
-	u_int bsr = ASSABET_BSR;
-
-	/* need 2 reads to read current value */
-	bsr = ASSABET_BSR;
-
-	if (port->mapbase == _Ser1UTCR0) {
-		if (bsr & ASSABET_BSR_COM_DCD)
-			ret |= TIOCM_CD;
-		if (bsr & ASSABET_BSR_COM_CTS)
-			ret |= TIOCM_CTS;
-		if (bsr & ASSABET_BSR_COM_DSR)
-			ret |= TIOCM_DSR;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		if (bsr & ASSABET_BSR_RAD_DCD)
-			ret |= TIOCM_CD;
-		if (bsr & ASSABET_BSR_RAD_CTS)
-			ret |= TIOCM_CTS;
-		if (bsr & ASSABET_BSR_RAD_DSR)
-			ret |= TIOCM_DSR;
-		if (bsr & ASSABET_BSR_RAD_RI)
-			ret |= TIOCM_RI;
-	} else {
-		ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+			ASSABET_BCR_set(ASSABET_BCR_RS232EN);
 	}
-
-	return ret;
 }
 
 static struct sa1100_port_fns assabet_port_fns __initdata = {
-	.set_mctrl	= assabet_set_mctrl,
-	.get_mctrl	= assabet_get_mctrl,
 	.pm		= assabet_uart_pm,
 };
 
-- 
2.1.0

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

* [PATCH 2/6] ARM: sa1100/assabet: convert serial to gpiod APIs
@ 2016-08-29 12:05           ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:05 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the Assabet serial modem control signals to use the gpiod APIs
rather than custom callbacks into platform code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/assabet.c | 91 +++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 63 deletions(-)

diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 14a75735e9d0..a841f6845701 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -515,6 +515,29 @@ static const struct gpio_keys_platform_data assabet_keys_pdata = {
 	.rep = 0,
 };
 
+static struct gpiod_lookup_table assabet_uart1_gpio_table = {
+	.dev_id = "sa11x0-uart.1",
+	.table = {
+		GPIO_LOOKUP("assabet", 16, "dtr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 17, "rts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 25, "dcd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 26, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 27, "dsr", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table assabet_uart3_gpio_table = {
+	.dev_id = "sa11x0-uart.3",
+	.table = {
+		GPIO_LOOKUP("assabet", 28, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 29, "dsr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 30, "dcd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("assabet", 31, "rng", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init assabet_init(void)
 {
 	gpiod_add_lookup_table(&assabet_irda_gpio_table);
@@ -568,6 +591,9 @@ static void __init assabet_init(void)
 						  &assabet_keys_pdata,
 						  sizeof(assabet_keys_pdata));
 
+		gpiod_add_lookup_table(&assabet_uart1_gpio_table);
+		gpiod_add_lookup_table(&assabet_uart3_gpio_table);
+
 		assabet_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
 					 assabet_cf_vcc_consumers,
 					 ARRAY_SIZE(assabet_cf_vcc_consumers));
@@ -650,74 +676,13 @@ static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		if (state)
-			ASSABET_BCR_clear(ASSABET_BCR_RS232EN |
-					  ASSABET_BCR_COM_RTS |
-					  ASSABET_BCR_COM_DTR);
-		else
-			ASSABET_BCR_set(ASSABET_BCR_RS232EN |
-					ASSABET_BCR_COM_RTS |
-					ASSABET_BCR_COM_DTR);
-	}
-}
-
-/*
- * Assabet uses COM_RTS and COM_DTR for both UART1 (com port)
- * and UART3 (radio module).  We only handle them for UART1 here.
- */
-static void assabet_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	if (port->mapbase == _Ser1UTCR0) {
-		u_int set = 0, clear = 0;
-
-		if (mctrl & TIOCM_RTS)
-			clear |= ASSABET_BCR_COM_RTS;
+			ASSABET_BCR_clear(ASSABET_BCR_RS232EN);
 		else
-			set |= ASSABET_BCR_COM_RTS;
-
-		if (mctrl & TIOCM_DTR)
-			clear |= ASSABET_BCR_COM_DTR;
-		else
-			set |= ASSABET_BCR_COM_DTR;
-
-		ASSABET_BCR_clear(clear);
-		ASSABET_BCR_set(set);
-	}
-}
-
-static u_int assabet_get_mctrl(struct uart_port *port)
-{
-	u_int ret = 0;
-	u_int bsr = ASSABET_BSR;
-
-	/* need 2 reads to read current value */
-	bsr = ASSABET_BSR;
-
-	if (port->mapbase == _Ser1UTCR0) {
-		if (bsr & ASSABET_BSR_COM_DCD)
-			ret |= TIOCM_CD;
-		if (bsr & ASSABET_BSR_COM_CTS)
-			ret |= TIOCM_CTS;
-		if (bsr & ASSABET_BSR_COM_DSR)
-			ret |= TIOCM_DSR;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		if (bsr & ASSABET_BSR_RAD_DCD)
-			ret |= TIOCM_CD;
-		if (bsr & ASSABET_BSR_RAD_CTS)
-			ret |= TIOCM_CTS;
-		if (bsr & ASSABET_BSR_RAD_DSR)
-			ret |= TIOCM_DSR;
-		if (bsr & ASSABET_BSR_RAD_RI)
-			ret |= TIOCM_RI;
-	} else {
-		ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+			ASSABET_BCR_set(ASSABET_BCR_RS232EN);
 	}
-
-	return ret;
 }
 
 static struct sa1100_port_fns assabet_port_fns __initdata = {
-	.set_mctrl	= assabet_set_mctrl,
-	.get_mctrl	= assabet_get_mctrl,
 	.pm		= assabet_uart_pm,
 };
 
-- 
2.1.0

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

* [PATCH 3/6] ARM: sa1100/h3xxx: convert serial to gpiod APIs
  2016-08-29 12:05         ` Russell King - ARM Linux
@ 2016-08-29 12:06           ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

Convert the iPAQ H3xxx serial modem control signals to use the gpiod
APIs rather than custom callbacks into platform code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/h3xxx.c | 64 ++++++++------------------------------------
 1 file changed, 11 insertions(+), 53 deletions(-)

diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index 31035ab3c095..d127cc190fb3 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -87,57 +87,6 @@ static struct resource h3xxx_flash_resource =
 /*
  * H3xxx uart support
  */
-static struct gpio h3xxx_uart_gpio[] = {
-	{ H3XXX_GPIO_COM_DCD,	GPIOF_IN,		"COM DCD" },
-	{ H3XXX_GPIO_COM_CTS,	GPIOF_IN,		"COM CTS" },
-	{ H3XXX_GPIO_COM_RTS,	GPIOF_OUT_INIT_LOW,	"COM RTS" },
-};
-
-static bool h3xxx_uart_request_gpios(void)
-{
-	static bool h3xxx_uart_gpio_ok;
-	int rc;
-
-	if (h3xxx_uart_gpio_ok)
-		return true;
-
-	rc = gpio_request_array(h3xxx_uart_gpio, ARRAY_SIZE(h3xxx_uart_gpio));
-	if (rc)
-		pr_err("h3xxx_uart_request_gpios: error %d\n", rc);
-	else
-		h3xxx_uart_gpio_ok = true;
-
-	return h3xxx_uart_gpio_ok;
-}
-
-static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	if (port->mapbase == _Ser3UTCR0) {
-		if (!h3xxx_uart_request_gpios())
-			return;
-		gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
-	}
-}
-
-static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
-{
-	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-	if (port->mapbase == _Ser3UTCR0) {
-		if (!h3xxx_uart_request_gpios())
-			return ret;
-		/*
-		 * DCD and CTS bits are inverted in GPLR by RS232 transceiver
-		 */
-		if (gpio_get_value(H3XXX_GPIO_COM_DCD))
-			ret &= ~TIOCM_CD;
-		if (gpio_get_value(H3XXX_GPIO_COM_CTS))
-			ret &= ~TIOCM_CTS;
-	}
-
-	return ret;
-}
-
 static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
 	if (port->mapbase == _Ser3UTCR0) {
@@ -170,12 +119,20 @@ static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
 }
 
 static struct sa1100_port_fns h3xxx_port_fns __initdata = {
-	.set_mctrl	= h3xxx_uart_set_mctrl,
-	.get_mctrl	= h3xxx_uart_get_mctrl,
 	.pm		= h3xxx_uart_pm,
 	.set_wake	= h3xxx_uart_set_wake,
 };
 
+static struct gpiod_lookup_table h3xxx_uart3_gpio_table = {
+	.dev_id = "sa11x0-uart.3",
+	.table = {
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_DCD, "dcd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_CTS, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_RTS, "rts", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /*
  * EGPIO
  */
@@ -283,6 +240,7 @@ static struct gpiod_lookup_table h3xxx_pcmcia_gpio_table = {
 void __init h3xxx_mach_init(void)
 {
 	gpiod_add_lookup_table(&h3xxx_pcmcia_gpio_table);
+	gpiod_add_lookup_table(&h3xxx_uart3_gpio_table);
 	sa1100_register_uart_fns(&h3xxx_port_fns);
 	sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
 	platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
-- 
2.1.0

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

* [PATCH 3/6] ARM: sa1100/h3xxx: convert serial to gpiod APIs
@ 2016-08-29 12:06           ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the iPAQ H3xxx serial modem control signals to use the gpiod
APIs rather than custom callbacks into platform code.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/h3xxx.c | 64 ++++++++------------------------------------
 1 file changed, 11 insertions(+), 53 deletions(-)

diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index 31035ab3c095..d127cc190fb3 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -87,57 +87,6 @@ static struct resource h3xxx_flash_resource =
 /*
  * H3xxx uart support
  */
-static struct gpio h3xxx_uart_gpio[] = {
-	{ H3XXX_GPIO_COM_DCD,	GPIOF_IN,		"COM DCD" },
-	{ H3XXX_GPIO_COM_CTS,	GPIOF_IN,		"COM CTS" },
-	{ H3XXX_GPIO_COM_RTS,	GPIOF_OUT_INIT_LOW,	"COM RTS" },
-};
-
-static bool h3xxx_uart_request_gpios(void)
-{
-	static bool h3xxx_uart_gpio_ok;
-	int rc;
-
-	if (h3xxx_uart_gpio_ok)
-		return true;
-
-	rc = gpio_request_array(h3xxx_uart_gpio, ARRAY_SIZE(h3xxx_uart_gpio));
-	if (rc)
-		pr_err("h3xxx_uart_request_gpios: error %d\n", rc);
-	else
-		h3xxx_uart_gpio_ok = true;
-
-	return h3xxx_uart_gpio_ok;
-}
-
-static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	if (port->mapbase == _Ser3UTCR0) {
-		if (!h3xxx_uart_request_gpios())
-			return;
-		gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
-	}
-}
-
-static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
-{
-	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-	if (port->mapbase == _Ser3UTCR0) {
-		if (!h3xxx_uart_request_gpios())
-			return ret;
-		/*
-		 * DCD and CTS bits are inverted in GPLR by RS232 transceiver
-		 */
-		if (gpio_get_value(H3XXX_GPIO_COM_DCD))
-			ret &= ~TIOCM_CD;
-		if (gpio_get_value(H3XXX_GPIO_COM_CTS))
-			ret &= ~TIOCM_CTS;
-	}
-
-	return ret;
-}
-
 static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
 	if (port->mapbase == _Ser3UTCR0) {
@@ -170,12 +119,20 @@ static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
 }
 
 static struct sa1100_port_fns h3xxx_port_fns __initdata = {
-	.set_mctrl	= h3xxx_uart_set_mctrl,
-	.get_mctrl	= h3xxx_uart_get_mctrl,
 	.pm		= h3xxx_uart_pm,
 	.set_wake	= h3xxx_uart_set_wake,
 };
 
+static struct gpiod_lookup_table h3xxx_uart3_gpio_table = {
+	.dev_id = "sa11x0-uart.3",
+	.table = {
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_DCD, "dcd", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_CTS, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_RTS, "rts", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /*
  * EGPIO
  */
@@ -283,6 +240,7 @@ static struct gpiod_lookup_table h3xxx_pcmcia_gpio_table = {
 void __init h3xxx_mach_init(void)
 {
 	gpiod_add_lookup_table(&h3xxx_pcmcia_gpio_table);
+	gpiod_add_lookup_table(&h3xxx_uart3_gpio_table);
 	sa1100_register_uart_fns(&h3xxx_port_fns);
 	sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
 	platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
-- 
2.1.0

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

* [PATCH 4/6] ARM: sa1100/badge4: remove commented out modem control initialisers
  2016-08-29 12:05         ` Russell King - ARM Linux
@ 2016-08-29 12:06           ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

Remove the commented out modem control initialisers.  These are doing
nothing useful.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/badge4.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 63361b6d04e9..17d28b4dab5e 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -315,8 +315,6 @@ badge4_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 }
 
 static struct sa1100_port_fns badge4_port_fns __initdata = {
-	//.get_mctrl	= badge4_get_mctrl,
-	//.set_mctrl	= badge4_set_mctrl,
 	.pm		= badge4_uart_pm,
 };
 
-- 
2.1.0

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

* [PATCH 4/6] ARM: sa1100/badge4: remove commented out modem control initialisers
@ 2016-08-29 12:06           ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the commented out modem control initialisers.  These are doing
nothing useful.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/badge4.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 63361b6d04e9..17d28b4dab5e 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -315,8 +315,6 @@ badge4_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 }
 
 static struct sa1100_port_fns badge4_port_fns __initdata = {
-	//.get_mctrl	= badge4_get_mctrl,
-	//.set_mctrl	= badge4_set_mctrl,
 	.pm		= badge4_uart_pm,
 };
 
-- 
2.1.0

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

* [PATCH 5/6] ARM: sa1100/hackkit: remove empty serial mctrl functions
  2016-08-29 12:05         ` Russell King - ARM Linux
@ 2016-08-29 12:06           ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

Remove the empty serial modem control signal functions from hackkit
as these are unnecessary - the core code can copes fine without
these.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/hackkit.c | 48 ------------------------------------------
 1 file changed, 48 deletions(-)

diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 643d5f2d9af9..9faf602666cf 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -49,8 +49,6 @@
 /* init funcs */
 static void __init hackkit_map_io(void);
 
-static u_int hackkit_get_mctrl(struct uart_port *port);
-static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
 static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
 
 /**********************************************************************
@@ -71,8 +69,6 @@ static struct map_desc hackkit_io_desc[] __initdata = {
 };
 
 static struct sa1100_port_fns hackkit_port_fns __initdata = {
-	.set_mctrl	= hackkit_set_mctrl,
-	.get_mctrl	= hackkit_get_mctrl,
 	.pm		= hackkit_uart_pm,
 };
 
@@ -105,50 +101,6 @@ static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 	/* TODO: switch on/off uart in powersave mode */
 }
 
-/*
- * Note! this can be called from IRQ context.
- * FIXME: No modem ctrl lines yet.
- */
-static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-#if 0
-	if (port->mapbase == _Ser1UTCR0) {
-		u_int set = 0, clear = 0;
-
-		if (mctrl & TIOCM_RTS)
-			set |= PT_CTRL2_RS1_RTS;
-		else
-			clear |= PT_CTRL2_RS1_RTS;
-
-		if (mctrl & TIOCM_DTR)
-			set |= PT_CTRL2_RS1_DTR;
-		else
-			clear |= PT_CTRL2_RS1_DTR;
-
-		PTCTRL2_clear(clear);
-		PTCTRL2_set(set);
-	}
-#endif
-}
-
-static u_int hackkit_get_mctrl(struct uart_port *port)
-{
-	u_int ret = 0;
-#if 0
-	u_int irqsr = PT_IRQSR;
-
-	/* need 2 reads to read current value */
-	irqsr = PT_IRQSR;
-
-	/* TODO: check IRQ source register for modem/com
-	 status lines and set them correctly. */
-#endif
-
-	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-	return ret;
-}
-
 static struct mtd_partition hackkit_partitions[] = {
 	{
 		.name		= "BLOB",
-- 
2.1.0

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

* [PATCH 5/6] ARM: sa1100/hackkit: remove empty serial mctrl functions
@ 2016-08-29 12:06           ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the empty serial modem control signal functions from hackkit
as these are unnecessary - the core code can copes fine without
these.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/hackkit.c | 48 ------------------------------------------
 1 file changed, 48 deletions(-)

diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 643d5f2d9af9..9faf602666cf 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -49,8 +49,6 @@
 /* init funcs */
 static void __init hackkit_map_io(void);
 
-static u_int hackkit_get_mctrl(struct uart_port *port);
-static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
 static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
 
 /**********************************************************************
@@ -71,8 +69,6 @@ static struct map_desc hackkit_io_desc[] __initdata = {
 };
 
 static struct sa1100_port_fns hackkit_port_fns __initdata = {
-	.set_mctrl	= hackkit_set_mctrl,
-	.get_mctrl	= hackkit_get_mctrl,
 	.pm		= hackkit_uart_pm,
 };
 
@@ -105,50 +101,6 @@ static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 	/* TODO: switch on/off uart in powersave mode */
 }
 
-/*
- * Note! this can be called from IRQ context.
- * FIXME: No modem ctrl lines yet.
- */
-static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-#if 0
-	if (port->mapbase == _Ser1UTCR0) {
-		u_int set = 0, clear = 0;
-
-		if (mctrl & TIOCM_RTS)
-			set |= PT_CTRL2_RS1_RTS;
-		else
-			clear |= PT_CTRL2_RS1_RTS;
-
-		if (mctrl & TIOCM_DTR)
-			set |= PT_CTRL2_RS1_DTR;
-		else
-			clear |= PT_CTRL2_RS1_DTR;
-
-		PTCTRL2_clear(clear);
-		PTCTRL2_set(set);
-	}
-#endif
-}
-
-static u_int hackkit_get_mctrl(struct uart_port *port)
-{
-	u_int ret = 0;
-#if 0
-	u_int irqsr = PT_IRQSR;
-
-	/* need 2 reads to read current value */
-	irqsr = PT_IRQSR;
-
-	/* TODO: check IRQ source register for modem/com
-	 status lines and set them correctly. */
-#endif
-
-	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-
-	return ret;
-}
-
 static struct mtd_partition hackkit_partitions[] = {
 	{
 		.name		= "BLOB",
-- 
2.1.0

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

* [PATCH 6/6] ARM: sa1100/neponset: convert serial to use gpiod APIs
  2016-08-29 12:05         ` Russell King - ARM Linux
@ 2016-08-29 12:06           ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel, linux-serial; +Cc: Greg Kroah-Hartman, Jiri Slaby

Convert the serial modem control signals to use the gpiod APIs rather
than the private platform callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 109 +++++++++++-----------------------------
 1 file changed, 28 insertions(+), 81 deletions(-)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 790d8da233da..bff6efdfaeaf 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -10,7 +10,6 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/serial_core.h>
@@ -48,23 +47,8 @@
 #define IRR_SA1111	(1 << 2)
 
 #define NCR_NGPIO	7
-
-#define MDM_CTL0_RTS1	(1 << 0)
-#define MDM_CTL0_DTR1	(1 << 1)
-#define MDM_CTL0_RTS2	(1 << 2)
-#define MDM_CTL0_DTR2	(1 << 3)
 #define MDM_CTL0_NGPIO	4
-
-#define MDM_CTL1_CTS1	(1 << 0)
-#define MDM_CTL1_DSR1	(1 << 1)
-#define MDM_CTL1_DCD1	(1 << 2)
-#define MDM_CTL1_CTS2	(1 << 3)
-#define MDM_CTL1_DSR2	(1 << 4)
-#define MDM_CTL1_DCD2	(1 << 5)
 #define MDM_CTL1_NGPIO	6
-
-#define AUD_SEL_1341	(1 << 0)
-#define AUD_MUTE_1341	(1 << 1)
 #define AUD_NGPIO	2
 
 extern void sa1110_mb_disable(void);
@@ -96,6 +80,30 @@ struct neponset_drvdata {
 	struct gpio_chip *gpio[4];
 };
 
+static struct gpiod_lookup_table neponset_uart1_gpio_table = {
+	.dev_id = "sa11x0-uart.1",
+	.table = {
+		GPIO_LOOKUP("neponset-mdm-ctl0", 2, "rts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl0", 3, "dtr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 3, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 4, "dsr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 5, "dcd", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table neponset_uart3_gpio_table = {
+	.dev_id = "sa11x0-uart.3",
+	.table = {
+		GPIO_LOOKUP("neponset-mdm-ctl0", 0, "rts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl0", 1, "dtr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 0, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 1, "dsr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 2, "dcd", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct gpiod_lookup_table neponset_pcmcia_table = {
 	.dev_id = "1800",
 	.table = {
@@ -123,69 +131,6 @@ void neponset_ncr_frob(unsigned int mask, unsigned int val)
 }
 EXPORT_SYMBOL(neponset_ncr_frob);
 
-static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	struct neponset_drvdata *n = nep;
-	unsigned long mask, val = 0;
-
-	if (!n)
-		return;
-
-	if (port->mapbase == _Ser1UTCR0) {
-		mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2;
-
-		if (!(mctrl & TIOCM_RTS))
-			val |= MDM_CTL0_RTS2;
-
-		if (!(mctrl & TIOCM_DTR))
-			val |= MDM_CTL0_DTR2;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1;
-
-		if (!(mctrl & TIOCM_RTS))
-			val |= MDM_CTL0_RTS1;
-
-		if (!(mctrl & TIOCM_DTR))
-			val |= MDM_CTL0_DTR1;
-	}
-
-	n->gpio[1]->set_multiple(n->gpio[1], &mask, &val);
-}
-
-static u_int neponset_get_mctrl(struct uart_port *port)
-{
-	void __iomem *base = nep->base;
-	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-	u_int mdm_ctl1;
-
-	if (!base)
-		return ret;
-
-	mdm_ctl1 = readb_relaxed(base + MDM_CTL_1);
-	if (port->mapbase == _Ser1UTCR0) {
-		if (mdm_ctl1 & MDM_CTL1_DCD2)
-			ret &= ~TIOCM_CD;
-		if (mdm_ctl1 & MDM_CTL1_CTS2)
-			ret &= ~TIOCM_CTS;
-		if (mdm_ctl1 & MDM_CTL1_DSR2)
-			ret &= ~TIOCM_DSR;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		if (mdm_ctl1 & MDM_CTL1_DCD1)
-			ret &= ~TIOCM_CD;
-		if (mdm_ctl1 & MDM_CTL1_CTS1)
-			ret &= ~TIOCM_CTS;
-		if (mdm_ctl1 & MDM_CTL1_DSR1)
-			ret &= ~TIOCM_DSR;
-	}
-
-	return ret;
-}
-
-static struct sa1100_port_fns neponset_port_fns = {
-	.set_mctrl	= neponset_set_mctrl,
-	.get_mctrl	= neponset_get_mctrl,
-};
-
 /*
  * Install handler for Neponset IRQ.  Note that we have to loop here
  * since the ETHERNET and USAR IRQs are level based, and we need to
@@ -384,6 +329,8 @@ static int neponset_probe(struct platform_device *dev)
 			   d->base + AUD_CTL, AUD_NGPIO, false,
 			   neponset_aud_names);
 
+	gpiod_add_lookup_table(&neponset_uart1_gpio_table);
+	gpiod_add_lookup_table(&neponset_uart3_gpio_table);
 	gpiod_add_lookup_table(&neponset_pcmcia_table);
 
 	/*
@@ -398,8 +345,6 @@ static int neponset_probe(struct platform_device *dev)
 		 d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
 	nep = d;
 
-	sa1100_register_uart_fns(&neponset_port_fns);
-
 	/* Ensure that the memory bus request/grant signals are setup */
 	sa1110_mb_disable();
 
@@ -441,6 +386,8 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->smc91x);
 
 	gpiod_remove_lookup_table(&neponset_pcmcia_table);
+	gpiod_remove_lookup_table(&neponset_uart3_gpio_table);
+	gpiod_remove_lookup_table(&neponset_uart1_gpio_table);
 
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
-- 
2.1.0

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

* [PATCH 6/6] ARM: sa1100/neponset: convert serial to use gpiod APIs
@ 2016-08-29 12:06           ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-29 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the serial modem control signals to use the gpiod APIs rather
than the private platform callbacks.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 109 +++++++++++-----------------------------
 1 file changed, 28 insertions(+), 81 deletions(-)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 790d8da233da..bff6efdfaeaf 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -10,7 +10,6 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/serial_core.h>
@@ -48,23 +47,8 @@
 #define IRR_SA1111	(1 << 2)
 
 #define NCR_NGPIO	7
-
-#define MDM_CTL0_RTS1	(1 << 0)
-#define MDM_CTL0_DTR1	(1 << 1)
-#define MDM_CTL0_RTS2	(1 << 2)
-#define MDM_CTL0_DTR2	(1 << 3)
 #define MDM_CTL0_NGPIO	4
-
-#define MDM_CTL1_CTS1	(1 << 0)
-#define MDM_CTL1_DSR1	(1 << 1)
-#define MDM_CTL1_DCD1	(1 << 2)
-#define MDM_CTL1_CTS2	(1 << 3)
-#define MDM_CTL1_DSR2	(1 << 4)
-#define MDM_CTL1_DCD2	(1 << 5)
 #define MDM_CTL1_NGPIO	6
-
-#define AUD_SEL_1341	(1 << 0)
-#define AUD_MUTE_1341	(1 << 1)
 #define AUD_NGPIO	2
 
 extern void sa1110_mb_disable(void);
@@ -96,6 +80,30 @@ struct neponset_drvdata {
 	struct gpio_chip *gpio[4];
 };
 
+static struct gpiod_lookup_table neponset_uart1_gpio_table = {
+	.dev_id = "sa11x0-uart.1",
+	.table = {
+		GPIO_LOOKUP("neponset-mdm-ctl0", 2, "rts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl0", 3, "dtr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 3, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 4, "dsr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 5, "dcd", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table neponset_uart3_gpio_table = {
+	.dev_id = "sa11x0-uart.3",
+	.table = {
+		GPIO_LOOKUP("neponset-mdm-ctl0", 0, "rts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl0", 1, "dtr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 0, "cts", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 1, "dsr", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("neponset-mdm-ctl1", 2, "dcd", GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct gpiod_lookup_table neponset_pcmcia_table = {
 	.dev_id = "1800",
 	.table = {
@@ -123,69 +131,6 @@ void neponset_ncr_frob(unsigned int mask, unsigned int val)
 }
 EXPORT_SYMBOL(neponset_ncr_frob);
 
-static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
-{
-	struct neponset_drvdata *n = nep;
-	unsigned long mask, val = 0;
-
-	if (!n)
-		return;
-
-	if (port->mapbase == _Ser1UTCR0) {
-		mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2;
-
-		if (!(mctrl & TIOCM_RTS))
-			val |= MDM_CTL0_RTS2;
-
-		if (!(mctrl & TIOCM_DTR))
-			val |= MDM_CTL0_DTR2;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1;
-
-		if (!(mctrl & TIOCM_RTS))
-			val |= MDM_CTL0_RTS1;
-
-		if (!(mctrl & TIOCM_DTR))
-			val |= MDM_CTL0_DTR1;
-	}
-
-	n->gpio[1]->set_multiple(n->gpio[1], &mask, &val);
-}
-
-static u_int neponset_get_mctrl(struct uart_port *port)
-{
-	void __iomem *base = nep->base;
-	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-	u_int mdm_ctl1;
-
-	if (!base)
-		return ret;
-
-	mdm_ctl1 = readb_relaxed(base + MDM_CTL_1);
-	if (port->mapbase == _Ser1UTCR0) {
-		if (mdm_ctl1 & MDM_CTL1_DCD2)
-			ret &= ~TIOCM_CD;
-		if (mdm_ctl1 & MDM_CTL1_CTS2)
-			ret &= ~TIOCM_CTS;
-		if (mdm_ctl1 & MDM_CTL1_DSR2)
-			ret &= ~TIOCM_DSR;
-	} else if (port->mapbase == _Ser3UTCR0) {
-		if (mdm_ctl1 & MDM_CTL1_DCD1)
-			ret &= ~TIOCM_CD;
-		if (mdm_ctl1 & MDM_CTL1_CTS1)
-			ret &= ~TIOCM_CTS;
-		if (mdm_ctl1 & MDM_CTL1_DSR1)
-			ret &= ~TIOCM_DSR;
-	}
-
-	return ret;
-}
-
-static struct sa1100_port_fns neponset_port_fns = {
-	.set_mctrl	= neponset_set_mctrl,
-	.get_mctrl	= neponset_get_mctrl,
-};
-
 /*
  * Install handler for Neponset IRQ.  Note that we have to loop here
  * since the ETHERNET and USAR IRQs are level based, and we need to
@@ -384,6 +329,8 @@ static int neponset_probe(struct platform_device *dev)
 			   d->base + AUD_CTL, AUD_NGPIO, false,
 			   neponset_aud_names);
 
+	gpiod_add_lookup_table(&neponset_uart1_gpio_table);
+	gpiod_add_lookup_table(&neponset_uart3_gpio_table);
 	gpiod_add_lookup_table(&neponset_pcmcia_table);
 
 	/*
@@ -398,8 +345,6 @@ static int neponset_probe(struct platform_device *dev)
 		 d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
 	nep = d;
 
-	sa1100_register_uart_fns(&neponset_port_fns);
-
 	/* Ensure that the memory bus request/grant signals are setup */
 	sa1110_mb_disable();
 
@@ -441,6 +386,8 @@ static int neponset_remove(struct platform_device *dev)
 		platform_device_unregister(d->smc91x);
 
 	gpiod_remove_lookup_table(&neponset_pcmcia_table);
+	gpiod_remove_lookup_table(&neponset_uart3_gpio_table);
+	gpiod_remove_lookup_table(&neponset_uart1_gpio_table);
 
 	irq_set_chained_handler(irq, NULL);
 	irq_free_descs(d->irq_base, NEP_IRQ_NR);
-- 
2.1.0

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-29 10:24     ` Russell King
@ 2016-08-29 19:39       ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-29 19:39 UTC (permalink / raw)
  To: Russell King
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Linus Walleij

Hi Russell,

Russell King <rmk+kernel@armlinux.org.uk> writes:

> Add a simple, generic, single register fixed-direction GPIO driver.
> This is able to support a single register where a fixed number of
> bits are used for input and a fixed number of bits used for output.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpio/Kconfig     |   6 ++
>  drivers/gpio/Makefile    |   1 +
>  drivers/gpio/gpio-reg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/gpio-reg.h |  12 ++++
>  4 files changed, 158 insertions(+)
>  create mode 100644 drivers/gpio/gpio-reg.c
>  create mode 100644 include/linux/gpio-reg.h
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 98dd47a30fc7..49bd8b89712e 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -365,6 +365,12 @@ config GPIO_RCAR
>  	help
>  	  Say yes here to support GPIO on Renesas R-Car SoCs.
>  
> +config GPIO_REG
> +	bool
So I suppose it is on purpose you forbid it to be a module. Is there a way to
write either in the commit message or in the Kconfig this purpose, so that
nobody on "purpose" changes this bool to tristate ?

> +	help
> +	  A 32-bit single register GPIO fixed in/out implementation.  This
> +	  can be used to represent any register as a set of GPIO signals.
Another question I was asking myself was how it differenciated itself from
gpio-mmio, ie. what brought the need for this driver that isn't available with
gpio-mmio ?

I seem to understand that this is mainly for platform code, hence the "builtin
only" necessity, and if I'm right a part of your cover letter could very well
fit within this patch's commit message.

> diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
> new file mode 100644
> index 000000000000..fc7e0a395f9f
> --- /dev/null
> +++ b/drivers/gpio/gpio-reg.c

...zip...
> +static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
> +	unsigned long *bits)
> +{
> +	struct gpio_reg *r = to_gpio_reg(gc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&r->lock, flags);
> +	r->out = (r->out & ~*mask) | *bits;
Shouldn't this be :
	r->out = (r->out & ~*mask) | (*bits & *mask);

> diff --git a/include/linux/gpio-reg.h b/include/linux/gpio-reg.h
> new file mode 100644
> index 000000000000..0352bec7319a
> --- /dev/null
> +++ b/include/linux/gpio-reg.h
> @@ -0,0 +1,12 @@
> +#ifndef GPIO_REG_H
> +#define GPIO_REG_H
> +
> +struct device;
> +
> +struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
> +	int base, int num, const char *label, u32 direction, u32 def_out,
> +	const char *const *names);
Maybe this one would deserve a doxygen comment ?

Cheers.

-- 
Robert

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-29 19:39       ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-29 19:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Russell,

Russell King <rmk+kernel@armlinux.org.uk> writes:

> Add a simple, generic, single register fixed-direction GPIO driver.
> This is able to support a single register where a fixed number of
> bits are used for input and a fixed number of bits used for output.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/gpio/Kconfig     |   6 ++
>  drivers/gpio/Makefile    |   1 +
>  drivers/gpio/gpio-reg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/gpio-reg.h |  12 ++++
>  4 files changed, 158 insertions(+)
>  create mode 100644 drivers/gpio/gpio-reg.c
>  create mode 100644 include/linux/gpio-reg.h
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 98dd47a30fc7..49bd8b89712e 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -365,6 +365,12 @@ config GPIO_RCAR
>  	help
>  	  Say yes here to support GPIO on Renesas R-Car SoCs.
>  
> +config GPIO_REG
> +	bool
So I suppose it is on purpose you forbid it to be a module. Is there a way to
write either in the commit message or in the Kconfig this purpose, so that
nobody on "purpose" changes this bool to tristate ?

> +	help
> +	  A 32-bit single register GPIO fixed in/out implementation.  This
> +	  can be used to represent any register as a set of GPIO signals.
Another question I was asking myself was how it differenciated itself from
gpio-mmio, ie. what brought the need for this driver that isn't available with
gpio-mmio ?

I seem to understand that this is mainly for platform code, hence the "builtin
only" necessity, and if I'm right a part of your cover letter could very well
fit within this patch's commit message.

> diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
> new file mode 100644
> index 000000000000..fc7e0a395f9f
> --- /dev/null
> +++ b/drivers/gpio/gpio-reg.c

...zip...
> +static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
> +	unsigned long *bits)
> +{
> +	struct gpio_reg *r = to_gpio_reg(gc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&r->lock, flags);
> +	r->out = (r->out & ~*mask) | *bits;
Shouldn't this be :
	r->out = (r->out & ~*mask) | (*bits & *mask);

> diff --git a/include/linux/gpio-reg.h b/include/linux/gpio-reg.h
> new file mode 100644
> index 000000000000..0352bec7319a
> --- /dev/null
> +++ b/include/linux/gpio-reg.h
> @@ -0,0 +1,12 @@
> +#ifndef GPIO_REG_H
> +#define GPIO_REG_H
> +
> +struct device;
> +
> +struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
> +	int base, int num, const char *label, u32 direction, u32 def_out,
> +	const char *const *names);
Maybe this one would deserve a doxygen comment ?

Cheers.

-- 
Robert

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

* Re: [PATCH 06/33] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
  2016-08-29 10:24     ` Russell King
@ 2016-08-29 19:57       ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-29 19:57 UTC (permalink / raw)
  To: Russell King
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

Russell King <rmk+kernel@armlinux.org.uk> writes:

..zip...
> diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
> index 7245f3359564..e974d1eb0f88 100644
> --- a/arch/arm/mach-pxa/lubbock.c
> +++ b/arch/arm/mach-pxa/lubbock.c
...zip...

> @@ -110,20 +111,18 @@ static unsigned long lubbock_pin_config[] __initdata = {
>  };
>  
>  #define LUB_HEXLED		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
> -#define LUB_MISC_WR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
>  
>  void lubbock_set_hexled(uint32_t value)
>  {
>  	LUB_HEXLED = value;
>  }
>  
> +static struct gpio_chip *lubbock_misc_wr_gc;
> +
>  void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
>  {
> -	unsigned long flags;
> -
> -	local_irq_save(flags);
> -	LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
> -	local_irq_restore(flags);
> +	unsigned long m = mask, v = set;
> +	lubbock_misc_wr_gc->set_multiple(lubbock_misc_wr_gc, &m, &v);
If gpio_reg_init() failed (and I know, the probability of a lack of memory at
that stage of the kernel boot is ridiculous), this will end up as an NULL
pointer dereference if either IRDA or PCMCIA is used.

If it's expected, then the the pr_err() below would deserve a pr_crit(). I would
as well take an option on a "panic()" if lubbock_misc_wr_gc allocation fails. If
not, maybe a not-NULL test on lubbock_misc_wr_gc is in order, even if that would
be "hidding under the carpet" and rather difficult to debug later.

Apart this detail point, it's good for me.

Cheers.

-- 
Robert

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

* [PATCH 06/33] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
@ 2016-08-29 19:57       ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-29 19:57 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King <rmk+kernel@armlinux.org.uk> writes:

..zip...
> diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
> index 7245f3359564..e974d1eb0f88 100644
> --- a/arch/arm/mach-pxa/lubbock.c
> +++ b/arch/arm/mach-pxa/lubbock.c
...zip...

> @@ -110,20 +111,18 @@ static unsigned long lubbock_pin_config[] __initdata = {
>  };
>  
>  #define LUB_HEXLED		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
> -#define LUB_MISC_WR		__LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
>  
>  void lubbock_set_hexled(uint32_t value)
>  {
>  	LUB_HEXLED = value;
>  }
>  
> +static struct gpio_chip *lubbock_misc_wr_gc;
> +
>  void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
>  {
> -	unsigned long flags;
> -
> -	local_irq_save(flags);
> -	LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
> -	local_irq_restore(flags);
> +	unsigned long m = mask, v = set;
> +	lubbock_misc_wr_gc->set_multiple(lubbock_misc_wr_gc, &m, &v);
If gpio_reg_init() failed (and I know, the probability of a lack of memory at
that stage of the kernel boot is ridiculous), this will end up as an NULL
pointer dereference if either IRDA or PCMCIA is used.

If it's expected, then the the pr_err() below would deserve a pr_crit(). I would
as well take an option on a "panic()" if lubbock_misc_wr_gc allocation fails. If
not, maybe a not-NULL test on lubbock_misc_wr_gc is in order, even if that would
be "hidding under the carpet" and rather difficult to debug later.

Apart this detail point, it's good for me.

Cheers.

-- 
Robert

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

* Re: [PATCH 06/33] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
  2016-08-29 19:57       ` Robert Jarzmik
@ 2016-08-29 22:58         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 22:58 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Linus Walleij

On Mon, Aug 29, 2016 at 09:57:20PM +0200, Robert Jarzmik wrote:
> Russell King <rmk+kernel@armlinux.org.uk> writes:
> If gpio_reg_init() failed (and I know, the probability of a lack of memory at
> that stage of the kernel boot is ridiculous), this will end up as an NULL
> pointer dereference if either IRDA or PCMCIA is used.
> 
> If it's expected, then the the pr_err() below would deserve a pr_crit(). I would
> as well take an option on a "panic()" if lubbock_misc_wr_gc allocation fails. If
> not, maybe a not-NULL test on lubbock_misc_wr_gc is in order, even if that would
> be "hidding under the carpet" and rather difficult to debug later.
> 
> Apart this detail point, it's good for me.

I'd prefer to kill the function entirely.  The PCMCIA user of it goes
later in the series, and all that's left are the three users in lubbock.c,
those being IrDA and ads7846.  I'd like to see pxaficp go the same way
as sa1100_ir - converting to using gpiolib gpiod* APIs to manage the
FIR mode select GPIO itself internally.

That leaves ads7846_cs(), and I'd be surprised if SPI didn't already of
wiring GPIOs up as chip selects.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 06/33] ARM: pxa/lubbock: add GPIO driver for LUB_MISC_WR register
@ 2016-08-29 22:58         ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 22:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 09:57:20PM +0200, Robert Jarzmik wrote:
> Russell King <rmk+kernel@armlinux.org.uk> writes:
> If gpio_reg_init() failed (and I know, the probability of a lack of memory at
> that stage of the kernel boot is ridiculous), this will end up as an NULL
> pointer dereference if either IRDA or PCMCIA is used.
> 
> If it's expected, then the the pr_err() below would deserve a pr_crit(). I would
> as well take an option on a "panic()" if lubbock_misc_wr_gc allocation fails. If
> not, maybe a not-NULL test on lubbock_misc_wr_gc is in order, even if that would
> be "hidding under the carpet" and rather difficult to debug later.
> 
> Apart this detail point, it's good for me.

I'd prefer to kill the function entirely.  The PCMCIA user of it goes
later in the series, and all that's left are the three users in lubbock.c,
those being IrDA and ads7846.  I'd like to see pxaficp go the same way
as sa1100_ir - converting to using gpiolib gpiod* APIs to manage the
FIR mode select GPIO itself internally.

That leaves ads7846_cs(), and I'd be surprised if SPI didn't already of
wiring GPIOs up as chip selects.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-29 19:39       ` Robert Jarzmik
@ 2016-08-29 23:12         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 23:12 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Linus Walleij

On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> Hi Russell,
> 
> Russell King <rmk+kernel@armlinux.org.uk> writes:
> 
> > Add a simple, generic, single register fixed-direction GPIO driver.
> > This is able to support a single register where a fixed number of
> > bits are used for input and a fixed number of bits used for output.
> >
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> >  drivers/gpio/Kconfig     |   6 ++
> >  drivers/gpio/Makefile    |   1 +
> >  drivers/gpio/gpio-reg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/gpio-reg.h |  12 ++++
> >  4 files changed, 158 insertions(+)
> >  create mode 100644 drivers/gpio/gpio-reg.c
> >  create mode 100644 include/linux/gpio-reg.h
> >
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index 98dd47a30fc7..49bd8b89712e 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -365,6 +365,12 @@ config GPIO_RCAR
> >  	help
> >  	  Say yes here to support GPIO on Renesas R-Car SoCs.
> >  
> > +config GPIO_REG
> > +	bool
> So I suppose it is on purpose you forbid it to be a module. Is there a way to
> write either in the commit message or in the Kconfig this purpose, so that
> nobody on "purpose" changes this bool to tristate ?

The only forbidding is that it's used from code early at boot, so it has
to be available to the kernel for some of these platforms to function.
Even if it's changed to tristate, the select from these platforms would
force it to be built-in.

> > +	help
> > +	  A 32-bit single register GPIO fixed in/out implementation.  This
> > +	  can be used to represent any register as a set of GPIO signals.
> Another question I was asking myself was how it differenciated itself from
> gpio-mmio, ie. what brought the need for this driver that isn't available with
> gpio-mmio ?

gpio-mmio doesn't allow the fixed direction - it assumes that you always
have some form of direction register.  It also doesn't do the double-read
that's necessary for some platforms to get the "current" state of inputs.
It also doesn't do the "use 32-bit accessors even for smaller numbers of
GPIOs".  Lastly, it assumes that the current output state can be read
from the registers - this is not always the case (and is not the case for
Assabet.)

> I seem to understand that this is mainly for platform code, hence the
> "builtin only" necessity, and if I'm right a part of your cover letter
> could very well fit within this patch's commit message.

Apart from the missing MODULE_* tags and symbol exports, there's nothing
whic prohibits it becoming a module.

> > +static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
> > +	unsigned long *bits)
> > +{
> > +	struct gpio_reg *r = to_gpio_reg(gc);
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&r->lock, flags);
> > +	r->out = (r->out & ~*mask) | *bits;
> Shouldn't this be :
> 	r->out = (r->out & ~*mask) | (*bits & *mask);

Possibly, but the latter is redundant when used through gpiolib.

> > diff --git a/include/linux/gpio-reg.h b/include/linux/gpio-reg.h
> > new file mode 100644
> > index 000000000000..0352bec7319a
> > --- /dev/null
> > +++ b/include/linux/gpio-reg.h
> > @@ -0,0 +1,12 @@
> > +#ifndef GPIO_REG_H
> > +#define GPIO_REG_H
> > +
> > +struct device;
> > +
> > +struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
> > +	int base, int num, const char *label, u32 direction, u32 def_out,
> > +	const char *const *names);
> Maybe this one would deserve a doxygen comment ?

Maybe, but I've been told not to put such comments in header files.
I've already spent the last two weeks on this stuff (at the expense
of reading mail), I've not got around to thinking about any kind of
documentation.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-29 23:12         ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-29 23:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> Hi Russell,
> 
> Russell King <rmk+kernel@armlinux.org.uk> writes:
> 
> > Add a simple, generic, single register fixed-direction GPIO driver.
> > This is able to support a single register where a fixed number of
> > bits are used for input and a fixed number of bits used for output.
> >
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> >  drivers/gpio/Kconfig     |   6 ++
> >  drivers/gpio/Makefile    |   1 +
> >  drivers/gpio/gpio-reg.c  | 139 +++++++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/gpio-reg.h |  12 ++++
> >  4 files changed, 158 insertions(+)
> >  create mode 100644 drivers/gpio/gpio-reg.c
> >  create mode 100644 include/linux/gpio-reg.h
> >
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index 98dd47a30fc7..49bd8b89712e 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -365,6 +365,12 @@ config GPIO_RCAR
> >  	help
> >  	  Say yes here to support GPIO on Renesas R-Car SoCs.
> >  
> > +config GPIO_REG
> > +	bool
> So I suppose it is on purpose you forbid it to be a module. Is there a way to
> write either in the commit message or in the Kconfig this purpose, so that
> nobody on "purpose" changes this bool to tristate ?

The only forbidding is that it's used from code early at boot, so it has
to be available to the kernel for some of these platforms to function.
Even if it's changed to tristate, the select from these platforms would
force it to be built-in.

> > +	help
> > +	  A 32-bit single register GPIO fixed in/out implementation.  This
> > +	  can be used to represent any register as a set of GPIO signals.
> Another question I was asking myself was how it differenciated itself from
> gpio-mmio, ie. what brought the need for this driver that isn't available with
> gpio-mmio ?

gpio-mmio doesn't allow the fixed direction - it assumes that you always
have some form of direction register.  It also doesn't do the double-read
that's necessary for some platforms to get the "current" state of inputs.
It also doesn't do the "use 32-bit accessors even for smaller numbers of
GPIOs".  Lastly, it assumes that the current output state can be read
from the registers - this is not always the case (and is not the case for
Assabet.)

> I seem to understand that this is mainly for platform code, hence the
> "builtin only" necessity, and if I'm right a part of your cover letter
> could very well fit within this patch's commit message.

Apart from the missing MODULE_* tags and symbol exports, there's nothing
whic prohibits it becoming a module.

> > +static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
> > +	unsigned long *bits)
> > +{
> > +	struct gpio_reg *r = to_gpio_reg(gc);
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&r->lock, flags);
> > +	r->out = (r->out & ~*mask) | *bits;
> Shouldn't this be :
> 	r->out = (r->out & ~*mask) | (*bits & *mask);

Possibly, but the latter is redundant when used through gpiolib.

> > diff --git a/include/linux/gpio-reg.h b/include/linux/gpio-reg.h
> > new file mode 100644
> > index 000000000000..0352bec7319a
> > --- /dev/null
> > +++ b/include/linux/gpio-reg.h
> > @@ -0,0 +1,12 @@
> > +#ifndef GPIO_REG_H
> > +#define GPIO_REG_H
> > +
> > +struct device;
> > +
> > +struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
> > +	int base, int num, const char *label, u32 direction, u32 def_out,
> > +	const char *const *names);
> Maybe this one would deserve a doxygen comment ?

Maybe, but I've been told not to put such comments in header files.
I've already spent the last two weeks on this stuff (at the expense
of reading mail), I've not got around to thinking about any kind of
documentation.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-29 23:12         ` Russell King - ARM Linux
@ 2016-08-30  6:08           ` Alexander Shiyan
  -1 siblings, 0 replies; 235+ messages in thread
From: Alexander Shiyan @ 2016-08-30  6:08 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, Daniel Mack, Robert Jarzmik,
	linux-arm-kernel

>Вторник, 30 августа 2016, 2:12 +03:00 от Russell King - ARM Linux <linux@armlinux.org.uk>:
>
>On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
>> Hi Russell,
>> 
>> Russell King < rmk+kernel@armlinux.org.uk > writes:
>> 
>> > Add a simple, generic, single register fixed-direction GPIO driver.
>> > This is able to support a single register where a fixed number of
>> > bits are used for input and a fixed number of bits used for output.
>> >
>> > Signed-off-by: Russell King < rmk+kernel@armlinux.org.uk >

There is a GPIO driver which already performs these tasks.
Plaease take a look on the gpio-74xx-mmio driver.

---

_______________________________________________
Linux PCMCIA reimplementation list
http://lists.infradead.org/mailman/listinfo/linux-pcmcia

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30  6:08           ` Alexander Shiyan
  0 siblings, 0 replies; 235+ messages in thread
From: Alexander Shiyan @ 2016-08-30  6:08 UTC (permalink / raw)
  To: linux-arm-kernel

>???????, 30 ??????? 2016, 2:12 +03:00 ?? Russell King - ARM Linux <linux@armlinux.org.uk>:
>
>On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
>> Hi Russell,
>> 
>> Russell King < rmk+kernel@armlinux.org.uk > writes:
>> 
>> > Add a simple, generic, single register fixed-direction GPIO driver.
>> > This is able to support a single register where a fixed number of
>> > bits are used for input and a fixed number of bits used for output.
>> >
>> > Signed-off-by: Russell King < rmk+kernel@armlinux.org.uk >

There is a GPIO driver which already performs these tasks.
Plaease take a look on the gpio-74xx-mmio driver.

---

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30  6:08           ` Alexander Shiyan
@ 2016-08-30  7:41             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30  7:41 UTC (permalink / raw)
  To: Alexander Shiyan
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack,
	Robert Jarzmik

On Tue, Aug 30, 2016 at 09:08:03AM +0300, Alexander Shiyan wrote:
> >Вторник, 30 августа 2016, 2:12 +03:00 от Russell King - ARM Linux <linux@armlinux.org.uk>:
> >
> >On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> >> Hi Russell,
> >> 
> >> Russell King < rmk+kernel@armlinux.org.uk > writes:
> >> 
> >> > Add a simple, generic, single register fixed-direction GPIO driver.
> >> > This is able to support a single register where a fixed number of
> >> > bits are used for input and a fixed number of bits used for output.
> >> >
> >> > Signed-off-by: Russell King < rmk+kernel@armlinux.org.uk >
> 
> There is a GPIO driver which already performs these tasks.
> Plaease take a look on the gpio-74xx-mmio driver.

I did, and no it doesn't, because:

1. It is either all-in or all-out, it doesn't support a mixture of
   fixed-directions for a single register.
2. It is DT-only, I need it for legacy platforms.
3. It uses the bgpio stuff, which is unsuitable for reasons already
   covered in a previous reply.

So, gpio-74xx-mmio is unsuitable.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30  7:41             ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 30, 2016 at 09:08:03AM +0300, Alexander Shiyan wrote:
> >???????, 30 ??????? 2016, 2:12 +03:00 ?? Russell King - ARM Linux <linux@armlinux.org.uk>:
> >
> >On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> >> Hi Russell,
> >> 
> >> Russell King < rmk+kernel@armlinux.org.uk > writes:
> >> 
> >> > Add a simple, generic, single register fixed-direction GPIO driver.
> >> > This is able to support a single register where a fixed number of
> >> > bits are used for input and a fixed number of bits used for output.
> >> >
> >> > Signed-off-by: Russell King < rmk+kernel@armlinux.org.uk >
> 
> There is a GPIO driver which already performs these tasks.
> Plaease take a look on the gpio-74xx-mmio driver.

I did, and no it doesn't, because:

1. It is either all-in or all-out, it doesn't support a mixture of
   fixed-directions for a single register.
2. It is DT-only, I need it for legacy platforms.
3. It uses the bgpio stuff, which is unsuitable for reasons already
   covered in a previous reply.

So, gpio-74xx-mmio is unsuitable.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-29 19:39       ` Robert Jarzmik
@ 2016-08-30  9:18         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30  9:18 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Linus Walleij

On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> Maybe this one would deserve a doxygen comment ?

Does this solve it?

diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
index fc7e0a395f9f..b91488ec122c 100644
--- a/drivers/gpio/gpio-reg.c
+++ b/drivers/gpio/gpio-reg.c
@@ -1,3 +1,12 @@
+/*
+ * gpio-reg: single register individually fixed-direction GPIOs
+ *
+ * Copyright (C) 2016 Russell King
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
 #include <linux/gpio/driver.h>
 #include <linux/gpio-reg.h>
 #include <linux/io.h>
@@ -87,6 +96,22 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 	spin_unlock_irqrestore(&r->lock, flags);
 }
 
+/**
+ * gpio_reg_init - add a fixed in/out register as gpio
+ * @dev: optional struct device associated with this register
+ * @base: start gpio number, or -1 to allocate
+ * @num: number of GPIOs, maximum 32
+ * @label: GPIO chip label
+ * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in
+ * @def_out: initial GPIO output value
+ * @names: array of %num strings describing each GPIO signal
+ *
+ * Add a single-register GPIO device containing up to 32 GPIO signals,
+ * where each GPIO has a fixed input or output configuration.  Only
+ * input GPIOs are assumed to be readable from the register, and only
+ * then after a double-read.  Output values are assumed not to be
+ * readable.
+ */
 struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	int base, int num, const char *label, u32 direction, u32 def_out,
 	const char *const *names)


-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30  9:18         ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30  9:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> Maybe this one would deserve a doxygen comment ?

Does this solve it?

diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
index fc7e0a395f9f..b91488ec122c 100644
--- a/drivers/gpio/gpio-reg.c
+++ b/drivers/gpio/gpio-reg.c
@@ -1,3 +1,12 @@
+/*
+ * gpio-reg: single register individually fixed-direction GPIOs
+ *
+ * Copyright (C) 2016 Russell King
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ */
 #include <linux/gpio/driver.h>
 #include <linux/gpio-reg.h>
 #include <linux/io.h>
@@ -87,6 +96,22 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 	spin_unlock_irqrestore(&r->lock, flags);
 }
 
+/**
+ * gpio_reg_init - add a fixed in/out register as gpio
+ * @dev: optional struct device associated with this register
+ * @base: start gpio number, or -1 to allocate
+ * @num: number of GPIOs, maximum 32
+ * @label: GPIO chip label
+ * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in
+ * @def_out: initial GPIO output value
+ * @names: array of %num strings describing each GPIO signal
+ *
+ * Add a single-register GPIO device containing up to 32 GPIO signals,
+ * where each GPIO has a fixed input or output configuration.  Only
+ * input GPIOs are assumed to be readable from the register, and only
+ * then after a double-read.  Output values are assumed not to be
+ * readable.
+ */
 struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	int base, int num, const char *label, u32 direction, u32 def_out,
 	const char *const *names)


-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
  2016-08-29 12:06           ` Russell King
@ 2016-08-30 10:51             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 10:51 UTC (permalink / raw)
  To: linux-arm-kernel, netdev; +Cc: Nicolas Pitre

This mini-series (which follows several other series on which it
depends) gets rid of the Assabet/Neponset hack in the smc91x driver.

In order to do that, we need to get several pieces in place first:
* gpiolib support throughout SA11x0/Assabet/Neponset so that we can
  represent control signals through gpiolib
* CCF support, so we can re-use the code in drivers/clk to implement
  the external crystal oscillator attached to the SMC91x.  This
  external crystal oscillator is enabled via a control signal.

This series:
- performs the SA11x0 CCF conversion
- adds an optional clock to SMC91x to cater for an external crystal
  oscillator
- switches the Neponset code to provide a 'struct clk' representing
  this oscillator
- removes the SMC91x hack to assert the enable signal

This results in the platform specific includes being removed from the
SMC91x driver.

Please ack these changes; due to the dependencies, I wish to merge
them through my tree.  Thanks.

 arch/arm/Kconfig                   |   1 +
 arch/arm/mach-sa1100/clock.c       | 191 +++++++++++++++++--------------------
 arch/arm/mach-sa1100/neponset.c    |  42 ++++++++
 drivers/net/ethernet/smsc/smc91x.c |  47 ++++++---
 drivers/net/ethernet/smsc/smc91x.h |   1 +
 5 files changed, 166 insertions(+), 116 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
@ 2016-08-30 10:51             ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 10:51 UTC (permalink / raw)
  To: linux-arm-kernel

This mini-series (which follows several other series on which it
depends) gets rid of the Assabet/Neponset hack in the smc91x driver.

In order to do that, we need to get several pieces in place first:
* gpiolib support throughout SA11x0/Assabet/Neponset so that we can
  represent control signals through gpiolib
* CCF support, so we can re-use the code in drivers/clk to implement
  the external crystal oscillator attached to the SMC91x.  This
  external crystal oscillator is enabled via a control signal.

This series:
- performs the SA11x0 CCF conversion
- adds an optional clock to SMC91x to cater for an external crystal
  oscillator
- switches the Neponset code to provide a 'struct clk' representing
  this oscillator
- removes the SMC91x hack to assert the enable signal

This results in the platform specific includes being removed from the
SMC91x driver.

Please ack these changes; due to the dependencies, I wish to merge
them through my tree.  Thanks.

 arch/arm/Kconfig                   |   1 +
 arch/arm/mach-sa1100/clock.c       | 191 +++++++++++++++++--------------------
 arch/arm/mach-sa1100/neponset.c    |  42 ++++++++
 drivers/net/ethernet/smsc/smc91x.c |  47 ++++++---
 drivers/net/ethernet/smsc/smc91x.h |   1 +
 5 files changed, 166 insertions(+), 116 deletions(-)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 1/4] ARM: sa1100: convert to common clock framework
  2016-08-30 10:51             ` Russell King - ARM Linux
@ 2016-08-30 10:52               ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel, netdev; +Cc: Nicolas Pitre

Convert sa1100 to use the common clock framework.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/Kconfig             |   1 +
 arch/arm/mach-sa1100/clock.c | 191 +++++++++++++++++++------------------------
 2 files changed, 87 insertions(+), 105 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91c47f30986..e6706601dbe9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -588,6 +588,7 @@ config ARCH_SA1100
 	select CLKSRC_MMIO
 	select CLKSRC_PXA
 	select CLKSRC_OF if OF
+	select COMMON_CLK
 	select CPU_FREQ
 	select CPU_SA1100
 	select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index f6f75c9325bf..ebb39eba3717 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -1,151 +1,132 @@
 /*
  *  linux/arch/arm/mach-sa1100/clock.c
  */
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/string.h>
 #include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
 
 #include <mach/hardware.h>
 #include <mach/generic.h>
 
-struct clkops {
-	void			(*enable)(struct clk *);
-	void			(*disable)(struct clk *);
-	unsigned long		(*get_rate)(struct clk *);
-};
-
-struct clk {
-	const struct clkops	*ops;
-	unsigned int		enabled;
+static const char *clk_tucr_parents[] = {
+	"clk32768", "clk3686400",
 };
 
-#define DEFINE_CLK(_name, _ops)				\
-struct clk clk_##_name = {				\
-		.ops	= _ops,				\
-	}
-
-static DEFINE_SPINLOCK(clocks_lock);
+static DEFINE_SPINLOCK(tucr_lock);
 
-static void clk_gpio27_enable(struct clk *clk)
+static int clk_gpio27_enable(struct clk_hw *hw)
 {
+	unsigned long flags;
+
 	/*
 	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
 	 * (SA-1110 Developer's Manual, section 9.1.2.1)
 	 */
+	local_irq_save(flags);
 	GAFR |= GPIO_32_768kHz;
 	GPDR |= GPIO_32_768kHz;
-	TUCR = TUCR_3_6864MHz;
-}
-
-static void clk_gpio27_disable(struct clk *clk)
-{
-	TUCR = 0;
-	GPDR &= ~GPIO_32_768kHz;
-	GAFR &= ~GPIO_32_768kHz;
-}
-
-static void clk_cpu_enable(struct clk *clk)
-{
-}
-
-static void clk_cpu_disable(struct clk *clk)
-{
-}
-
-static unsigned long clk_cpu_get_rate(struct clk *clk)
-{
-	return sa11x0_getspeed(0) * 1000;
-}
-
-int clk_enable(struct clk *clk)
-{
-	unsigned long flags;
-
-	if (clk) {
-		spin_lock_irqsave(&clocks_lock, flags);
-		if (clk->enabled++ == 0)
-			clk->ops->enable(clk);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-	}
+	local_irq_restore(flags);
 
 	return 0;
 }
-EXPORT_SYMBOL(clk_enable);
 
-void clk_disable(struct clk *clk)
+static void clk_gpio27_disable(struct clk_hw *hw)
 {
 	unsigned long flags;
 
-	if (clk) {
-		WARN_ON(clk->enabled == 0);
-		spin_lock_irqsave(&clocks_lock, flags);
-		if (--clk->enabled == 0)
-			clk->ops->disable(clk);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-	}
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk && clk->ops && clk->ops->get_rate)
-		return clk->ops->get_rate(clk);
-
-	return 0;
+	local_irq_save(flags);
+	GPDR &= ~GPIO_32_768kHz;
+	GAFR &= ~GPIO_32_768kHz;
+	local_irq_restore(flags);
 }
-EXPORT_SYMBOL(clk_get_rate);
 
-const struct clkops clk_gpio27_ops = {
-	.enable		= clk_gpio27_enable,
-	.disable	= clk_gpio27_disable,
+static const struct clk_ops clk_gpio27_ops = {
+	.enable = clk_gpio27_enable,
+	.disable = clk_gpio27_disable,
 };
 
-const struct clkops clk_cpu_ops = {
-	.enable		= clk_cpu_enable,
-	.disable	= clk_cpu_disable,
-	.get_rate	= clk_cpu_get_rate,
+static const char *clk_gpio27_parents[] = {
+	"tucr-mux",
 };
 
-static DEFINE_CLK(gpio27, &clk_gpio27_ops);
-
-static DEFINE_CLK(cpu, &clk_cpu_ops);
-
-static unsigned long clk_36864_get_rate(struct clk *clk)
+static unsigned long clk_mpll_recalc_rate(struct clk_hw *hw, unsigned long prate)
 {
-	return 3686400;
+	return sa11x0_getspeed(0) * 1000;
 }
 
-static struct clkops clk_36864_ops = {
-	.enable		= clk_cpu_enable,
-	.disable	= clk_cpu_disable,
-	.get_rate	= clk_36864_get_rate,
+static const struct clk_ops cpu_clock_ops = {
+	.recalc_rate = clk_mpll_recalc_rate,
 };
 
-static DEFINE_CLK(36864, &clk_36864_ops);
-
-static struct clk_lookup sa11xx_clkregs[] = {
-	CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
-	CLKDEV_INIT("sa1100-rtc", NULL, NULL),
-	CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
-	CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
-	CLKDEV_INIT("sa11x0-pcmcia.0", NULL, &clk_cpu),
-	CLKDEV_INIT("sa11x0-pcmcia.1", NULL, &clk_cpu),
-	/* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
-	CLKDEV_INIT("1800", NULL, &clk_cpu),
-	CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
+static const char *clk_mpll_parents[] = {
+	"clk3686400",
 };
 
 int __init sa11xx_clk_init(void)
 {
-	clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	hw = clk_hw_register_fixed_rate(NULL, "clk32768", NULL, 0, 32768);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	clk_hw_register_clkdev(hw, NULL, "sa1100-rtc");
+
+	hw = clk_hw_register_fixed_rate(NULL, "clk3686400", NULL, 0, 3686400);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	clk_hw_register_clkdev(hw, "OSTIMER0", NULL);
+
+	init.name = "mpll";
+	init.ops = &cpu_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = clk_mpll_parents;
+	init.num_parents = ARRAY_SIZE(clk_mpll_parents);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw)
+		return -ENOMEM;
+	hw->init = &init;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(hw);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-fb");
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia");
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia.0");
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia.1");
+	clk_hw_register_clkdev(hw, NULL, "1800");
+
+	hw = clk_hw_register_mux(NULL, "tucr-mux", clk_tucr_parents,
+				 ARRAY_SIZE(clk_tucr_parents), 0,
+				 (void __iomem *)&TUCR, FShft(TUCR_TSEL),
+				 FAlnMsk(TUCR_TSEL), 0, &tucr_lock);
+	clk_set_rate(hw->clk, 3686400);
+
+	init.name = "gpio27";
+	init.ops = &clk_gpio27_ops;
+	init.parent_names = clk_gpio27_parents;
+	init.num_parents = ARRAY_SIZE(clk_gpio27_parents);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw)
+		return -ENOMEM;
+	hw->init = &init;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(hw);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(hw, NULL, "sa1111.0");
+
 	return 0;
 }
-- 
2.1.0

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

* [PATCH 1/4] ARM: sa1100: convert to common clock framework
@ 2016-08-30 10:52               ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

Convert sa1100 to use the common clock framework.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/Kconfig             |   1 +
 arch/arm/mach-sa1100/clock.c | 191 +++++++++++++++++++------------------------
 2 files changed, 87 insertions(+), 105 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91c47f30986..e6706601dbe9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -588,6 +588,7 @@ config ARCH_SA1100
 	select CLKSRC_MMIO
 	select CLKSRC_PXA
 	select CLKSRC_OF if OF
+	select COMMON_CLK
 	select CPU_FREQ
 	select CPU_SA1100
 	select GENERIC_CLOCKEVENTS
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index f6f75c9325bf..ebb39eba3717 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -1,151 +1,132 @@
 /*
  *  linux/arch/arm/mach-sa1100/clock.c
  */
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/string.h>
 #include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
 
 #include <mach/hardware.h>
 #include <mach/generic.h>
 
-struct clkops {
-	void			(*enable)(struct clk *);
-	void			(*disable)(struct clk *);
-	unsigned long		(*get_rate)(struct clk *);
-};
-
-struct clk {
-	const struct clkops	*ops;
-	unsigned int		enabled;
+static const char *clk_tucr_parents[] = {
+	"clk32768", "clk3686400",
 };
 
-#define DEFINE_CLK(_name, _ops)				\
-struct clk clk_##_name = {				\
-		.ops	= _ops,				\
-	}
-
-static DEFINE_SPINLOCK(clocks_lock);
+static DEFINE_SPINLOCK(tucr_lock);
 
-static void clk_gpio27_enable(struct clk *clk)
+static int clk_gpio27_enable(struct clk_hw *hw)
 {
+	unsigned long flags;
+
 	/*
 	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
 	 * (SA-1110 Developer's Manual, section 9.1.2.1)
 	 */
+	local_irq_save(flags);
 	GAFR |= GPIO_32_768kHz;
 	GPDR |= GPIO_32_768kHz;
-	TUCR = TUCR_3_6864MHz;
-}
-
-static void clk_gpio27_disable(struct clk *clk)
-{
-	TUCR = 0;
-	GPDR &= ~GPIO_32_768kHz;
-	GAFR &= ~GPIO_32_768kHz;
-}
-
-static void clk_cpu_enable(struct clk *clk)
-{
-}
-
-static void clk_cpu_disable(struct clk *clk)
-{
-}
-
-static unsigned long clk_cpu_get_rate(struct clk *clk)
-{
-	return sa11x0_getspeed(0) * 1000;
-}
-
-int clk_enable(struct clk *clk)
-{
-	unsigned long flags;
-
-	if (clk) {
-		spin_lock_irqsave(&clocks_lock, flags);
-		if (clk->enabled++ == 0)
-			clk->ops->enable(clk);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-	}
+	local_irq_restore(flags);
 
 	return 0;
 }
-EXPORT_SYMBOL(clk_enable);
 
-void clk_disable(struct clk *clk)
+static void clk_gpio27_disable(struct clk_hw *hw)
 {
 	unsigned long flags;
 
-	if (clk) {
-		WARN_ON(clk->enabled == 0);
-		spin_lock_irqsave(&clocks_lock, flags);
-		if (--clk->enabled == 0)
-			clk->ops->disable(clk);
-		spin_unlock_irqrestore(&clocks_lock, flags);
-	}
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk && clk->ops && clk->ops->get_rate)
-		return clk->ops->get_rate(clk);
-
-	return 0;
+	local_irq_save(flags);
+	GPDR &= ~GPIO_32_768kHz;
+	GAFR &= ~GPIO_32_768kHz;
+	local_irq_restore(flags);
 }
-EXPORT_SYMBOL(clk_get_rate);
 
-const struct clkops clk_gpio27_ops = {
-	.enable		= clk_gpio27_enable,
-	.disable	= clk_gpio27_disable,
+static const struct clk_ops clk_gpio27_ops = {
+	.enable = clk_gpio27_enable,
+	.disable = clk_gpio27_disable,
 };
 
-const struct clkops clk_cpu_ops = {
-	.enable		= clk_cpu_enable,
-	.disable	= clk_cpu_disable,
-	.get_rate	= clk_cpu_get_rate,
+static const char *clk_gpio27_parents[] = {
+	"tucr-mux",
 };
 
-static DEFINE_CLK(gpio27, &clk_gpio27_ops);
-
-static DEFINE_CLK(cpu, &clk_cpu_ops);
-
-static unsigned long clk_36864_get_rate(struct clk *clk)
+static unsigned long clk_mpll_recalc_rate(struct clk_hw *hw, unsigned long prate)
 {
-	return 3686400;
+	return sa11x0_getspeed(0) * 1000;
 }
 
-static struct clkops clk_36864_ops = {
-	.enable		= clk_cpu_enable,
-	.disable	= clk_cpu_disable,
-	.get_rate	= clk_36864_get_rate,
+static const struct clk_ops cpu_clock_ops = {
+	.recalc_rate = clk_mpll_recalc_rate,
 };
 
-static DEFINE_CLK(36864, &clk_36864_ops);
-
-static struct clk_lookup sa11xx_clkregs[] = {
-	CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
-	CLKDEV_INIT("sa1100-rtc", NULL, NULL),
-	CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
-	CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
-	CLKDEV_INIT("sa11x0-pcmcia.0", NULL, &clk_cpu),
-	CLKDEV_INIT("sa11x0-pcmcia.1", NULL, &clk_cpu),
-	/* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
-	CLKDEV_INIT("1800", NULL, &clk_cpu),
-	CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
+static const char *clk_mpll_parents[] = {
+	"clk3686400",
 };
 
 int __init sa11xx_clk_init(void)
 {
-	clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int ret;
+
+	hw = clk_hw_register_fixed_rate(NULL, "clk32768", NULL, 0, 32768);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	clk_hw_register_clkdev(hw, NULL, "sa1100-rtc");
+
+	hw = clk_hw_register_fixed_rate(NULL, "clk3686400", NULL, 0, 3686400);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	clk_hw_register_clkdev(hw, "OSTIMER0", NULL);
+
+	init.name = "mpll";
+	init.ops = &cpu_clock_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = clk_mpll_parents;
+	init.num_parents = ARRAY_SIZE(clk_mpll_parents);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw)
+		return -ENOMEM;
+	hw->init = &init;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(hw);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-fb");
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia");
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia.0");
+	clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia.1");
+	clk_hw_register_clkdev(hw, NULL, "1800");
+
+	hw = clk_hw_register_mux(NULL, "tucr-mux", clk_tucr_parents,
+				 ARRAY_SIZE(clk_tucr_parents), 0,
+				 (void __iomem *)&TUCR, FShft(TUCR_TSEL),
+				 FAlnMsk(TUCR_TSEL), 0, &tucr_lock);
+	clk_set_rate(hw->clk, 3686400);
+
+	init.name = "gpio27";
+	init.ops = &clk_gpio27_ops;
+	init.parent_names = clk_gpio27_parents;
+	init.num_parents = ARRAY_SIZE(clk_gpio27_parents);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw)
+		return -ENOMEM;
+	hw->init = &init;
+	ret = clk_hw_register(NULL, hw);
+	if (ret) {
+		kfree(hw);
+		return ret;
+	}
+
+	clk_hw_register_clkdev(hw, NULL, "sa1111.0");
+
 	return 0;
 }
-- 
2.1.0

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

* [PATCH 2/4] net: smc91x: add external clock support
  2016-08-30 10:51             ` Russell King - ARM Linux
@ 2016-08-30 10:52               ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel, netdev; +Cc: Nicolas Pitre

The smc91x can be operated with either a directly attached crystal, or
an externally supplied clock.  When used with an externally supplied
clock, this clock may require some configuration or control.  Add calls
to the driver to lookup, enable and disable this optional clock.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/ethernet/smsc/smc91x.c | 38 ++++++++++++++++++++++++++++++++++++--
 drivers/net/ethernet/smsc/smc91x.h |  1 +
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 503a3b6dce91..43dbc1c7b9a5 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -73,6 +73,7 @@ static const char version[] =
 #include <linux/irq.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
+#include <linux/clk.h>
 #include <linux/crc32.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
@@ -2284,6 +2285,18 @@ static int smc_drv_probe(struct platform_device *pdev)
 		}
 	}
 
+	/*
+	 * Some platforms drive the xtal input from an external clock
+	 * source which may require some control.  Request the clock,
+	 * but allow probing to continue if no clock is specified.
+	 */
+	lp->xtal = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(lp->xtal)) {
+		if (PTR_ERR(lp->xtal) != -ENOENT)
+			return PTR_ERR(lp->xtal);
+		lp->xtal = NULL;
+	}
+
 #if IS_BUILTIN(CONFIG_OF)
 	match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev);
 	if (match) {
@@ -2375,15 +2388,20 @@ static int smc_drv_probe(struct platform_device *pdev)
 	if (machine_is_assabet() && machine_has_neponset())
 		neponset_ncr_set(NCR_ENET_OSC_EN);
 #endif
+	if (lp->xtal) {
+		ret = clk_prepare_enable(lp->xtal);
+		if (ret)
+			goto out_release_attrib;
+	}
 	platform_set_drvdata(pdev, ndev);
 	ret = smc_enable_device(pdev);
 	if (ret)
-		goto out_release_attrib;
+		goto out_disable_xtal;
 
 	addr = ioremap(res->start, SMC_IO_EXTENT);
 	if (!addr) {
 		ret = -ENOMEM;
-		goto out_release_attrib;
+		goto out_disable_xtal;
 	}
 
 #ifdef CONFIG_ARCH_PXA
@@ -2407,6 +2425,9 @@ static int smc_drv_probe(struct platform_device *pdev)
 	iounmap(addr);
  out_release_attrib:
 	smc_release_attrib(pdev, ndev);
+ out_disable_xtal:
+	if (lp->xtal)
+		clk_disable_unprepare(lp->xtal);
  out_release_io:
 	release_mem_region(res->start, SMC_IO_EXTENT);
  out_free_netdev:
@@ -2441,6 +2462,9 @@ static int smc_drv_remove(struct platform_device *pdev)
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, SMC_IO_EXTENT);
 
+	if (lp->xtal)
+		clk_disable_unprepare(lp->xtal);
+
 	free_netdev(ndev);
 
 	return 0;
@@ -2453,9 +2477,14 @@ static int smc_drv_suspend(struct device *dev)
 
 	if (ndev) {
 		if (netif_running(ndev)) {
+			struct smc_local *lp = netdev_priv(ndev);
+
 			netif_device_detach(ndev);
 			smc_shutdown(ndev);
 			smc_phy_powerdown(ndev);
+
+			if (lp->xtal)
+				clk_disable_unprepare(lp->xtal);
 		}
 	}
 	return 0;
@@ -2468,6 +2497,11 @@ static int smc_drv_resume(struct device *dev)
 
 	if (ndev) {
 		struct smc_local *lp = netdev_priv(ndev);
+		if (lp->xtal) {
+			int ret = clk_prepare_enable(lp->xtal);
+			if (ret)
+				return ret;
+		}
 		smc_enable_device(pdev);
 		if (netif_running(ndev)) {
 			smc_reset(ndev);
diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
index e17671c9d1b0..5377c2e1b8b9 100644
--- a/drivers/net/ethernet/smsc/smc91x.h
+++ b/drivers/net/ethernet/smsc/smc91x.h
@@ -266,6 +266,7 @@ struct smc_local {
 
 	struct gpio_desc *power_gpio;
 	struct gpio_desc *reset_gpio;
+	struct clk *xtal;
 
 	/* version/revision of the SMC91x chip */
 	int	version;
-- 
2.1.0

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

* [PATCH 2/4] net: smc91x: add external clock support
@ 2016-08-30 10:52               ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

The smc91x can be operated with either a directly attached crystal, or
an externally supplied clock.  When used with an externally supplied
clock, this clock may require some configuration or control.  Add calls
to the driver to lookup, enable and disable this optional clock.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/ethernet/smsc/smc91x.c | 38 ++++++++++++++++++++++++++++++++++++--
 drivers/net/ethernet/smsc/smc91x.h |  1 +
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 503a3b6dce91..43dbc1c7b9a5 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -73,6 +73,7 @@ static const char version[] =
 #include <linux/irq.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
+#include <linux/clk.h>
 #include <linux/crc32.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
@@ -2284,6 +2285,18 @@ static int smc_drv_probe(struct platform_device *pdev)
 		}
 	}
 
+	/*
+	 * Some platforms drive the xtal input from an external clock
+	 * source which may require some control.  Request the clock,
+	 * but allow probing to continue if no clock is specified.
+	 */
+	lp->xtal = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(lp->xtal)) {
+		if (PTR_ERR(lp->xtal) != -ENOENT)
+			return PTR_ERR(lp->xtal);
+		lp->xtal = NULL;
+	}
+
 #if IS_BUILTIN(CONFIG_OF)
 	match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev);
 	if (match) {
@@ -2375,15 +2388,20 @@ static int smc_drv_probe(struct platform_device *pdev)
 	if (machine_is_assabet() && machine_has_neponset())
 		neponset_ncr_set(NCR_ENET_OSC_EN);
 #endif
+	if (lp->xtal) {
+		ret = clk_prepare_enable(lp->xtal);
+		if (ret)
+			goto out_release_attrib;
+	}
 	platform_set_drvdata(pdev, ndev);
 	ret = smc_enable_device(pdev);
 	if (ret)
-		goto out_release_attrib;
+		goto out_disable_xtal;
 
 	addr = ioremap(res->start, SMC_IO_EXTENT);
 	if (!addr) {
 		ret = -ENOMEM;
-		goto out_release_attrib;
+		goto out_disable_xtal;
 	}
 
 #ifdef CONFIG_ARCH_PXA
@@ -2407,6 +2425,9 @@ static int smc_drv_probe(struct platform_device *pdev)
 	iounmap(addr);
  out_release_attrib:
 	smc_release_attrib(pdev, ndev);
+ out_disable_xtal:
+	if (lp->xtal)
+		clk_disable_unprepare(lp->xtal);
  out_release_io:
 	release_mem_region(res->start, SMC_IO_EXTENT);
  out_free_netdev:
@@ -2441,6 +2462,9 @@ static int smc_drv_remove(struct platform_device *pdev)
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, SMC_IO_EXTENT);
 
+	if (lp->xtal)
+		clk_disable_unprepare(lp->xtal);
+
 	free_netdev(ndev);
 
 	return 0;
@@ -2453,9 +2477,14 @@ static int smc_drv_suspend(struct device *dev)
 
 	if (ndev) {
 		if (netif_running(ndev)) {
+			struct smc_local *lp = netdev_priv(ndev);
+
 			netif_device_detach(ndev);
 			smc_shutdown(ndev);
 			smc_phy_powerdown(ndev);
+
+			if (lp->xtal)
+				clk_disable_unprepare(lp->xtal);
 		}
 	}
 	return 0;
@@ -2468,6 +2497,11 @@ static int smc_drv_resume(struct device *dev)
 
 	if (ndev) {
 		struct smc_local *lp = netdev_priv(ndev);
+		if (lp->xtal) {
+			int ret = clk_prepare_enable(lp->xtal);
+			if (ret)
+				return ret;
+		}
 		smc_enable_device(pdev);
 		if (netif_running(ndev)) {
 			smc_reset(ndev);
diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
index e17671c9d1b0..5377c2e1b8b9 100644
--- a/drivers/net/ethernet/smsc/smc91x.h
+++ b/drivers/net/ethernet/smsc/smc91x.h
@@ -266,6 +266,7 @@ struct smc_local {
 
 	struct gpio_desc *power_gpio;
 	struct gpio_desc *reset_gpio;
+	struct clk *xtal;
 
 	/* version/revision of the SMC91x chip */
 	int	version;
-- 
2.1.0

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

* [PATCH 3/4] ARM: sa1100/neponset: add ethernet oscillator
  2016-08-30 10:51             ` Russell King - ARM Linux
@ 2016-08-30 10:52               ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel, netdev; +Cc: Nicolas Pitre

Add the clock structure for the external SMC91x ethernet oscillator.
This oscillator has an enable signal which allows the oscillator to be
placed in low power mode when not required.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index bff6efdfaeaf..700659cadebb 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -1,6 +1,8 @@
 /*
  * linux/arch/arm/mach-sa1100/neponset.c
  */
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/machine.h>
@@ -78,6 +80,9 @@ struct neponset_drvdata {
 	struct platform_device *smc91x;
 	unsigned irq_base;
 	struct gpio_chip *gpio[4];
+	struct clk_hw *enet_osc_ck;
+	struct clk_hw *enet_osc_gate;
+	struct clk_lookup *enet_osc_cl;
 };
 
 static struct gpiod_lookup_table neponset_uart1_gpio_table = {
@@ -217,6 +222,38 @@ static int neponset_init_gpio(struct gpio_chip **gcp,
 	return 0;
 }
 
+static int neponset_init_enet(struct device *dev, struct neponset_drvdata *d)
+{
+	int ret;
+
+	d->enet_osc_ck = clk_hw_register_fixed_rate(dev, "nep_enet_osc",
+						    NULL, 0, 20000000);
+	if (IS_ERR(d->enet_osc_ck))
+		return PTR_ERR(d->enet_osc_ck);
+
+	d->enet_osc_gate = clk_hw_register_gpio_gate(dev, "nep_enet_gate",
+						     "nep_enet_osc",
+						     d->gpio[0]->base + 3,
+						     false, 0);
+	if (IS_ERR(d->enet_osc_gate)) {
+		ret = PTR_ERR(d->enet_osc_gate);
+		goto err;
+	}
+
+	d->enet_osc_cl = clkdev_hw_create(d->enet_osc_gate, NULL, "smc91x.0");
+	if (!d->enet_osc_cl) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	return 0;
+
+err:
+	if (d->enet_osc_ck)
+		clk_hw_unregister_fixed_rate(d->enet_osc_ck);
+	return ret;
+}
+
 static struct sa1111_platform_data sa1111_info = {
 	.disable_devs	= SA1111_DEVID_PS2_MSE,
 };
@@ -333,6 +370,8 @@ static int neponset_probe(struct platform_device *dev)
 	gpiod_add_lookup_table(&neponset_uart3_gpio_table);
 	gpiod_add_lookup_table(&neponset_pcmcia_table);
 
+	neponset_init_enet(&dev->dev, d);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -385,6 +424,9 @@ static int neponset_remove(struct platform_device *dev)
 	if (!IS_ERR(d->smc91x))
 		platform_device_unregister(d->smc91x);
 
+	clkdev_drop(d->enet_osc_cl);
+	clk_hw_unregister_fixed_rate(d->enet_osc_ck);
+
 	gpiod_remove_lookup_table(&neponset_pcmcia_table);
 	gpiod_remove_lookup_table(&neponset_uart3_gpio_table);
 	gpiod_remove_lookup_table(&neponset_uart1_gpio_table);
-- 
2.1.0

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

* [PATCH 3/4] ARM: sa1100/neponset: add ethernet oscillator
@ 2016-08-30 10:52               ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

Add the clock structure for the external SMC91x ethernet oscillator.
This oscillator has an enable signal which allows the oscillator to be
placed in low power mode when not required.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/neponset.c | 42 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index bff6efdfaeaf..700659cadebb 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -1,6 +1,8 @@
 /*
  * linux/arch/arm/mach-sa1100/neponset.c
  */
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 #include <linux/err.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/machine.h>
@@ -78,6 +80,9 @@ struct neponset_drvdata {
 	struct platform_device *smc91x;
 	unsigned irq_base;
 	struct gpio_chip *gpio[4];
+	struct clk_hw *enet_osc_ck;
+	struct clk_hw *enet_osc_gate;
+	struct clk_lookup *enet_osc_cl;
 };
 
 static struct gpiod_lookup_table neponset_uart1_gpio_table = {
@@ -217,6 +222,38 @@ static int neponset_init_gpio(struct gpio_chip **gcp,
 	return 0;
 }
 
+static int neponset_init_enet(struct device *dev, struct neponset_drvdata *d)
+{
+	int ret;
+
+	d->enet_osc_ck = clk_hw_register_fixed_rate(dev, "nep_enet_osc",
+						    NULL, 0, 20000000);
+	if (IS_ERR(d->enet_osc_ck))
+		return PTR_ERR(d->enet_osc_ck);
+
+	d->enet_osc_gate = clk_hw_register_gpio_gate(dev, "nep_enet_gate",
+						     "nep_enet_osc",
+						     d->gpio[0]->base + 3,
+						     false, 0);
+	if (IS_ERR(d->enet_osc_gate)) {
+		ret = PTR_ERR(d->enet_osc_gate);
+		goto err;
+	}
+
+	d->enet_osc_cl = clkdev_hw_create(d->enet_osc_gate, NULL, "smc91x.0");
+	if (!d->enet_osc_cl) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	return 0;
+
+err:
+	if (d->enet_osc_ck)
+		clk_hw_unregister_fixed_rate(d->enet_osc_ck);
+	return ret;
+}
+
 static struct sa1111_platform_data sa1111_info = {
 	.disable_devs	= SA1111_DEVID_PS2_MSE,
 };
@@ -333,6 +370,8 @@ static int neponset_probe(struct platform_device *dev)
 	gpiod_add_lookup_table(&neponset_uart3_gpio_table);
 	gpiod_add_lookup_table(&neponset_pcmcia_table);
 
+	neponset_init_enet(&dev->dev, d);
+
 	/*
 	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 	 * something on the Neponset activates this IRQ on sleep (eth?)
@@ -385,6 +424,9 @@ static int neponset_remove(struct platform_device *dev)
 	if (!IS_ERR(d->smc91x))
 		platform_device_unregister(d->smc91x);
 
+	clkdev_drop(d->enet_osc_cl);
+	clk_hw_unregister_fixed_rate(d->enet_osc_ck);
+
 	gpiod_remove_lookup_table(&neponset_pcmcia_table);
 	gpiod_remove_lookup_table(&neponset_uart3_gpio_table);
 	gpiod_remove_lookup_table(&neponset_uart1_gpio_table);
-- 
2.1.0

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

* [PATCH 4/4] net: smc91x: remove neponset specific oscillator hack
  2016-08-30 10:51             ` Russell King - ARM Linux
@ 2016-08-30 10:52               ` Russell King
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel, netdev; +Cc: Nicolas Pitre

Remove the neponset specific oscillator hack from the smc91x driver,
relying instead on the gpio controls provided.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/ethernet/smsc/smc91x.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 43dbc1c7b9a5..e53aa640f0d7 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -92,11 +92,6 @@ static const char version[] =
 
 #include "smc91x.h"
 
-#if defined(CONFIG_ASSABET_NEPONSET)
-#include <mach/assabet.h>
-#include <mach/neponset.h>
-#endif
-
 #ifndef SMC_NOWAIT
 # define SMC_NOWAIT		0
 #endif
@@ -2384,10 +2379,6 @@ static int smc_drv_probe(struct platform_device *pdev)
 	ret = smc_request_attrib(pdev, ndev);
 	if (ret)
 		goto out_release_io;
-#if defined(CONFIG_ASSABET_NEPONSET)
-	if (machine_is_assabet() && machine_has_neponset())
-		neponset_ncr_set(NCR_ENET_OSC_EN);
-#endif
 	if (lp->xtal) {
 		ret = clk_prepare_enable(lp->xtal);
 		if (ret)
-- 
2.1.0

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

* [PATCH 4/4] net: smc91x: remove neponset specific oscillator hack
@ 2016-08-30 10:52               ` Russell King
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the neponset specific oscillator hack from the smc91x driver,
relying instead on the gpio controls provided.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/net/ethernet/smsc/smc91x.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 43dbc1c7b9a5..e53aa640f0d7 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -92,11 +92,6 @@ static const char version[] =
 
 #include "smc91x.h"
 
-#if defined(CONFIG_ASSABET_NEPONSET)
-#include <mach/assabet.h>
-#include <mach/neponset.h>
-#endif
-
 #ifndef SMC_NOWAIT
 # define SMC_NOWAIT		0
 #endif
@@ -2384,10 +2379,6 @@ static int smc_drv_probe(struct platform_device *pdev)
 	ret = smc_request_attrib(pdev, ndev);
 	if (ret)
 		goto out_release_io;
-#if defined(CONFIG_ASSABET_NEPONSET)
-	if (machine_is_assabet() && machine_has_neponset())
-		neponset_ncr_set(NCR_ENET_OSC_EN);
-#endif
 	if (lp->xtal) {
 		ret = clk_prepare_enable(lp->xtal);
 		if (ret)
-- 
2.1.0

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

* [PATCH 0/8] SA11x0/PXA remainder & cleanups
  2016-08-30 10:51             ` Russell King - ARM Linux
                               ` (4 preceding siblings ...)
  (?)
@ 2016-08-30 10:59             ` Russell King - ARM Linux
  2016-08-30 11:00               ` [PATCH 1/8] mfd: ucb1x00: allow IRQ probing to work with IRQs > 32 Russell King
                                 ` (7 more replies)
  -1 siblings, 8 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

This last part of the series is predominantly a set of cleanup patches
removing definitions and files that aren't required, and moving some
files out of public view.  The ucb1x00 patch could arguably have
been sent in the first set, something that I'll arrange for the next
iteration.

Further conversions are possible - eg, mainstone could have its platform
register converted to the gpio-reg code, and then pxaficp and other
drivers could be further adapted to use gpiolib.  However, that would
make this series even larger than it already is, and I'm already
concerned that it's very much on the big side.  Given that it already
takes a long time to post this series in a sane manner, I'd like to
prevent it growing any further.

The only reason PXA got touched is becaues of the PCMCIA changes which
needed lubbock's MISC write register to be accessible for the MAX1600
code.

 arch/arm/mach-pxa/include/mach/lubbock.h           |   4 -
 arch/arm/mach-pxa/lubbock.c                        |   3 +-
 arch/arm/mach-sa1100/cerf.c                        |   3 +-
 arch/arm/mach-sa1100/{include/mach => }/cerf.h     |   9 +-
 arch/arm/mach-sa1100/include/mach/SA-1101.h        | 925 ---------------------
 arch/arm/mach-sa1100/include/mach/hardware.h       |   4 -
 arch/arm/mach-sa1100/include/mach/neponset.h       |  30 -
 arch/arm/mach-sa1100/nanoengine.c                  |   2 +-
 .../mach-sa1100/{include/mach => }/nanoengine.h    |  11 -
 arch/arm/mach-sa1100/neponset.c                    |  14 +-
 arch/arm/mach-sa1100/pci-nanoengine.c              |   3 +-
 drivers/mfd/ucb1x00-core.c                         |   4 -
 12 files changed, 8 insertions(+), 1004 deletions(-)
 rename arch/arm/mach-sa1100/{include/mach => }/cerf.h (66%)
 delete mode 100644 arch/arm/mach-sa1100/include/mach/SA-1101.h
 delete mode 100644 arch/arm/mach-sa1100/include/mach/neponset.h
 rename arch/arm/mach-sa1100/{include/mach => }/nanoengine.h (69%)

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 1/8] mfd: ucb1x00: allow IRQ probing to work with IRQs > 32
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 12:00                 ` Lee Jones
  2016-08-30 11:00               ` [PATCH 2/8] ARM: pxa/lubbock: remove lubbock_set_misc_wr() from global view Russell King
                                 ` (6 subsequent siblings)
  7 siblings, 1 reply; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

probe_irq_on() only returns non-zero if it found any interrupts below
IRQ32 which could be probe candidates.  If all the probable interrupts
are higher than 32, then this will cause a failure.  Fix this.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 drivers/mfd/ucb1x00-core.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 9ab9ec47ea75..48bea5038654 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -446,10 +446,6 @@ static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
 	unsigned long mask;
 
 	mask = probe_irq_on();
-	if (!mask) {
-		probe_irq_off(mask);
-		return NO_IRQ;
-	}
 
 	/*
 	 * Enable the ADC interrupt.
-- 
2.1.0

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

* [PATCH 2/8] ARM: pxa/lubbock: remove lubbock_set_misc_wr() from global view
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
  2016-08-30 11:00               ` [PATCH 1/8] mfd: ucb1x00: allow IRQ probing to work with IRQs > 32 Russell King
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 11:00               ` [PATCH 3/8] ARM: sa1100/cerf: remove redundant definitions Russell King
                                 ` (5 subsequent siblings)
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

There are now no users of lubbock_set_misc_wr() outside lubbock.c, so
make this function static.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/include/mach/lubbock.h | 4 ----
 arch/arm/mach-pxa/lubbock.c              | 3 +--
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h
index 1eecf794acd2..9926a5d741f7 100644
--- a/arch/arm/mach-pxa/include/mach/lubbock.h
+++ b/arch/arm/mach-pxa/include/mach/lubbock.h
@@ -50,7 +50,3 @@
 #define LUBBOCK_LAST_IRQ	LUBBOCK_IRQ(6)
 
 #define LUBBOCK_SA1111_IRQ_BASE	(LUBBOCK_NR_IRQS + 32)
-
-#ifndef __ASSEMBLY__
-extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
-#endif
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 8686c5d0dc3b..ffbab27cb581 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -119,12 +119,11 @@ void lubbock_set_hexled(uint32_t value)
 
 static struct gpio_chip *lubbock_misc_wr_gc;
 
-void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
+static void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
 {
 	unsigned long m = mask, v = set;
 	lubbock_misc_wr_gc->set_multiple(lubbock_misc_wr_gc, &m, &v);
 }
-EXPORT_SYMBOL(lubbock_set_misc_wr);
 
 static int lubbock_udc_is_connected(void)
 {
-- 
2.1.0

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

* [PATCH 3/8] ARM: sa1100/cerf: remove redundant definitions
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
  2016-08-30 11:00               ` [PATCH 1/8] mfd: ucb1x00: allow IRQ probing to work with IRQs > 32 Russell King
  2016-08-30 11:00               ` [PATCH 2/8] ARM: pxa/lubbock: remove lubbock_set_misc_wr() from global view Russell King
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 11:00               ` [PATCH 4/8] ARM: sa1100/cerf: move cerf header file Russell King
                                 ` (4 subsequent siblings)
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Remove redundant CF GPIO definitions from mach/cerf.h

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/include/mach/cerf.h | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/include/mach/cerf.h
index 88fd9c006ce0..f9f2222f013b 100644
--- a/arch/arm/mach-sa1100/include/mach/cerf.h
+++ b/arch/arm/mach-sa1100/include/mach/cerf.h
@@ -10,14 +10,7 @@
 #ifndef _INCLUDE_CERF_H_
 #define _INCLUDE_CERF_H_
 
-
 #define CERF_ETH_IO			0xf0000000
 #define CERF_ETH_IRQ IRQ_GPIO26
 
-#define CERF_GPIO_CF_BVD2		19
-#define CERF_GPIO_CF_BVD1		20
-#define CERF_GPIO_CF_RESET		21
-#define CERF_GPIO_CF_IRQ		22
-#define CERF_GPIO_CF_CD			23
-
 #endif // _INCLUDE_CERF_H_
-- 
2.1.0

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

* [PATCH 4/8] ARM: sa1100/cerf: move cerf header file
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
                                 ` (2 preceding siblings ...)
  2016-08-30 11:00               ` [PATCH 3/8] ARM: sa1100/cerf: remove redundant definitions Russell King
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 11:00               ` [PATCH 5/8] ARM: sa1100/nanoengine: remove redundant definitions Russell King
                                 ` (3 subsequent siblings)
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Nothing outside arch/arm/mach-sa1100 needs the cerf header file, so
move it into that directory.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/cerf.c                    | 3 ++-
 arch/arm/mach-sa1100/{include/mach => }/cerf.h | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
 rename arch/arm/mach-sa1100/{include/mach => }/cerf.h (89%)

diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 88e526561a24..0a32c32485be 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -30,9 +30,10 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 
-#include <mach/cerf.h>
 #include <linux/platform_data/mfd-mcp-sa11x0.h>
 #include <mach/irqs.h>
+
+#include "cerf.h"
 #include "generic.h"
 
 static struct resource cerfuart2_resources[] = {
diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/cerf.h
similarity index 89%
rename from arch/arm/mach-sa1100/include/mach/cerf.h
rename to arch/arm/mach-sa1100/cerf.h
index f9f2222f013b..a47c82ed8fae 100644
--- a/arch/arm/mach-sa1100/include/mach/cerf.h
+++ b/arch/arm/mach-sa1100/cerf.h
@@ -1,5 +1,5 @@
 /*
- * arch/arm/mach-sa1100/include/mach/cerf.h
+ * cerf.h
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
-- 
2.1.0

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

* [PATCH 5/8] ARM: sa1100/nanoengine: remove redundant definitions
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
                                 ` (3 preceding siblings ...)
  2016-08-30 11:00               ` [PATCH 4/8] ARM: sa1100/cerf: move cerf header file Russell King
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 11:00               ` [PATCH 6/8] ARM: sa1100/nanoengine: move nanoengine header file Russell King
                                 ` (2 subsequent siblings)
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Remove redundant GPIO definitions from mach/nanoengine.h

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/include/mach/nanoengine.h | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h
index 5ebd469a31f2..29ec4bfe5009 100644
--- a/arch/arm/mach-sa1100/include/mach/nanoengine.h
+++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h
@@ -16,18 +16,7 @@
 
 #include <mach/irqs.h>
 
-#define GPIO_PC_READY0	11 /* ready for socket 0 (active high)*/
-#define GPIO_PC_READY1	12 /* ready for socket 1 (active high) */
-#define GPIO_PC_CD0	13 /* detect for socket 0 (active low) */
-#define GPIO_PC_CD1	14 /* detect for socket 1 (active low) */
-#define GPIO_PC_RESET0	15 /* reset socket 0 */
-#define GPIO_PC_RESET1	16 /* reset socket 1 */
-
 #define NANOENGINE_IRQ_GPIO_PCI		IRQ_GPIO0
-#define NANOENGINE_IRQ_GPIO_PC_READY0	IRQ_GPIO11
-#define NANOENGINE_IRQ_GPIO_PC_READY1	IRQ_GPIO12
-#define NANOENGINE_IRQ_GPIO_PC_CD0	IRQ_GPIO13
-#define NANOENGINE_IRQ_GPIO_PC_CD1	IRQ_GPIO14
 
 /*
  * nanoEngine Memory Map:
-- 
2.1.0

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

* [PATCH 6/8] ARM: sa1100/nanoengine: move nanoengine header file
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
                                 ` (4 preceding siblings ...)
  2016-08-30 11:00               ` [PATCH 5/8] ARM: sa1100/nanoengine: remove redundant definitions Russell King
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 11:00               ` [PATCH 7/8] ARM: sa1100/neponset: remove neponset_ncr_* GPIO interfaces and header Russell King
  2016-08-30 11:01               ` [PATCH 8/8] ARM: sa1100: remove SA-1101 header file Russell King
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Nothing outside arch/arm/mach-sa1100 needs the nanoengine header file,
so move it into that directory.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/nanoengine.c                    | 2 +-
 arch/arm/mach-sa1100/{include/mach => }/nanoengine.h | 0
 arch/arm/mach-sa1100/pci-nanoengine.c                | 3 ++-
 3 files changed, 3 insertions(+), 2 deletions(-)
 rename arch/arm/mach-sa1100/{include/mach => }/nanoengine.h (100%)

diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index 4d35258a7b32..51e8ab94cd6d 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -28,10 +28,10 @@
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
-#include <mach/nanoengine.h>
 #include <mach/irqs.h>
 
 #include "generic.h"
+#include "nanoengine.h"
 
 /* Flash bank 0 */
 static struct mtd_partition nanoengine_partitions[] = {
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/nanoengine.h
similarity index 100%
rename from arch/arm/mach-sa1100/include/mach/nanoengine.h
rename to arch/arm/mach-sa1100/nanoengine.h
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
index d7ae8d50f6d8..81c5e7f68135 100644
--- a/arch/arm/mach-sa1100/pci-nanoengine.c
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -26,9 +26,10 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
-#include <mach/nanoengine.h>
 #include <mach/hardware.h>
 
+#include "nanoengine.h"
+
 static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus,
 					    unsigned int devfn, int where)
 {
-- 
2.1.0

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

* [PATCH 7/8] ARM: sa1100/neponset: remove neponset_ncr_* GPIO interfaces and header
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
                                 ` (5 preceding siblings ...)
  2016-08-30 11:00               ` [PATCH 6/8] ARM: sa1100/nanoengine: move nanoengine header file Russell King
@ 2016-08-30 11:00               ` Russell King
  2016-08-30 11:01               ` [PATCH 8/8] ARM: sa1100: remove SA-1101 header file Russell King
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:00 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the legacy neponset_ncr_*() interfaces and definitions, which
leaves the header empty apart from the header and footer.  Remove the
header as well.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/include/mach/neponset.h | 30 ----------------------------
 arch/arm/mach-sa1100/neponset.c              | 14 +------------
 2 files changed, 1 insertion(+), 43 deletions(-)
 delete mode 100644 arch/arm/mach-sa1100/include/mach/neponset.h

diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h
deleted file mode 100644
index 5516a52a329d..000000000000
--- a/arch/arm/mach-sa1100/include/mach/neponset.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/neponset.h
- *
- * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
- *
- * This file contains the hardware specific definitions for Assabet
- * Only include this file from SA1100-specific files.
- *
- * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
- *      Definitions for Neponset added.
- */
-#ifndef __ASM_ARCH_NEPONSET_H
-#define __ASM_ARCH_NEPONSET_H
-
-/*
- * Neponset definitions: 
- */
-#define NCR_GP01_OFF		(1<<0)
-#define NCR_TP_PWR_EN		(1<<1)
-#define NCR_MS_PWR_EN		(1<<2)
-#define NCR_ENET_OSC_EN		(1<<3)
-#define NCR_SPI_KB_WK_UP	(1<<4)
-#define NCR_A0VPP		(1<<5)
-#define NCR_A1VPP		(1<<6)
-
-void neponset_ncr_frob(unsigned int, unsigned int);
-#define neponset_ncr_set(v)	neponset_ncr_frob(0, v)
-#define neponset_ncr_clear(v)	neponset_ncr_frob(v, 0)
-
-#endif
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 700659cadebb..b3c2266b2302 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -25,7 +25,6 @@
 
 #include <mach/hardware.h>
 #include <mach/assabet.h>
-#include <mach/neponset.h>
 #include <mach/irqs.h>
 
 #define NEP_IRQ_SMC91X	0
@@ -48,6 +47,7 @@
 #define IRR_USAR	(1 << 1)
 #define IRR_SA1111	(1 << 2)
 
+#define NCR_GP01_OFF	BIT(0)
 #define NCR_NGPIO	7
 #define MDM_CTL0_NGPIO	4
 #define MDM_CTL1_NGPIO	6
@@ -124,18 +124,6 @@ static struct gpiod_lookup_table neponset_pcmcia_table = {
 
 static struct neponset_drvdata *nep;
 
-void neponset_ncr_frob(unsigned int mask, unsigned int val)
-{
-	struct neponset_drvdata *n = nep;
-	unsigned long m = mask, v = val;
-
-	if (nep)
-		n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
-	else
-		WARN(1, "nep unset\n");
-}
-EXPORT_SYMBOL(neponset_ncr_frob);
-
 /*
  * Install handler for Neponset IRQ.  Note that we have to loop here
  * since the ETHERNET and USAR IRQs are level based, and we need to
-- 
2.1.0

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

* [PATCH 8/8] ARM: sa1100: remove SA-1101 header file
  2016-08-30 10:59             ` [PATCH 0/8] SA11x0/PXA remainder & cleanups Russell King - ARM Linux
                                 ` (6 preceding siblings ...)
  2016-08-30 11:00               ` [PATCH 7/8] ARM: sa1100/neponset: remove neponset_ncr_* GPIO interfaces and header Russell King
@ 2016-08-30 11:01               ` Russell King
  7 siblings, 0 replies; 235+ messages in thread
From: Russell King @ 2016-08-30 11:01 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the completely unused SA-1101 header file.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-sa1100/include/mach/SA-1101.h  | 925 ---------------------------
 arch/arm/mach-sa1100/include/mach/hardware.h |   4 -
 2 files changed, 929 deletions(-)
 delete mode 100644 arch/arm/mach-sa1100/include/mach/SA-1101.h

diff --git a/arch/arm/mach-sa1100/include/mach/SA-1101.h b/arch/arm/mach-sa1100/include/mach/SA-1101.h
deleted file mode 100644
index 5d2ad7db991c..000000000000
--- a/arch/arm/mach-sa1100/include/mach/SA-1101.h
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * SA-1101.h
- *
- * Copyright (c) Peter Danielsson 1999
- *
- * Definition of constants related to the sa1101
- * support chip for the sa1100
- *
- */
-
-
-/* Be sure that virtual mapping is defined right */
-#ifndef __ASM_ARCH_HARDWARE_H
-#error You must include hardware.h not SA-1101.h
-#endif
-
-#ifndef SA1101_BASE
-#error You must define SA-1101 physical base address
-#endif
-
-#ifndef LANGUAGE
-# ifdef __ASSEMBLY__
-#  define LANGUAGE Assembly
-# else
-#  define LANGUAGE C
-# endif
-#endif
-
-/*
- * We have mapped the sa1101 depending on the value of SA1101_BASE.
- * It then appears from 0xf4000000.
- */
-
-#define SA1101_p2v( x )         ((x) - SA1101_BASE + 0xf4000000)
-#define SA1101_v2p( x )         ((x) - 0xf4000000  + SA1101_BASE)
-
-#ifndef SA1101_p2v
-#define SA1101_p2v(PhAdd)  (PhAdd)
-#endif
-
-#include <mach/bitfield.h>
-
-#define C               0
-#define Assembly        1
-
-
-/*
- * Memory map
- */
-
-#define __SHMEM_CONTROL0	0x00000000
-#define __SYSTEM_CONTROL1	0x00000400
-#define __ARBITER		0x00020000
-#define __SYSTEM_CONTROL2	0x00040000
-#define __SYSTEM_CONTROL3	0x00060000
-#define __PARALLEL_PORT		0x00080000
-#define __VIDMEM_CONTROL	0x00100000
-#define __UPDATE_FIFO		0x00120000
-#define __SHMEM_CONTROL1	0x00140000
-#define __INTERRUPT_CONTROL	0x00160000
-#define __USB_CONTROL		0x00180000
-#define __TRACK_INTERFACE	0x001a0000
-#define __MOUSE_INTERFACE	0x001b0000
-#define __KEYPAD_INTERFACE	0x001c0000
-#define __PCMCIA_INTERFACE	0x001e0000
-#define	__VGA_CONTROL		0x00200000
-#define __GPIO_INTERFACE	0x00300000
-
-/*
- * Macro that calculates real address for registers in the SA-1101
- */
-
-#define _SA1101( x )    ((x) + SA1101_BASE)
-
-/*
- * Interface and shared memory controller registers
- *
- * Registers
- *	SKCR		SA-1101 control register (read/write)
- *	SMCR		Shared Memory Controller Register
- *	SNPR		Snoop Register
- */
-
-#define _SKCR		_SA1101( 0x00000000 ) /* SA-1101 Control Reg. */
-#define _SMCR		_SA1101( 0x00140000 ) /* Shared Mem. Control Reg. */
-#define _SNPR		_SA1101( 0x00140400 ) /* Snoop Reg. */
-
-#if LANGUAGE == C
-#define SKCR		(*((volatile Word *) SA1101_p2v (_SKCR)))
-#define SMCR		(*((volatile Word *) SA1101_p2v (_SMCR)))
-#define SNPR		(*((volatile Word *) SA1101_p2v (_SNPR)))
-
-#define SKCR_PLLEn	  0x0001	  /* Enable On-Chip PLL */
-#define SKCR_BCLKEn	  0x0002	  /* Enables BCLK */
-#define SKCR_Sleep	  0x0004	  /* Sleep Mode */
-#define SKCR_IRefEn	  0x0008	  /* DAC Iref input enable */
-#define SKCR_VCOON	  0x0010	  /* VCO bias */
-#define SKCR_ScanTestEn	  0x0020	  /* Enables scan test */
-#define SKCR_ClockTestEn  0x0040	  /* Enables clock test */
-
-#define SMCR_DCAC	  Fld(2,0)	  /* Number of column address bits */
-#define SMCR_DRAC	  Fld(2,2)	  /* Number of row address bits */
-#define SMCR_ArbiterBias  0x0008	  /* favor video or USB */
-#define SMCR_TopVidMem	  Fld(4,5)	  /* Top 4 bits of vidmem addr. */
-
-#define SMCR_ColAdrBits( x )		  /* col. addr bits 8..11 */ \
-	(( (x) - 8 ) << FShft (SMCR_DCAC))
-#define SMCR_RowAdrBits( x )		  /* row addr bits 9..12 */\
-	(( (x) - 9 ) << FShft (SMCR_DRAC))
-
-#define SNPR_VFBstart	  Fld(12,0)	/* Video frame buffer addr */
-#define SNPR_VFBsize	  Fld(11,12)	/* Video frame buffer size */
-#define SNPR_WholeBank	  (1 << 23)	/* Whole bank bit */
-#define SNPR_BankSelect	  Fld(2,27)	/* Bank select */
-#define SNPR_SnoopEn	  (1 << 31)	/* Enable snoop operation */
-
-#define SNPR_Set_VFBsize( x )   /* set frame buffer size (in kb) */ \
-	( (x) << FShft (SNPR_VFBsize))
-#define SNPR_Select_Bank(x)     /* select bank 0 or 1 */  \
-	(( (x) + 1 ) << FShft (SNPR_BankSelect ))
-
-#endif /* LANGUAGE == C */
-
-/*
- * Video Memory Controller
- *
- * Registers
- *    VMCCR	Configuration register
- *    VMCAR	VMC address register
- *    VMCDR	VMC data register
- *
- */
-
-#define _VMCCR		_SA1101( 0x00100000 )	/* Configuration register */
-#define _VMCAR		_SA1101( 0x00101000 )	/* VMC address register */
-#define _VMCDR		_SA1101( 0x00101400 )	/* VMC data register */
-
-#if LANGUAGE == C
-#define VMCCR		(*((volatile Word *) SA1101_p2v (_VMCCR)))
-#define VMCAR		(*((volatile Word *) SA1101_p2v (_VMCAR)))
-#define VMCDR		(*((volatile Word *) SA1101_p2v (_VMCDR)))
-
-#define VMCCR_RefreshEn	    0x0000	  /* Enable memory refresh */
-#define VMCCR_Config	    0x0001	  /* DRAM size */
-#define VMCCR_RefPeriod	    Fld(2,3)	  /* Refresh period */
-#define VMCCR_StaleDataWait Fld(4,5)	  /* Stale FIFO data timeout counter */
-#define VMCCR_SleepState    (1<<9)	  /* State of interface pins in sleep*/
-#define VMCCR_RefTest	    (1<<10)	  /* refresh test */
-#define VMCCR_RefLow	    Fld(6,11)	  /* refresh low counter */
-#define VMCCR_RefHigh	    Fld(7,17)	  /* refresh high counter */
-#define VMCCR_SDTCTest	    Fld(7,24)	  /* stale data timeout counter */
-#define VMCCR_ForceSelfRef  (1<<31)	  /* Force self refresh */
-
-#endif LANGUAGE == C
-
-
-/* Update FIFO
- *
- * Registers
- *    UFCR	Update FIFO Control Register
- *    UFSR	Update FIFO Status Register
- *    UFLVLR	update FIFO level register
- *    UFDR	update FIFO data register
- */
-
-#define _UFCR	_SA1101(0x00120000)   /* Update FIFO Control Reg. */
-#define _UFSR	_SA1101(0x00120400)   /* Update FIFO Status Reg. */	
-#define _UFLVLR	_SA1101(0x00120800)   /* Update FIFO level reg. */
-#define _UFDR	_SA1101(0x00120c00)   /* Update FIFO data reg. */
-
-#if LANGUAGE == C
-
-#define UFCR 	(*((volatile Word *) SA1101_p2v (_UFCR)))
-#define UFSR	(*((volatile Word *) SA1101_p2v (_UFSR)))
-#define UFLVLR	(*((volatile Word *) SA1101_p2v (_UFLVLR))) 
-#define UFDR	(*((volatile Word *) SA1101_p2v (_UFDR)))
-
-
-#define UFCR_FifoThreshhold	Fld(7,0)	/* Level for FifoGTn flag */
-
-#define UFSR_FifoGTnFlag	0x01		/* FifoGTn flag */#define UFSR_FifoEmpty		0x80		/* FIFO is empty */
-
-#endif /* LANGUAGE == C */
-
-/* System Controller
- *
- * Registers
- *    SKPCR	Power Control Register
- *    SKCDR	Clock Divider Register
- *    DACDR1	DAC1 Data register
- *    DACDR2	DAC2 Data register
- */
-
-#define _SKPCR		_SA1101(0x00000400)
-#define _SKCDR		_SA1101(0x00040000)
-#define _DACDR1		_SA1101(0x00060000)
-#define _DACDR2		_SA1101(0x00060400)
-
-#if LANGUAGE == C
-#define SKPCR 	(*((volatile Word *) SA1101_p2v (_SKPCR)))
-#define SKCDR	(*((volatile Word *) SA1101_p2v (_SKCDR)))
-#define DACDR1	(*((volatile Word *) SA1101_p2v (_DACDR1)))
-#define DACDR2	(*((volatile Word *) SA1101_p2v (_DACDR2)))
-
-#define SKPCR_UCLKEn	     0x01    /* USB Enable */
-#define SKPCR_PCLKEn	     0x02    /* PS/2 Enable */
-#define SKPCR_ICLKEn	     0x04    /* Interrupt Controller Enable */
-#define SKPCR_VCLKEn	     0x08    /* Video Controller Enable */
-#define SKPCR_PICLKEn	     0x10    /* parallel port Enable */
-#define SKPCR_DCLKEn	     0x20    /* DACs Enable */
-#define SKPCR_nKPADEn	     0x40    /* Multiplexer */
-
-#define SKCDR_PLLMul	     Fld(7,0)	/* PLL Multiplier */
-#define SKCDR_VCLKEn	     Fld(2,7)	/* Video controller clock divider */
-#define SKDCR_BCLKEn	     (1<<9)	/* BCLK Divider */
-#define SKDCR_UTESTCLKEn     (1<<10)	/* Route USB clock during test mode */
-#define SKDCR_DivRValue	     Fld(6,11)	/* Input clock divider for PLL */
-#define SKDCR_DivNValue	     Fld(5,17)	/* Output clock divider for PLL */
-#define SKDCR_PLLRSH	     Fld(3,22)	/* PLL bandwidth control */
-#define SKDCR_ChargePump     (1<<25)	/* Charge pump control */
-#define SKDCR_ClkTestMode    (1<<26)	/* Clock output test mode */
-#define SKDCR_ClkTestEn	     (1<<27)	/* Test clock generator */
-#define SKDCR_ClkJitterCntl  Fld(3,28)	/* video clock jitter compensation */
-
-#define DACDR_DACCount	     Fld(8,0)	/* Count value */
-#define DACDR1_DACCount	     DACDR_DACCount
-#define DACDR2_DACCount	     DACDR_DACCount
-
-#endif /* LANGUAGE == C */
-
-/*
- * Parallel Port Interface
- *
- * Registers
- *    IEEE_Config	IEEE mode selection and programmable attributes
- *    IEEE_Control	Controls the states of IEEE port control outputs
- *    IEEE_Data		Forward transfer data register
- *    IEEE_Addr		Forward transfer address register
- *    IEEE_Status	Port IO signal status register
- *    IEEE_IntStatus	Port interrupts status register
- *    IEEE_FifoLevels   Rx and Tx FIFO interrupt generation levels
- *    IEEE_InitTime	Forward timeout counter initial value
- *    IEEE_TimerStatus	Forward timeout counter current value
- *    IEEE_FifoReset	Reset forward transfer FIFO
- *    IEEE_ReloadValue	Counter reload value
- *    IEEE_TestControl	Control testmode
- *    IEEE_TestDataIn	Test data register
- *    IEEE_TestDataInEn	Enable test data
- *    IEEE_TestCtrlIn	Test control signals
- *    IEEE_TestCtrlInEn	Enable test control signals
- *    IEEE_TestDataStat	Current data bus value
- *
- */
-
-/*
- * The control registers are defined as offsets from a base address 
- */
- 
-#define _IEEE( x ) _SA1101( (x) + __PARALLEL_PORT )
-
-#define _IEEE_Config	    _IEEE( 0x0000 )
-#define _IEEE_Control	    _IEEE( 0x0400 )
-#define _IEEE_Data	    _IEEE( 0x4000 )
-#define _IEEE_Addr	    _IEEE( 0x0800 )
-#define _IEEE_Status	    _IEEE( 0x0c00 )
-#define _IEEE_IntStatus	    _IEEE( 0x1000 )
-#define _IEEE_FifoLevels    _IEEE( 0x1400 )
-#define _IEEE_InitTime	    _IEEE( 0x1800 )
-#define _IEEE_TimerStatus   _IEEE( 0x1c00 )
-#define _IEEE_FifoReset	    _IEEE( 0x2000 )
-#define _IEEE_ReloadValue   _IEEE( 0x3c00 )
-#define _IEEE_TestControl   _IEEE( 0x2400 )
-#define _IEEE_TestDataIn    _IEEE( 0x2800 )
-#define _IEEE_TestDataInEn  _IEEE( 0x2c00 )
-#define _IEEE_TestCtrlIn    _IEEE( 0x3000 )
-#define _IEEE_TestCtrlInEn  _IEEE( 0x3400 )
-#define _IEEE_TestDataStat  _IEEE( 0x3800 )
- 
-
-#if LANGUAGE == C
-#define IEEE_Config	    (*((volatile Word *) SA1101_p2v (_IEEE_Config)))
-#define IEEE_Control	    (*((volatile Word *) SA1101_p2v (_IEEE_Control)))
-#define IEEE_Data	    (*((volatile Word *) SA1101_p2v (_IEEE_Data)))
-#define IEEE_Addr	    (*((volatile Word *) SA1101_p2v (_IEEE_Addr)))
-#define IEEE_Status	    (*((volatile Word *) SA1101_p2v (_IEEE_Status)))
-#define IEEE_IntStatus	    (*((volatile Word *) SA1101_p2v (_IEEE_IntStatus)))
-#define IEEE_FifoLevels	    (*((volatile Word *) SA1101_p2v (_IEEE_FifoLevels)))
-#define IEEE_InitTime	    (*((volatile Word *) SA1101_p2v (_IEEE_InitTime)))
-#define IEEE_TimerStatus    (*((volatile Word *) SA1101_p2v (_IEEE_TimerStatus)))
-#define IEEE_FifoReset	    (*((volatile Word *) SA1101_p2v (_IEEE_FifoReset)))
-#define IEEE_ReloadValue    (*((volatile Word *) SA1101_p2v (_IEEE_ReloadValue)))
-#define IEEE_TestControl    (*((volatile Word *) SA1101_p2v (_IEEE_TestControl)))
-#define IEEE_TestDataIn     (*((volatile Word *) SA1101_p2v (_IEEE_TestDataIn)))
-#define IEEE_TestDataInEn   (*((volatile Word *) SA1101_p2v (_IEEE_TestDataInEn)))
-#define IEEE_TestCtrlIn     (*((volatile Word *) SA1101_p2v (_IEEE_TestCtrlIn)))
-#define IEEE_TestCtrlInEn   (*((volatile Word *) SA1101_p2v (_IEEE_TestCtrlInEn)))
-#define IEEE_TestDataStat   (*((volatile Word *) SA1101_p2v (_IEEE_TestDataStat)))
-
-
-#define IEEE_Config_M	    Fld(3,0)	 /* Mode select */
-#define IEEE_Config_D	    0x04	 /* FIFO access enable */
-#define IEEE_Config_B	    0x08	 /* 9-bit word enable */
-#define IEEE_Config_T	    0x10	 /* Data transfer enable */
-#define IEEE_Config_A	    0x20	 /* Data transfer direction */
-#define IEEE_Config_E	    0x40	 /* Timer enable */
-#define IEEE_Control_A	    0x08	 /* AutoFd output */
-#define IEEE_Control_E	    0x04	 /* Selectin output */
-#define IEEE_Control_T	    0x02	 /* Strobe output */
-#define IEEE_Control_I	    0x01	 /* Port init output */
-#define IEEE_Data_C	    (1<<31)	 /* Byte count */
-#define IEEE_Data_Db	    Fld(9,16)	 /* Data byte 2 */
-#define IEEE_Data_Da	    Fld(9,0)	 /* Data byte 1 */
-#define IEEE_Addr_A	    Fld(8,0)	 /* forward address transfer byte */
-#define IEEE_Status_A	    0x0100	 /* nAutoFd port output status */
-#define IEEE_Status_E	    0x0080	 /* nSelectIn port output status */
-#define IEEE_Status_T	    0x0040	 /* nStrobe port output status */
-#define IEEE_Status_I	    0x0020	 /* nInit port output status */
-#define IEEE_Status_B	    0x0010	 /* Busy port inout status */
-#define IEEE_Status_S	    0x0008	 /* Select port input status */
-#define IEEE_Status_K	    0x0004	 /* nAck port input status */
-#define IEEE_Status_F	    0x0002	 /* nFault port input status */
-#define IEEE_Status_R	    0x0001	 /* pError port input status */
-
-#define IEEE_IntStatus_IntReqDat	 0x0100
-#define IEEE_IntStatus_IntReqEmp	 0x0080
-#define IEEE_IntStatus_IntReqInt	 0x0040
-#define IEEE_IntStatus_IntReqRav	 0x0020
-#define IEEE_IntStatus_IntReqTim	 0x0010
-#define IEEE_IntStatus_RevAddrComp	 0x0008
-#define IEEE_IntStatus_RevDataComp	 0x0004
-#define IEEE_IntStatus_FwdAddrComp	 0x0002
-#define IEEE_IntStatus_FwdDataComp	 0x0001
-#define IEEE_FifoLevels_RevFifoLevel	 2
-#define IEEE_FifoLevels_FwdFifoLevel	 1
-#define IEEE_InitTime_TimValInit	 Fld(22,0)
-#define IEEE_TimerStatus_TimValStat	 Fld(22,0)
-#define IEEE_ReloadValue_Reload		 Fld(4,0)
-
-#define IEEE_TestControl_RegClk		 0x04
-#define IEEE_TestControl_ClockSelect	 Fld(2,1)
-#define IEEE_TestControl_TimerTestModeEn 0x01
-#define IEEE_TestCtrlIn_PError		 0x10
-#define IEEE_TestCtrlIn_nFault		 0x08
-#define IEEE_TestCtrlIn_nAck		 0x04
-#define IEEE_TestCtrlIn_PSel		 0x02
-#define IEEE_TestCtrlIn_Busy		 0x01
-
-#endif /* LANGUAGE == C */
-
-/*
- * VGA Controller
- *
- * Registers
- *    VideoControl	Video Control Register
- *    VgaTiming0	VGA Timing Register 0
- *    VgaTiming1	VGA Timing Register 1
- *    VgaTiming2	VGA Timing Register 2
- *    VgaTiming3	VGA Timing Register 3
- *    VgaBorder		VGA Border Color Register
- *    VgaDBAR		VGADMA Base Address Register
- *    VgaDCAR		VGADMA Channel Current Address Register
- *    VgaStatus		VGA Status Register
- *    VgaInterruptMask	VGA Interrupt Mask Register
- *    VgaPalette	VGA Palette Registers
- *    DacControl	DAC Control Register
- *    VgaTest		VGA Controller Test Register
- */
-
-#define _VGA( x )	_SA1101( ( x ) + __VGA_CONTROL )
-
-#define _VideoControl	    _VGA( 0x0000 )
-#define _VgaTiming0	    _VGA( 0x0400 )
-#define _VgaTiming1	    _VGA( 0x0800 )
-#define _VgaTiming2	    _VGA( 0x0c00 )
-#define _VgaTiming3	    _VGA( 0x1000 )
-#define _VgaBorder	    _VGA( 0x1400 )
-#define _VgaDBAR	    _VGA( 0x1800 )
-#define _VgaDCAR	    _VGA( 0x1c00 )
-#define _VgaStatus	    _VGA( 0x2000 )
-#define _VgaInterruptMask   _VGA( 0x2400 )
-#define _VgaPalette	    _VGA( 0x40000 )
-#define _DacControl	    _VGA( 0x3000 )
-#define _VgaTest	    _VGA( 0x2c00 )
-
-#if (LANGUAGE == C)
-#define VideoControl   (*((volatile Word *) SA1101_p2v (_VideoControl)))
-#define VgaTiming0     (*((volatile Word *) SA1101_p2v (_VgaTiming0)))
-#define VgaTiming1     (*((volatile Word *) SA1101_p2v (_VgaTiming1)))
-#define VgaTiming2     (*((volatile Word *) SA1101_p2v (_VgaTiming2)))
-#define VgaTiming3     (*((volatile Word *) SA1101_p2v (_VgaTiming3)))
-#define VgaBorder      (*((volatile Word *) SA1101_p2v (_VgaBorder)))
-#define VgaDBAR	       (*((volatile Word *) SA1101_p2v (_VgaDBAR)))
-#define VgaDCAR	       (*((volatile Word *) SA1101_p2v (_VgaDCAR)))
-#define VgaStatus      (*((volatile Word *) SA1101_p2v (_VgaStatus)))
-#define VgaInterruptMask (*((volatile Word *) SA1101_p2v (_VgaInterruptMask)))
-#define VgaPalette     (*((volatile Word *) SA1101_p2v (_VgaPalette)))
-#define DacControl     (*((volatile Word *) SA1101_p2v (_DacControl)))
-#define VgaTest        (*((volatile Word *) SA1101_p2v (_VgaTest)))
-
-#define VideoControl_VgaEn    0x00000000
-#define VideoControl_BGR      0x00000001
-#define VideoControl_VCompVal Fld(2,2)
-#define VideoControl_VgaReq   Fld(4,4)
-#define VideoControl_VBurstL  Fld(4,8)
-#define VideoControl_VMode    (1<<12)
-#define VideoControl_PalRead  (1<<13)
-
-#define VgaTiming0_PPL	      Fld(6,2)
-#define VgaTiming0_HSW	      Fld(8,8)
-#define VgaTiming0_HFP	      Fld(8,16)
-#define VgaTiming0_HBP	      Fld(8,24)
-
-#define VgaTiming1_LPS	      Fld(10,0)
-#define VgaTiming1_VSW	      Fld(6,10)
-#define VgaTiming1_VFP	      Fld(8,16)
-#define VgaTiming1_VBP	      Fld(8,24)
-
-#define VgaTiming2_IVS	      0x01
-#define VgaTiming2_IHS	      0x02
-#define VgaTiming2_CVS	      0x04
-#define VgaTiming2_CHS	      0x08
-
-#define VgaTiming3_HBS	      Fld(8,0)
-#define VgaTiming3_HBE	      Fld(8,8)
-#define VgaTiming3_VBS	      Fld(8,16)
-#define VgaTiming3_VBE	      Fld(8,24)
-
-#define VgaBorder_BCOL	      Fld(24,0)
-
-#define VgaStatus_VFUF	      0x01
-#define VgaStatus_VNext	      0x02
-#define VgaStatus_VComp	      0x04
-
-#define VgaInterruptMask_VFUFMask   0x00
-#define VgaInterruptMask_VNextMask  0x01
-#define VgaInterruptMask_VCompMask  0x02
-
-#define VgaPalette_R	      Fld(8,0)
-#define VgaPalette_G	      Fld(8,8)
-#define VgaPalette_B	      Fld(8,16)
-
-#define DacControl_DACON      0x0001
-#define DacControl_COMPON     0x0002
-#define DacControl_PEDON      0x0004
-#define DacControl_RTrim      Fld(5,4)
-#define DacControl_GTrim      Fld(5,9)
-#define DacControl_BTrim      Fld(5,14)
-
-#define VgaTest_TDAC	      0x00
-#define VgaTest_Datatest      Fld(4,1)
-#define VgaTest_DACTESTDAC    0x10
-#define VgaTest_DACTESTOUT    Fld(3,5)
-
-#endif /* LANGUAGE == C */
-
-/*
- * USB Host Interface Controller
- *
- * Registers
- *    Revision
- *    Control
- *    CommandStatus
- *    InterruptStatus
- *    InterruptEnable
- *    HCCA
- *    PeriodCurrentED
- *    ControlHeadED
- *    BulkHeadED
- *    BulkCurrentED
- *    DoneHead
- *    FmInterval
- *    FmRemaining
- *    FmNumber
- *    PeriodicStart
- *    LSThreshold
- *    RhDescriptorA
- *    RhDescriptorB
- *    RhStatus
- *    RhPortStatus
- *    USBStatus
- *    USBReset
- *    USTAR
- *    USWER
- *    USRFR
- *    USNFR
- *    USTCSR
- *    USSR
- *    
- */
-
-#define _USB( x )	_SA1101( ( x ) + __USB_CONTROL )
-
-
-#define _Revision	  _USB( 0x0000 )
-#define _Control	  _USB( 0x0888 )
-#define _CommandStatus	  _USB( 0x0c00 )
-#define _InterruptStatus  _USB( 0x1000 )
-#define _InterruptEnable  _USB( 0x1400 )
-#define _HCCA		  _USB( 0x1800 )
-#define _PeriodCurrentED  _USB( 0x1c00 )
-#define _ControlHeadED	  _USB( 0x2000 )
-#define _BulkHeadED	  _USB( 0x2800 )
-#define _BulkCurrentED	  _USB( 0x2c00 )
-#define _DoneHead	  _USB( 0x3000 )
-#define _FmInterval	  _USB( 0x3400 )
-#define _FmRemaining	  _USB( 0x3800 )
-#define _FmNumber	  _USB( 0x3c00 )
-#define _PeriodicStart	  _USB( 0x4000 )
-#define _LSThreshold	  _USB( 0x4400 )
-#define _RhDescriptorA	  _USB( 0x4800 )
-#define _RhDescriptorB	  _USB( 0x4c00 )
-#define _RhStatus	  _USB( 0x5000 )
-#define _RhPortStatus	  _USB( 0x5400 )
-#define _USBStatus	  _USB( 0x11800 )
-#define _USBReset	  _USB( 0x11c00 )
-
-#define _USTAR		  _USB( 0x10400 )
-#define _USWER		  _USB( 0x10800 )
-#define _USRFR		  _USB( 0x10c00 )
-#define _USNFR		  _USB( 0x11000 )
-#define _USTCSR		  _USB( 0x11400 )
-#define _USSR		  _USB( 0x11800 )
-
-
-#if (LANGUAGE == C)
-
-#define Revision	(*((volatile Word *) SA1101_p2v (_Revision)))
-#define Control		(*((volatile Word *) SA1101_p2v (_Control)))
-#define CommandStatus	(*((volatile Word *) SA1101_p2v (_CommandStatus)))
-#define InterruptStatus	(*((volatile Word *) SA1101_p2v (_InterruptStatus)))
-#define InterruptEnable	(*((volatile Word *) SA1101_p2v (_InterruptEnable)))
-#define HCCA		(*((volatile Word *) SA1101_p2v (_HCCA)))
-#define PeriodCurrentED	(*((volatile Word *) SA1101_p2v (_PeriodCurrentED)))
-#define ControlHeadED	(*((volatile Word *) SA1101_p2v (_ControlHeadED)))
-#define BulkHeadED	(*((volatile Word *) SA1101_p2v (_BulkHeadED)))
-#define BulkCurrentED	(*((volatile Word *) SA1101_p2v (_BulkCurrentED)))
-#define DoneHead	(*((volatile Word *) SA1101_p2v (_DoneHead)))
-#define FmInterval	(*((volatile Word *) SA1101_p2v (_FmInterval)))
-#define FmRemaining	(*((volatile Word *) SA1101_p2v (_FmRemaining)))
-#define FmNumber	(*((volatile Word *) SA1101_p2v (_FmNumber)))
-#define PeriodicStart	(*((volatile Word *) SA1101_p2v (_PeriodicStart)))
-#define LSThreshold	(*((volatile Word *) SA1101_p2v (_LSThreshold)))
-#define RhDescriptorA	(*((volatile Word *) SA1101_p2v (_RhDescriptorA)))
-#define RhDescriptorB	(*((volatile Word *) SA1101_p2v (_RhDescriptorB)))
-#define RhStatus	(*((volatile Word *) SA1101_p2v (_RhStatus)))
-#define RhPortStatus	(*((volatile Word *) SA1101_p2v (_RhPortStatus)))
-#define USBStatus	(*((volatile Word *) SA1101_p2v (_USBStatus)))
-#define USBReset	(*((volatile Word *) SA1101_p2v (_USBReset)))
-#define USTAR		(*((volatile Word *) SA1101_p2v (_USTAR)))
-#define USWER		(*((volatile Word *) SA1101_p2v (_USWER)))
-#define USRFR		(*((volatile Word *) SA1101_p2v (_USRFR)))
-#define USNFR		(*((volatile Word *) SA1101_p2v (_USNFR)))
-#define USTCSR		(*((volatile Word *) SA1101_p2v (_USTCSR)))
-#define USSR		(*((volatile Word *) SA1101_p2v (_USSR)))
-
-
-#define USBStatus_IrqHciRmtWkp	     (1<<7)
-#define USBStatus_IrqHciBuffAcc	     (1<<8)
-#define USBStatus_nIrqHciM	     (1<<9)
-#define USBStatus_nHciMFClr	     (1<<10)
-
-#define USBReset_ForceIfReset	     0x01
-#define USBReset_ForceHcReset	     0x02
-#define USBReset_ClkGenReset	     0x04
-
-#define USTCR_RdBstCntrl	     Fld(3,0)
-#define USTCR_ByteEnable	     Fld(4,3)
-#define USTCR_WriteEn		     (1<<7)
-#define USTCR_FifoCir		     (1<<8)
-#define USTCR_TestXferSel	     (1<<9)
-#define USTCR_FifoCirAtEnd	     (1<<10)
-#define USTCR_nSimScaleDownClk	     (1<<11)
-
-#define USSR_nAppMDEmpty	     0x01
-#define USSR_nAppMDFirst	     0x02
-#define USSR_nAppMDLast		     0x04
-#define USSR_nAppMDFull		     0x08
-#define USSR_nAppMAFull		     0x10
-#define USSR_XferReq		     0x20
-#define USSR_XferEnd		     0x40
-
-#endif /* LANGUAGE == C */
-
-
-/*
- * Interrupt Controller
- *
- * Registers
- *    INTTEST0		Test register 0
- *    INTTEST1		Test register 1
- *    INTENABLE0	Interrupt Enable register 0
- *    INTENABLE1	Interrupt Enable register 1
- *    INTPOL0		Interrupt Polarity selection 0
- *    INTPOL1		Interrupt Polarity selection 1
- *    INTTSTSEL		Interrupt source selection
- *    INTSTATCLR0	Interrupt Status 0
- *    INTSTATCLR1	Interrupt Status 1
- *    INTSET0		Interrupt Set 0
- *    INTSET1		Interrupt Set 1
- */
-
-#define _INT( x )	_SA1101( ( x ) + __INTERRUPT_CONTROL)
-
-#define _INTTEST0	_INT( 0x1000 )
-#define _INTTEST1	_INT( 0x1400 )
-#define _INTENABLE0	_INT( 0x2000 )
-#define _INTENABLE1	_INT( 0x2400 )
-#define _INTPOL0	_INT( 0x3000 )
-#define _INTPOL1	_INT( 0x3400 )
-#define _INTTSTSEL     	_INT( 0x5000 )
-#define _INTSTATCLR0	_INT( 0x6000 )
-#define _INTSTATCLR1	_INT( 0x6400 )
-#define _INTSET0	_INT( 0x7000 )
-#define _INTSET1	_INT( 0x7400 )
-
-#if ( LANGUAGE == C )
-#define INTTEST0	(*((volatile Word *) SA1101_p2v (_INTTEST0)))
-#define INTTEST1	(*((volatile Word *) SA1101_p2v (_INTTEST1)))
-#define INTENABLE0	(*((volatile Word *) SA1101_p2v (_INTENABLE0)))
-#define INTENABLE1	(*((volatile Word *) SA1101_p2v (_INTENABLE1)))
-#define INTPOL0		(*((volatile Word *) SA1101_p2v (_INTPOL0)))
-#define INTPOL1		(*((volatile Word *) SA1101_p2v (_INTPOL1)))
-#define INTTSTSEL	(*((volatile Word *) SA1101_p2v (_INTTSTSEL)))
-#define INTSTATCLR0	(*((volatile Word *) SA1101_p2v (_INTSTATCLR0)))
-#define INTSTATCLR1	(*((volatile Word *) SA1101_p2v (_INTSTATCLR1)))
-#define INTSET0		(*((volatile Word *) SA1101_p2v (_INTSET0)))
-#define INTSET1		(*((volatile Word *) SA1101_p2v (_INTSET1)))
-
-#endif /* LANGUAGE == C */
-
-/*
- * PS/2 Trackpad and Mouse Interfaces
- *
- * Registers   (prefix kbd applies to trackpad interface, mse to mouse)
- *    KBDCR		Control Register
- *    KBDSTAT		Status Register
- *    KBDDATA		Transmit/Receive Data register
- *    KBDCLKDIV		Clock Division Register
- *    KBDPRECNT		Clock Precount Register
- *    KBDTEST1		Test register 1
- *    KBDTEST2		Test register 2
- *    KBDTEST3		Test register 3
- *    KBDTEST4		Test register 4
- *    MSECR	
- *    MSESTAT
- *    MSEDATA
- *    MSECLKDIV
- *    MSEPRECNT
- *    MSETEST1
- *    MSETEST2
- *    MSETEST3
- *    MSETEST4
- *     
- */
-
-#define _KBD( x )	_SA1101( ( x ) + __TRACK_INTERFACE )
-#define _MSE( x )	_SA1101( ( x ) + __MOUSE_INTERFACE )
-
-#define _KBDCR		_KBD( 0x0000 )
-#define _KBDSTAT	_KBD( 0x0400 )
-#define _KBDDATA	_KBD( 0x0800 )
-#define _KBDCLKDIV	_KBD( 0x0c00 )
-#define _KBDPRECNT	_KBD( 0x1000 )
-#define	_KBDTEST1	_KBD( 0x2000 )
-#define _KBDTEST2	_KBD( 0x2400 )
-#define _KBDTEST3	_KBD( 0x2800 )
-#define _KBDTEST4	_KBD( 0x2c00 )
-#define _MSECR		_MSE( 0x0000 )
-#define _MSESTAT	_MSE( 0x0400 )
-#define _MSEDATA	_MSE( 0x0800 )
-#define _MSECLKDIV	_MSE( 0x0c00 )
-#define _MSEPRECNT	_MSE( 0x1000 )
-#define	_MSETEST1	_MSE( 0x2000 )
-#define _MSETEST2	_MSE( 0x2400 )
-#define _MSETEST3	_MSE( 0x2800 )
-#define _MSETEST4	_MSE( 0x2c00 )
-
-#if ( LANGUAGE == C )
-
-#define KBDCR	    (*((volatile Word *) SA1101_p2v (_KBDCR)))
-#define KBDSTAT	    (*((volatile Word *) SA1101_p2v (_KBDSTAT)))
-#define KBDDATA	    (*((volatile Word *) SA1101_p2v (_KBDDATA)))
-#define KBDCLKDIV   (*((volatile Word *) SA1101_p2v (_KBDCLKDIV)))
-#define KBDPRECNT   (*((volatile Word *) SA1101_p2v (_KBDPRECNT)))
-#define KBDTEST1    (*((volatile Word *) SA1101_p2v (_KBDTEST1)))
-#define KBDTEST2    (*((volatile Word *) SA1101_p2v (_KBDTEST2)))
-#define KBDTEST3    (*((volatile Word *) SA1101_p2v (_KBDTEST3)))
-#define KBDTEST4    (*((volatile Word *) SA1101_p2v (_KBDTEST4)))
-#define MSECR	    (*((volatile Word *) SA1101_p2v (_MSECR)))
-#define MSESTAT	    (*((volatile Word *) SA1101_p2v (_MSESTAT)))
-#define MSEDATA	    (*((volatile Word *) SA1101_p2v (_MSEDATA)))
-#define MSECLKDIV   (*((volatile Word *) SA1101_p2v (_MSECLKDIV)))
-#define MSEPRECNT   (*((volatile Word *) SA1101_p2v (_MSEPRECNT)))
-#define MSETEST1    (*((volatile Word *) SA1101_p2v (_MSETEST1)))
-#define MSETEST2    (*((volatile Word *) SA1101_p2v (_MSETEST2)))
-#define MSETEST3    (*((volatile Word *) SA1101_p2v (_MSETEST3)))
-#define MSETEST4    (*((volatile Word *) SA1101_p2v (_MSETEST4)))
-
-
-#define KBDCR_ENA		 0x08
-#define KBDCR_FKD		 0x02
-#define KBDCR_FKC		 0x01
-
-#define KBDSTAT_TXE		 0x80
-#define KBDSTAT_TXB		 0x40
-#define KBDSTAT_RXF		 0x20
-#define KBDSTAT_RXB		 0x10
-#define KBDSTAT_ENA		 0x08
-#define KBDSTAT_RXP		 0x04
-#define KBDSTAT_KBD		 0x02
-#define KBDSTAT_KBC		 0x01
-
-#define KBDCLKDIV_DivVal	 Fld(4,0)
-
-#define MSECR_ENA		 0x08
-#define MSECR_FKD		 0x02
-#define MSECR_FKC		 0x01
-
-#define MSESTAT_TXE		 0x80
-#define MSESTAT_TXB		 0x40
-#define MSESTAT_RXF		 0x20
-#define MSESTAT_RXB		 0x10
-#define MSESTAT_ENA		 0x08
-#define MSESTAT_RXP		 0x04	
-#define MSESTAT_MSD		 0x02
-#define MSESTAT_MSC		 0x01
-
-#define MSECLKDIV_DivVal	 Fld(4,0)
-
-#define KBDTEST1_CD		 0x80
-#define KBDTEST1_RC1		 0x40
-#define KBDTEST1_MC		 0x20
-#define KBDTEST1_C		 Fld(2,3)
-#define KBDTEST1_T2		 0x40
-#define KBDTEST1_T1		 0x20
-#define KBDTEST1_T0		 0x10
-#define KBDTEST2_TICBnRES	 0x08
-#define KBDTEST2_RKC		 0x04
-#define KBDTEST2_RKD		 0x02
-#define KBDTEST2_SEL		 0x01
-#define KBDTEST3_ms_16		 0x80
-#define KBDTEST3_us_64		 0x40
-#define KBDTEST3_us_16		 0x20
-#define KBDTEST3_DIV8		 0x10
-#define KBDTEST3_DIn		 0x08
-#define KBDTEST3_CIn		 0x04
-#define KBDTEST3_KD		 0x02
-#define KBDTEST3_KC		 0x01
-#define KBDTEST4_BC12		 0x80
-#define KBDTEST4_BC11		 0x40
-#define KBDTEST4_TRES		 0x20
-#define KBDTEST4_CLKOE		 0x10
-#define KBDTEST4_CRES		 0x08
-#define KBDTEST4_RXB		 0x04
-#define KBDTEST4_TXB		 0x02
-#define KBDTEST4_SRX		 0x01
-
-#define MSETEST1_CD		 0x80
-#define MSETEST1_RC1		 0x40
-#define MSETEST1_MC		 0x20
-#define MSETEST1_C		 Fld(2,3)
-#define MSETEST1_T2		 0x40
-#define MSETEST1_T1		 0x20
-#define MSETEST1_T0		 0x10
-#define MSETEST2_TICBnRES	 0x08
-#define MSETEST2_RKC		 0x04
-#define MSETEST2_RKD		 0x02
-#define MSETEST2_SEL		 0x01
-#define MSETEST3_ms_16		 0x80
-#define MSETEST3_us_64		 0x40
-#define MSETEST3_us_16		 0x20
-#define MSETEST3_DIV8		 0x10
-#define MSETEST3_DIn		 0x08
-#define MSETEST3_CIn		 0x04
-#define MSETEST3_KD		 0x02
-#define MSETEST3_KC		 0x01
-#define MSETEST4_BC12		 0x80
-#define MSETEST4_BC11		 0x40
-#define MSETEST4_TRES		 0x20
-#define MSETEST4_CLKOE		 0x10
-#define MSETEST4_CRES		 0x08
-#define MSETEST4_RXB		 0x04
-#define MSETEST4_TXB		 0x02
-#define MSETEST4_SRX		 0x01
-
-#endif  /* LANGUAGE == C */
-
-
-/*
- * General-Purpose I/O Interface
- *
- * Registers
- *    PADWR	Port A Data Write Register
- *    PBDWR	Port B Data Write Register
- *    PADRR	Port A Data Read Register
- *    PBDRR	Port B Data Read Register
- *    PADDR	Port A Data Direction Register
- *    PBDDR	Port B Data Direction Register
- *    PASSR	Port A Sleep State Register
- *    PBSSR	Port B Sleep State Register
- *
- */
-
-#define _PIO( x )      _SA1101( ( x ) + __GPIO_INTERFACE )
-
-#define _PADWR	       _PIO( 0x0000 )
-#define _PBDWR	       _PIO( 0x0400 )
-#define _PADRR	       _PIO( 0x0000 )
-#define _PBDRR	       _PIO( 0x0400 )
-#define _PADDR	       _PIO( 0x0800 )
-#define _PBDDR	       _PIO( 0x0c00 )
-#define _PASSR	       _PIO( 0x1000 )
-#define _PBSSR	       _PIO( 0x1400 )
-
-
-#if ( LANGUAGE == C )
-
-
-#define PADWR	    (*((volatile Word *) SA1101_p2v (_PADWR)))
-#define PBDWR	    (*((volatile Word *) SA1101_p2v (_PBDWR)))
-#define PADRR	    (*((volatile Word *) SA1101_p2v (_PADRR)))
-#define PBDRR	    (*((volatile Word *) SA1101_p2v (_PBDRR)))
-#define PADDR	    (*((volatile Word *) SA1101_p2v (_PADDR)))
-#define PBDDR	    (*((volatile Word *) SA1101_p2v (_PBDDR)))
-#define PASSR	    (*((volatile Word *) SA1101_p2v (_PASSR)))
-#define PBSSR	    (*((volatile Word *) SA1101_p2v (_PBSSR)))
-
-#endif
-
-
-
-/*
- * Keypad Interface
- *
- * Registers
- *    PXDWR
- *    PXDRR
- *    PYDWR
- *    PYDRR
- *
- */
-
-#define _KEYPAD( x )	_SA1101( ( x ) + __KEYPAD_INTERFACE ) 
-
-#define _PXDWR	   _KEYPAD( 0x0000 )
-#define _PXDRR	   _KEYPAD( 0x0000 )
-#define _PYDWR	   _KEYPAD( 0x0400 )
-#define _PYDRR	   _KEYPAD( 0x0400 )
-
-#if ( LANGUAGE == C )
-
-
-#define PXDWR	    (*((volatile Word *) SA1101_p2v (_PXDWR)))
-#define PXDRR	    (*((volatile Word *) SA1101_p2v (_PXDRR)))
-#define PYDWR	    (*((volatile Word *) SA1101_p2v (_PYDWR)))
-#define PYDRR	    (*((volatile Word *) SA1101_p2v (_PYDRR)))
-
-#endif
-
-
-
-/*
- * PCMCIA Interface
- *
- * Registers
- *    PCSR	Status Register
- *    PCCR	Control Register
- *    PCSSR	Sleep State Register
- *
- */
-
-#define _CARD( x )	_SA1101( ( x ) + __PCMCIA_INTERFACE )
-
-#define _PCSR	   _CARD( 0x0000 )
-#define _PCCR	   _CARD( 0x0400 )
-#define _PCSSR	   _CARD( 0x0800 )
-
-#if ( LANGUAGE == C )
-#define PCSR    (*((volatile Word *) SA1101_p2v (_PCSR)))
-#define PCCR	(*((volatile Word *) SA1101_p2v (_PCCR)))
-#define PCSSR	(*((volatile Word *) SA1101_p2v (_PCSSR)))
-
-#define PCSR_S0_ready		0x0001
-#define PCSR_S1_ready		0x0002
-#define PCSR_S0_detected	0x0004
-#define PCSR_S1_detected	0x0008
-#define PCSR_S0_VS1		0x0010
-#define PCSR_S0_VS2		0x0020
-#define PCSR_S1_VS1		0x0040
-#define PCSR_S1_VS2		0x0080
-#define PCSR_S0_WP		0x0100
-#define PCSR_S1_WP		0x0200
-#define PCSR_S0_BVD1_nSTSCHG	0x0400
-#define PCSR_S0_BVD2_nSPKR	0x0800
-#define PCSR_S1_BVD1_nSTSCHG	0x1000
-#define PCSR_S1_BVD2_nSPKR	0x2000
-
-#define PCCR_S0_VPP0		0x0001
-#define PCCR_S0_VPP1		0x0002
-#define PCCR_S0_VCC0		0x0004
-#define PCCR_S0_VCC1		0x0008
-#define PCCR_S1_VPP0		0x0010
-#define PCCR_S1_VPP1		0x0020
-#define PCCR_S1_VCC0		0x0040
-#define PCCR_S1_VCC1		0x0080
-#define PCCR_S0_reset		0x0100
-#define PCCR_S1_reset		0x0200
-#define PCCR_S0_float		0x0400
-#define PCCR_S1_float		0x0800
-
-#define PCSSR_S0_VCC0		0x0001
-#define PCSSR_S0_VCC1		0x0002
-#define PCSSR_S0_VPP0		0x0004
-#define PCSSR_S0_VPP1		0x0008
-#define PCSSR_S0_control	0x0010
-#define PCSSR_S1_VCC0		0x0020
-#define PCSSR_S1_VCC1		0x0040
-#define PCSSR_S1_VPP0		0x0080
-#define PCSSR_S1_VPP1		0x0100
-#define PCSSR_S1_control	0x0200
-
-#endif
-
-#undef C
-#undef Assembly
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index d944fd7e464f..c420b436de64 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -56,8 +56,4 @@ static inline unsigned long get_clock_tick_rate(void)
 
 #include "SA-1100.h"
 
-#ifdef CONFIG_SA1101
-#include "SA-1101.h"
-#endif
-
 #endif  /* _ASM_ARCH_HARDWARE_H */
-- 
2.1.0

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

* [PATCH 1/8] mfd: ucb1x00: allow IRQ probing to work with IRQs > 32
  2016-08-30 11:00               ` [PATCH 1/8] mfd: ucb1x00: allow IRQ probing to work with IRQs > 32 Russell King
@ 2016-08-30 12:00                 ` Lee Jones
  0 siblings, 0 replies; 235+ messages in thread
From: Lee Jones @ 2016-08-30 12:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 30 Aug 2016, Russell King wrote:

> probe_irq_on() only returns non-zero if it found any interrupts below
> IRQ32 which could be probe candidates.  If all the probable interrupts
> are higher than 32, then this will cause a failure.  Fix this.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/mfd/ucb1x00-core.c | 4 ----
>  1 file changed, 4 deletions(-)

Sounds reasonable.  Will fix the $SUBJECT line for you.

Applied, thanks.

> diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
> index 9ab9ec47ea75..48bea5038654 100644
> --- a/drivers/mfd/ucb1x00-core.c
> +++ b/drivers/mfd/ucb1x00-core.c
> @@ -446,10 +446,6 @@ static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
>  	unsigned long mask;
>  
>  	mask = probe_irq_on();
> -	if (!mask) {
> -		probe_irq_off(mask);
> -		return NO_IRQ;
> -	}
>  
>  	/*
>  	 * Enable the ADC interrupt.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
  2016-08-30 10:51             ` Russell King - ARM Linux
@ 2016-08-30 15:31               ` Nicolas Pitre
  -1 siblings, 0 replies; 235+ messages in thread
From: Nicolas Pitre @ 2016-08-30 15:31 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: netdev, linux-arm-kernel

On Tue, 30 Aug 2016, Russell King - ARM Linux wrote:

> This mini-series (which follows several other series on which it
> depends) gets rid of the Assabet/Neponset hack in the smc91x driver.
> 
> In order to do that, we need to get several pieces in place first:
> * gpiolib support throughout SA11x0/Assabet/Neponset so that we can
>   represent control signals through gpiolib
> * CCF support, so we can re-use the code in drivers/clk to implement
>   the external crystal oscillator attached to the SMC91x.  This
>   external crystal oscillator is enabled via a control signal.
> 
> This series:
> - performs the SA11x0 CCF conversion
> - adds an optional clock to SMC91x to cater for an external crystal
>   oscillator
> - switches the Neponset code to provide a 'struct clk' representing
>   this oscillator
> - removes the SMC91x hack to assert the enable signal
> 
> This results in the platform specific includes being removed from the
> SMC91x driver.
> 
> Please ack these changes; due to the dependencies, I wish to merge
> them through my tree.  Thanks.

Looks nice to me.

Acked-by: Nicolas Pitre <nico@linaro.org>

>  arch/arm/Kconfig                   |   1 +
>  arch/arm/mach-sa1100/clock.c       | 191 +++++++++++++++++--------------------
>  arch/arm/mach-sa1100/neponset.c    |  42 ++++++++
>  drivers/net/ethernet/smsc/smc91x.c |  47 ++++++---
>  drivers/net/ethernet/smsc/smc91x.h |   1 +
>  5 files changed, 166 insertions(+), 116 deletions(-)
> 
> -- 
> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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

* [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
@ 2016-08-30 15:31               ` Nicolas Pitre
  0 siblings, 0 replies; 235+ messages in thread
From: Nicolas Pitre @ 2016-08-30 15:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 30 Aug 2016, Russell King - ARM Linux wrote:

> This mini-series (which follows several other series on which it
> depends) gets rid of the Assabet/Neponset hack in the smc91x driver.
> 
> In order to do that, we need to get several pieces in place first:
> * gpiolib support throughout SA11x0/Assabet/Neponset so that we can
>   represent control signals through gpiolib
> * CCF support, so we can re-use the code in drivers/clk to implement
>   the external crystal oscillator attached to the SMC91x.  This
>   external crystal oscillator is enabled via a control signal.
> 
> This series:
> - performs the SA11x0 CCF conversion
> - adds an optional clock to SMC91x to cater for an external crystal
>   oscillator
> - switches the Neponset code to provide a 'struct clk' representing
>   this oscillator
> - removes the SMC91x hack to assert the enable signal
> 
> This results in the platform specific includes being removed from the
> SMC91x driver.
> 
> Please ack these changes; due to the dependencies, I wish to merge
> them through my tree.  Thanks.

Looks nice to me.

Acked-by: Nicolas Pitre <nico@linaro.org>

>  arch/arm/Kconfig                   |   1 +
>  arch/arm/mach-sa1100/clock.c       | 191 +++++++++++++++++--------------------
>  arch/arm/mach-sa1100/neponset.c    |  42 ++++++++
>  drivers/net/ethernet/smsc/smc91x.c |  47 ++++++---
>  drivers/net/ethernet/smsc/smc91x.h |   1 +
>  5 files changed, 166 insertions(+), 116 deletions(-)
> 
> -- 
> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

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

* Re: [PATCH 1/8] dmaengine: sa11x0: add DMA filters
  2016-08-29 11:26         ` Russell King
@ 2016-08-30 15:57           ` Vinod Koul
  -1 siblings, 0 replies; 235+ messages in thread
From: Vinod Koul @ 2016-08-30 15:57 UTC (permalink / raw)
  To: Russell King
  Cc: dmaengine, linux-arm-kernel, netdev, Dan Williams, Samuel Ortiz

On Mon, Aug 29, 2016 at 12:26:04PM +0100, Russell King wrote:
> Add DMA filters for the sa11x0 DMA channels.  This will allow us to
> migrate away from directly using the DMA filter function in drivers.

Acked-by: Vinod Koul <vinod.koul@intel.com>

-- 
~Vinod

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

* [PATCH 1/8] dmaengine: sa11x0: add DMA filters
@ 2016-08-30 15:57           ` Vinod Koul
  0 siblings, 0 replies; 235+ messages in thread
From: Vinod Koul @ 2016-08-30 15:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 12:26:04PM +0100, Russell King wrote:
> Add DMA filters for the sa11x0 DMA channels.  This will allow us to
> migrate away from directly using the DMA filter function in drivers.

Acked-by: Vinod Koul <vinod.koul@intel.com>

-- 
~Vinod

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

* Re: [PATCH 4/8] dmaengine: sa11x0: unexport sa11x0_dma_filter_fn and clean up
  2016-08-29 11:26         ` Russell King
@ 2016-08-30 15:58           ` Vinod Koul
  -1 siblings, 0 replies; 235+ messages in thread
From: Vinod Koul @ 2016-08-30 15:58 UTC (permalink / raw)
  To: Russell King
  Cc: dmaengine, linux-arm-kernel, netdev, Dan Williams, Samuel Ortiz

On Mon, Aug 29, 2016 at 12:26:20PM +0100, Russell King wrote:
> As we now have no users of sa11x0_dma_filter_fn() in the tree, we can
> unexport this function, and remove the now unused header file.

Acked-by: Vinod Koul <vinod.koul@intel.com>


-- 
~Vinod

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

* [PATCH 4/8] dmaengine: sa11x0: unexport sa11x0_dma_filter_fn and clean up
@ 2016-08-30 15:58           ` Vinod Koul
  0 siblings, 0 replies; 235+ messages in thread
From: Vinod Koul @ 2016-08-30 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 12:26:20PM +0100, Russell King wrote:
> As we now have no users of sa11x0_dma_filter_fn() in the tree, we can
> unexport this function, and remove the now unused header file.

Acked-by: Vinod Koul <vinod.koul@intel.com>


-- 
~Vinod

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30  9:18         ` Russell King - ARM Linux
@ 2016-08-30 16:42           ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-30 16:42 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Linus Walleij

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
>> Maybe this one would deserve a doxygen comment ?
>
> Does this solve it?
Oh yes, that's very nice, especially the "1 = in" for which I have always a
doubt.

Reviewed-by: Robert Jarzmik <robert.jarzmik@free.fr>

I hope to have an "attempt" to test all your series on the lubbock board in the
next days. The "attempt" part is because last time I checked pcmcia support was
broken on lubbock (ie. CONFIG_PCMCIA_SA1111 activated implies an Oops), and I
don't remember having repaired it (and it's disabled on my test farm which is a
sign I was not very confident about this part).

If you happen to have somewhere a branch I can pull, with all your series (at
least "[RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)" and
"[PATCH 0/8] SA11x0/PXA remainder & cleanups"), that would spare me the multiple
git-am to make the test(s).

Cheers.

--
Robert

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30 16:42           ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-30 16:42 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
>> Maybe this one would deserve a doxygen comment ?
>
> Does this solve it?
Oh yes, that's very nice, especially the "1 = in" for which I have always a
doubt.

Reviewed-by: Robert Jarzmik <robert.jarzmik@free.fr>

I hope to have an "attempt" to test all your series on the lubbock board in the
next days. The "attempt" part is because last time I checked pcmcia support was
broken on lubbock (ie. CONFIG_PCMCIA_SA1111 activated implies an Oops), and I
don't remember having repaired it (and it's disabled on my test farm which is a
sign I was not very confident about this part).

If you happen to have somewhere a branch I can pull, with all your series (at
least "[RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)" and
"[PATCH 0/8] SA11x0/PXA remainder & cleanups"), that would spare me the multiple
git-am to make the test(s).

Cheers.

--
Robert

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30 16:42           ` Robert Jarzmik
@ 2016-08-30 18:46             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 18:46 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Linus Walleij

On Tue, Aug 30, 2016 at 06:42:03PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> 
> > On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> >> Maybe this one would deserve a doxygen comment ?
> >
> > Does this solve it?
> Oh yes, that's very nice, especially the "1 = in" for which I have always a
> doubt.
> 
> Reviewed-by: Robert Jarzmik <robert.jarzmik@free.fr>
> 
> I hope to have an "attempt" to test all your series on the lubbock board in the
> next days. The "attempt" part is because last time I checked pcmcia support was
> broken on lubbock (ie. CONFIG_PCMCIA_SA1111 activated implies an Oops), and I
> don't remember having repaired it (and it's disabled on my test farm which is a
> sign I was not very confident about this part).
> 
> If you happen to have somewhere a branch I can pull, with all your series (at
> least "[RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)" and
> "[PATCH 0/8] SA11x0/PXA remainder & cleanups"), that would spare me the multiple
> git-am to make the test(s).

If you can wait a day or two, I'll push a branch out for everything in
all these multiple series.

Thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30 18:46             ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 30, 2016 at 06:42:03PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> 
> > On Mon, Aug 29, 2016 at 09:39:54PM +0200, Robert Jarzmik wrote:
> >> Maybe this one would deserve a doxygen comment ?
> >
> > Does this solve it?
> Oh yes, that's very nice, especially the "1 = in" for which I have always a
> doubt.
> 
> Reviewed-by: Robert Jarzmik <robert.jarzmik@free.fr>
> 
> I hope to have an "attempt" to test all your series on the lubbock board in the
> next days. The "attempt" part is because last time I checked pcmcia support was
> broken on lubbock (ie. CONFIG_PCMCIA_SA1111 activated implies an Oops), and I
> don't remember having repaired it (and it's disabled on my test farm which is a
> sign I was not very confident about this part).
> 
> If you happen to have somewhere a branch I can pull, with all your series (at
> least "[RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)" and
> "[PATCH 0/8] SA11x0/PXA remainder & cleanups"), that would spare me the multiple
> git-am to make the test(s).

If you can wait a day or two, I'll push a branch out for everything in
all these multiple series.

Thanks.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-29 10:24     ` Russell King
@ 2016-08-30 21:25       ` Linus Walleij
  -1 siblings, 0 replies; 235+ messages in thread
From: Linus Walleij @ 2016-08-30 21:25 UTC (permalink / raw)
  To: Russell King
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Robert Jarzmik

On Mon, Aug 29, 2016 at 12:24 PM, Russell King
<rmk+kernel@armlinux.org.uk> wrote:

> Add a simple, generic, single register fixed-direction GPIO driver.
> This is able to support a single register where a fixed number of
> bits are used for input and a fixed number of bits used for output.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Clever, I like it!

>  include/linux/gpio-reg.h |  12 ++++

Can we put this in include/linux/gpio/gpio-reg.h?

I try to do some scopeing to <linux/gpio/*> there.

> +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)

You don't need that trickery anymore, just:

> +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct gpio_reg *r = to_gpio_reg(gc);

struct gpio_reg *r = gpiochip_get_data(gc);

(applied everywhere)

> +       if (dev)
> +               ret = devm_gpiochip_add_data(dev, &r->gc, r);
> +       else
> +               ret = gpiochip_add_data(&r->gc, r);

Aha both device and device-less, I see.

Apart from that it looks nice, any other questionmarks were
fixed in the other replies.

Yours,
Linus Walleij

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30 21:25       ` Linus Walleij
  0 siblings, 0 replies; 235+ messages in thread
From: Linus Walleij @ 2016-08-30 21:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 12:24 PM, Russell King
<rmk+kernel@armlinux.org.uk> wrote:

> Add a simple, generic, single register fixed-direction GPIO driver.
> This is able to support a single register where a fixed number of
> bits are used for input and a fixed number of bits used for output.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

Clever, I like it!

>  include/linux/gpio-reg.h |  12 ++++

Can we put this in include/linux/gpio/gpio-reg.h?

I try to do some scopeing to <linux/gpio/*> there.

> +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)

You don't need that trickery anymore, just:

> +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
> +{
> +       struct gpio_reg *r = to_gpio_reg(gc);

struct gpio_reg *r = gpiochip_get_data(gc);

(applied everywhere)

> +       if (dev)
> +               ret = devm_gpiochip_add_data(dev, &r->gc, r);
> +       else
> +               ret = gpiochip_add_data(&r->gc, r);

Aha both device and device-less, I see.

Apart from that it looks nice, any other questionmarks were
fixed in the other replies.

Yours,
Linus Walleij

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

* Re: [RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)
  2016-08-29 10:23   ` Russell King - ARM Linux
@ 2016-08-30 21:31     ` Linus Walleij
  -1 siblings, 0 replies; 235+ messages in thread
From: Linus Walleij @ 2016-08-30 21:31 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Robert Jarzmik

On Mon, Aug 29, 2016 at 12:23 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:

> Following on from the PCMCIA fixes, this series reworks GPIO on SA11x0
> and PXA platforms.  This is a subset of a larger series, which I'm
> splitting up due to its size.  This part contains the base and PCMCIA
> updates.  Further updates for IrDA drivers, DMA engine, serial, and
> ethernet will follow in time.

For all the GPIO patches:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

With the smallish changes needed to patch 5/33 that one is acked too.

In fact I would ACK it anyway, because the net total cleanup is so
nice on the kernel at large... SA11x0 has never been prettier than
after this series.

I suspect you want to keep the series together and queue it in the ARM
tree? Else tell me what to apply in the GPIO tree.

Yours,
Linus Walleij

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

* [RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)
@ 2016-08-30 21:31     ` Linus Walleij
  0 siblings, 0 replies; 235+ messages in thread
From: Linus Walleij @ 2016-08-30 21:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 12:23 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:

> Following on from the PCMCIA fixes, this series reworks GPIO on SA11x0
> and PXA platforms.  This is a subset of a larger series, which I'm
> splitting up due to its size.  This part contains the base and PCMCIA
> updates.  Further updates for IrDA drivers, DMA engine, serial, and
> ethernet will follow in time.

For all the GPIO patches:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

With the smallish changes needed to patch 5/33 that one is acked too.

In fact I would ACK it anyway, because the net total cleanup is so
nice on the kernel at large... SA11x0 has never been prettier than
after this series.

I suspect you want to keep the series together and queue it in the ARM
tree? Else tell me what to apply in the GPIO tree.

Yours,
Linus Walleij

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30 18:46             ` Russell King - ARM Linux
@ 2016-08-30 21:32               ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-30 21:32 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> If you can wait a day or two, I'll push a branch out for everything in
> all these multiple series.
Sure, just ping me when you have something.

Cheers.

-- 
Robert

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30 21:32               ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-08-30 21:32 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> If you can wait a day or two, I'll push a branch out for everything in
> all these multiple series.
Sure, just ping me when you have something.

Cheers.

-- 
Robert

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30 21:25       ` Linus Walleij
@ 2016-08-30 21:42         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 21:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Robert Jarzmik

On Tue, Aug 30, 2016 at 11:25:19PM +0200, Linus Walleij wrote:
> On Mon, Aug 29, 2016 at 12:24 PM, Russell King
> <rmk+kernel@armlinux.org.uk> wrote:
> 
> > Add a simple, generic, single register fixed-direction GPIO driver.
> > This is able to support a single register where a fixed number of
> > bits are used for input and a fixed number of bits used for output.
> >
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> 
> Clever, I like it!
> 
> >  include/linux/gpio-reg.h |  12 ++++
> 
> Can we put this in include/linux/gpio/gpio-reg.h?
> 
> I try to do some scopeing to <linux/gpio/*> there.

Sure, I'll just have to hunt through all the patches to find an occurance
of the include to fix them all up...

> > +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
> 
> You don't need that trickery anymore, just:
> 
> > +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
> > +{
> > +       struct gpio_reg *r = to_gpio_reg(gc);
> 
> struct gpio_reg *r = gpiochip_get_data(gc);
> 
> (applied everywhere)

I prefer my method by a long shot - it's always going to work because
the gpiochip is embedded within the gpio_reg structure, and the compiler
is inteligent enough to keep a single pointer around.  With your
suggestion, the compiler has no idea that 'r' and 'gc' are actually
the same pointer, but a different type, and we end up having to carry
around identical pointers in two registers rather than just one.

It makes more sense to use gpiochip_get_data() if gpio_chip were a const
data structure that was never embedded, but the way *gpiochip_add*()
writes to the structure and the presence of members like "base" prevents
that.

> 
> > +       if (dev)
> > +               ret = devm_gpiochip_add_data(dev, &r->gc, r);
> > +       else
> > +               ret = gpiochip_add_data(&r->gc, r);
> 
> Aha both device and device-less, I see.

Yes, to avoid problems with the transition to it - the legacy APIs
(such as ASSABET_BCR_frob(), etc) can be called really early, so we
need the gpiochip available early as well so we can keep the legacy
APIs working until they can be killed off.  There's some corner
cases in the assabet code which make that difficult at the moment.

This whole patch set is still very much a work-in-progress - there's
more that needs doing, but I wanted to get _this_ out there so that
people can reviewing it, and hopefully get it queued for the next
merge window.

> Apart from that it looks nice, any other questionmarks were
> fixed in the other replies.
> 
> Yours,
> Linus Walleij

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30 21:42         ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-30 21:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 30, 2016 at 11:25:19PM +0200, Linus Walleij wrote:
> On Mon, Aug 29, 2016 at 12:24 PM, Russell King
> <rmk+kernel@armlinux.org.uk> wrote:
> 
> > Add a simple, generic, single register fixed-direction GPIO driver.
> > This is able to support a single register where a fixed number of
> > bits are used for input and a fixed number of bits used for output.
> >
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> 
> Clever, I like it!
> 
> >  include/linux/gpio-reg.h |  12 ++++
> 
> Can we put this in include/linux/gpio/gpio-reg.h?
> 
> I try to do some scopeing to <linux/gpio/*> there.

Sure, I'll just have to hunt through all the patches to find an occurance
of the include to fix them all up...

> > +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
> 
> You don't need that trickery anymore, just:
> 
> > +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
> > +{
> > +       struct gpio_reg *r = to_gpio_reg(gc);
> 
> struct gpio_reg *r = gpiochip_get_data(gc);
> 
> (applied everywhere)

I prefer my method by a long shot - it's always going to work because
the gpiochip is embedded within the gpio_reg structure, and the compiler
is inteligent enough to keep a single pointer around.  With your
suggestion, the compiler has no idea that 'r' and 'gc' are actually
the same pointer, but a different type, and we end up having to carry
around identical pointers in two registers rather than just one.

It makes more sense to use gpiochip_get_data() if gpio_chip were a const
data structure that was never embedded, but the way *gpiochip_add*()
writes to the structure and the presence of members like "base" prevents
that.

> 
> > +       if (dev)
> > +               ret = devm_gpiochip_add_data(dev, &r->gc, r);
> > +       else
> > +               ret = gpiochip_add_data(&r->gc, r);
> 
> Aha both device and device-less, I see.

Yes, to avoid problems with the transition to it - the legacy APIs
(such as ASSABET_BCR_frob(), etc) can be called really early, so we
need the gpiochip available early as well so we can keep the legacy
APIs working until they can be killed off.  There's some corner
cases in the assabet code which make that difficult at the moment.

This whole patch set is still very much a work-in-progress - there's
more that needs doing, but I wanted to get _this_ out there so that
people can reviewing it, and hopefully get it queued for the next
merge window.

> Apart from that it looks nice, any other questionmarks were
> fixed in the other replies.
> 
> Yours,
> Linus Walleij

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30 21:42         ` Russell King - ARM Linux
@ 2016-08-30 21:47           ` Linus Walleij
  -1 siblings, 0 replies; 235+ messages in thread
From: Linus Walleij @ 2016-08-30 21:47 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Robert Jarzmik

On Tue, Aug 30, 2016 at 11:42 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Tue, Aug 30, 2016 at 11:25:19PM +0200, Linus Walleij wrote:

>> > +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
>>
>> You don't need that trickery anymore, just:
>>
>> > +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
>> > +{
>> > +       struct gpio_reg *r = to_gpio_reg(gc);
>>
>> struct gpio_reg *r = gpiochip_get_data(gc);
>>
>> (applied everywhere)
>
> I prefer my method by a long shot

Sure it's no strong preference. Keep it like this if you like.
I'm very happy with the series either way!

Yours,
Linus Walleij

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-30 21:47           ` Linus Walleij
  0 siblings, 0 replies; 235+ messages in thread
From: Linus Walleij @ 2016-08-30 21:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 30, 2016 at 11:42 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Tue, Aug 30, 2016 at 11:25:19PM +0200, Linus Walleij wrote:

>> > +#define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
>>
>> You don't need that trickery anymore, just:
>>
>> > +static int gpio_reg_get_direction(struct gpio_chip *gc, unsigned offset)
>> > +{
>> > +       struct gpio_reg *r = to_gpio_reg(gc);
>>
>> struct gpio_reg *r = gpiochip_get_data(gc);
>>
>> (applied everywhere)
>
> I prefer my method by a long shot

Sure it's no strong preference. Keep it like this if you like.
I'm very happy with the series either way!

Yours,
Linus Walleij

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30 21:32               ` Robert Jarzmik
@ 2016-08-31  8:49                 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-31  8:49 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

On Tue, Aug 30, 2016 at 11:32:16PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> 
> > If you can wait a day or two, I'll push a branch out for everything in
> > all these multiple series.
> Sure, just ping me when you have something.

git://git.armlinux.org.uk/~rmk/linux-arm.git sa1100

should get you something suitable to test.  It's based on 4.7-rc3 plus
my fixes branch.

It would be great to have this tested on Lubbock, and get the PCMCIA
issues fixed.  Maybe we can look at converting mainstone as well?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-31  8:49                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-31  8:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 30, 2016 at 11:32:16PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> 
> > If you can wait a day or two, I'll push a branch out for everything in
> > all these multiple series.
> Sure, just ping me when you have something.

git://git.armlinux.org.uk/~rmk/linux-arm.git sa1100

should get you something suitable to test.  It's based on 4.7-rc3 plus
my fixes branch.

It would be great to have this tested on Lubbock, and get the PCMCIA
issues fixed.  Maybe we can look at converting mainstone as well?

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-31  8:49                 ` Russell King - ARM Linux
@ 2016-08-31 10:27                   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-31 10:27 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

On Wed, Aug 31, 2016 at 09:49:38AM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 30, 2016 at 11:32:16PM +0200, Robert Jarzmik wrote:
> > Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > 
> > > If you can wait a day or two, I'll push a branch out for everything in
> > > all these multiple series.
> > Sure, just ping me when you have something.
> 
> git://git.armlinux.org.uk/~rmk/linux-arm.git sa1100
> 
> should get you something suitable to test.  It's based on 4.7-rc3 plus
> my fixes branch.
> 
> It would be great to have this tested on Lubbock, and get the PCMCIA
> issues fixed.  Maybe we can look at converting mainstone as well?

Yes, looking at mainstone's PCMCIA, it uses a MAX1602 device, which
is supported by the new max1600.c code.

#define MST_PCMCIA_PWR_VPP_0    0x0        /* voltage VPP = 0V */
#define MST_PCMCIA_PWR_VPP_120  0x2        /* voltage VPP = 12V*/
#define MST_PCMCIA_PWR_VPP_VCC  0x1        /* voltage VPP = VCC */
#define MST_PCMCIA_PWR_VCC_0    0x0        /* voltage VCC = 0V */
#define MST_PCMCIA_PWR_VCC_33   0x8        /* voltage VCC = 3.3V */
#define MST_PCMCIA_PWR_VCC_50   0x4        /* voltage VCC = 5.0V */

This follows the Cirrus code (also used by Lubbock.)  So, if we represent
the MST_PCMCIA[01] registers as GPIOs, we can switch pxa2xx_mainstone.c
to use the max1600.c code for power control.

With the other signals in MST_PCMCIA[01] represented as GPIOs (we'd
need to add the VS* to soc_common), we'd then have those read by
generic code, which means mst_pcmcia_socket_state() becomes just the
hack for STSCHG.

With gpio-reg, we can represent these registers easily as GPIOs, eg:

	gc = gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0,
			   -1, 11, "mst-pcmcia0", ~MST_PCMCIA_PWR_MASK, 0,
			   mst_pcmcia_names);

There is a slight issue, which is that the interrupts can't be
translated to an interrupt by gpio-reg, which will currently cause
soc_common problems - but that's an easy fix, though leaves us with
more code than I'd desire in pxa2xx_mainstone.c.  Maybe a solution
there would be to have gpio-reg also take an array of interrupt
numbers... not sure yet.


For IrDA, it looks like it has the same transceiver as the assabet, so
I've (already) patches to split out the gpio-based transceiver control
from sa1100_ir - maybe we can re-use that in pxaficp_ir too.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-08-31 10:27                   ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-08-31 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 31, 2016 at 09:49:38AM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 30, 2016 at 11:32:16PM +0200, Robert Jarzmik wrote:
> > Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > 
> > > If you can wait a day or two, I'll push a branch out for everything in
> > > all these multiple series.
> > Sure, just ping me when you have something.
> 
> git://git.armlinux.org.uk/~rmk/linux-arm.git sa1100
> 
> should get you something suitable to test.  It's based on 4.7-rc3 plus
> my fixes branch.
> 
> It would be great to have this tested on Lubbock, and get the PCMCIA
> issues fixed.  Maybe we can look at converting mainstone as well?

Yes, looking at mainstone's PCMCIA, it uses a MAX1602 device, which
is supported by the new max1600.c code.

#define MST_PCMCIA_PWR_VPP_0    0x0        /* voltage VPP = 0V */
#define MST_PCMCIA_PWR_VPP_120  0x2        /* voltage VPP = 12V*/
#define MST_PCMCIA_PWR_VPP_VCC  0x1        /* voltage VPP = VCC */
#define MST_PCMCIA_PWR_VCC_0    0x0        /* voltage VCC = 0V */
#define MST_PCMCIA_PWR_VCC_33   0x8        /* voltage VCC = 3.3V */
#define MST_PCMCIA_PWR_VCC_50   0x4        /* voltage VCC = 5.0V */

This follows the Cirrus code (also used by Lubbock.)  So, if we represent
the MST_PCMCIA[01] registers as GPIOs, we can switch pxa2xx_mainstone.c
to use the max1600.c code for power control.

With the other signals in MST_PCMCIA[01] represented as GPIOs (we'd
need to add the VS* to soc_common), we'd then have those read by
generic code, which means mst_pcmcia_socket_state() becomes just the
hack for STSCHG.

With gpio-reg, we can represent these registers easily as GPIOs, eg:

	gc = gpio_reg_init(NULL, (void __iomem *)&MST_PCMCIA0,
			   -1, 11, "mst-pcmcia0", ~MST_PCMCIA_PWR_MASK, 0,
			   mst_pcmcia_names);

There is a slight issue, which is that the interrupts can't be
translated to an interrupt by gpio-reg, which will currently cause
soc_common problems - but that's an easy fix, though leaves us with
more code than I'd desire in pxa2xx_mainstone.c.  Maybe a solution
there would be to have gpio-reg also take an array of interrupt
numbers... not sure yet.


For IrDA, it looks like it has the same transceiver as the assabet, so
I've (already) patches to split out the gpio-based transceiver control
from sa1100_ir - maybe we can re-use that in pxaficp_ir too.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 1/6] serial: sa1100: add support for mctrl gpios
  2016-08-29 12:05           ` Russell King
@ 2016-08-31 13:25             ` Greg Kroah-Hartman
  -1 siblings, 0 replies; 235+ messages in thread
From: Greg Kroah-Hartman @ 2016-08-31 13:25 UTC (permalink / raw)
  To: Russell King; +Cc: linux-serial, linux-arm-kernel, Jiri Slaby

On Mon, Aug 29, 2016 at 01:05:51PM +0100, Russell King wrote:
> Add support for the generic mctrl gpio helper.  This will allow us to
> convert several board files to use the gpiod tables to assign GPIOs to
> serial ports, rather than needing to have private function callbacks.
> 
> If the generic mctrl gpio helper fails, ignore the mctrl gpios rather
> than preventing the (possibly console) serial port from being created.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/tty/serial/Kconfig  |  1 +
>  drivers/tty/serial/sa1100.c | 42 ++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 39 insertions(+), 4 deletions(-)

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* [PATCH 1/6] serial: sa1100: add support for mctrl gpios
@ 2016-08-31 13:25             ` Greg Kroah-Hartman
  0 siblings, 0 replies; 235+ messages in thread
From: Greg Kroah-Hartman @ 2016-08-31 13:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 29, 2016 at 01:05:51PM +0100, Russell King wrote:
> Add support for the generic mctrl gpio helper.  This will allow us to
> convert several board files to use the gpiod tables to assign GPIOs to
> serial ports, rather than needing to have private function callbacks.
> 
> If the generic mctrl gpio helper fails, ignore the mctrl gpios rather
> than preventing the (possibly console) serial port from being created.
> 
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
>  drivers/tty/serial/Kconfig  |  1 +
>  drivers/tty/serial/sa1100.c | 42 ++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 39 insertions(+), 4 deletions(-)

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-31 10:27                   ` Russell King - ARM Linux
@ 2016-09-01  7:19                     ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-01  7:19 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Wed, Aug 31, 2016 at 09:49:38AM +0100, Russell King - ARM Linux wrote:
>> On Tue, Aug 30, 2016 at 11:32:16PM +0200, Robert Jarzmik wrote:
>> > Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>> > 
>> > > If you can wait a day or two, I'll push a branch out for everything in
>> > > all these multiple series.
>> > Sure, just ping me when you have something.
>> 
>> git://git.armlinux.org.uk/~rmk/linux-arm.git sa1100
>> 
>> should get you something suitable to test.  It's based on 4.7-rc3 plus
>> my fixes branch.
>> 
>> It would be great to have this tested on Lubbock, and get the PCMCIA
>> issues fixed.
Ok Russell, I run a first mini-test.

I used :
 - one trivial typo fix of your patches in [1]
 - one "make it better fix" in [2] to pass the pcmcia probe, without much
   thinking about it, just to have the probe finished

The result today is that my PCMCIA card inserted in Lubbock's slot is not
detected, but that's not really a surprise. As a matter of fact, I didn't look
much into it, the only data points I have are :
 - PCMCIA is probed now
   - this is based on dmesg in [3]
   - this is also based on ls /sys/bus/sa1111-rab/devices/1800
	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 driver -> ../../../../bus/sa1111-rab/drivers/sa1111-pcmcia
	drwxr-xr-x    2 root     root             0 Jan  1 00:15 power
	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 subsystem -> ../../../../bus/sa1111-rab
	-rw-r--r--    1 root     root          4096 Jan  1 00:15 uevent

 - PCMCIA sockets are not there
   - this is based on ls /sys/class/pcmcia_socket/ where there is nothing

 - MAX16xx gpio are not claimed, which is surprising
   - this is based on cat /sys/kernel/debug/gpio
	gpiochip0: GPIOs 0-84, gpio-pxa:
	gpiochip2: GPIOs 478-495, parent: platform/sa1111, sa1111:
	gpiochip1: GPIOs 496-511, lubbock:

I'm not familiar with drivers/pcmcia part of the kernel tree so I won't be fast
to go down to the problem, but I'll try in the next days. Maybe if I activate
debug logs in pcmcia related parts I'll find out more quickly what is happening.

> Maybe we can look at converting mainstone as well?
Yep.

> This follows the Cirrus code (also used by Lubbock.)  So, if we represent the
> MST_PCMCIA[01] registers as GPIOs, we can switch pxa2xx_mainstone.c to use the
> max1600.c code for power control.
Yes.

> There is a slight issue, which is that the interrupts can't be translated to
> an interrupt by gpio-reg, which will currently cause soc_common problems - but
> that's an easy fix, though leaves us with more code than I'd desire in
> pxa2xx_mainstone.c.  Maybe a solution there would be to have gpio-reg also
> take an array of interrupt numbers... not sure yet.
Normally these interrupts are already dealt with by
arch/arm/mach-pxa/pxa_cplds_irq.c, which adds an irqdomain for them. The missing
part is the "gpio to interrupt" translation part, right ? This is where your
array comes into play if I get your right, to be the input of the to_irq()
function of the gpiochip.

As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
so that your translation is only a linear irq = gpio + offset ?

> For IrDA, it looks like it has the same transceiver as the assabet, so I've
> (already) patches to split out the gpio-based transceiver control from
> sa1100_ir - maybe we can re-use that in pxaficp_ir too.
Once PCMCIA is over, sure.

Cheers.

--
Robert

[1] Typo fix
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index f034928b99a1..81a1de6fb46f 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -13,7 +13,7 @@
  */
 #include <linux/clkdev.h>
 #include <linux/gpio.h>
-#include <linux/gpip/gpio-reg.h>
+#include <linux/gpio/gpio-reg.h>
 #include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/kernel.h>

[2] Kind-of fix for lubbock pcmcia probe
>From 977c16201a752aac8a8fb2da1f4271795f0b2122 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Thu, 1 Sep 2016 08:31:08 +0200
Subject: [PATCH] pcmcia: lubbock: fix sockets configuration

On lubbock board, the probe of the driver crashes by dereferencing very
early a platform_data structure which is not set, in
pxa2xx_configure_sockets().

This patch blindly fixes it without any analysis as to know if it's the
right fix or even if the fix doesn't break in suspend/resume.

The stack fixed is :
[    0.244353] SA1111 Microprocessor Companion Chip: silicon revision 1, metal revision 1
[    0.256321] sa1111 sa1111: Providing IRQ336-390
[    0.340899] clocksource: Switched to clocksource oscr0
[    0.472263] Unable to handle kernel NULL pointer dereference at virtual address 00000004
[    0.480469] pgd = c0004000
[    0.483432] [00000004] *pgd=00000000
[    0.487105] Internal error: Oops: f5 [#1] ARM
[    0.491497] Modules linked in:
[    0.494650] CPU: 0 PID: 1 Comm: swapper Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2068
[    0.503229] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
[    0.510344] task: c3e42000 task.stack: c3e44000
[    0.514984] PC is at pxa2xx_configure_sockets+0x4/0x24 (drivers/pcmcia/pxa2xx_base.c:227)
[    0.520193] LR is at pcmcia_lubbock_init+0x1c/0x38
[    0.525079] pc : [<c0247c30>]    lr : [<c02479b0>]    psr: a0000053
[    0.525079] sp : c3e45e70  ip : 100019ff  fp : 00000000
[    0.536651] r10: c0828900  r9 : c0434838  r8 : 00000000
[    0.541953] r7 : c0820700  r6 : c0857b30  r5 : c3ec1400  r4 : c0820758
[    0.548549] r3 : 00000000  r2 : 0000000c  r1 : c3c09c40  r0 : c3ec1400
[    0.555154] Flags: NzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
[    0.562450] Control: 0000397f  Table: a0004000  DAC: 00000053
[    0.568257] Process swapper (pid: 1, stack limit = 0xc3e44190)
[    0.574154] Stack: (0xc3e45e70 to 0xc3e46000)
[    0.578610] 5e60:                                     c4849800 00000000 c3ec1400 c024769c
[    0.586928] 5e80: 00000000 c3ec140c c3c0ee0c c3ec1400 c3ec1434 c020c410 c3ec1400 c3ec1434
[    0.595244] 5ea0: c0820700 c080b408 c0828900 c020c5f8 00000000 c0820700 c020c578 c020ac5c
[    0.603560] 5ec0: c3e687cc c3e71e10 c0820700 00000000 c3c02de0 c020bae4 c03c62f7 c03c62f7
[    0.611872] 5ee0: c3e68780 c0820700 c042e034 00000000 c043c440 c020cdec c080b408 00000005
[    0.620188] 5f00: c042e034 c00096c0 c0034440 c01c730c 20000053 ffffffff 00000000 00000000
[    0.628502] 5f20: 00000000 c3ffcb87 c3ffcb90 c00346ac c3e66ba0 c03f7914 00000092 00000005
[    0.636811] 5f40: 00000005 c03f847c 00000091 c03f847c 00000000 00000005 c0434828 00000005
[    0.645125] 5f60: c043482c 00000092 c043c440 c0828900 c0434838 c0418d2c 00000005 00000005
[    0.653430] 5f80: 00000000 c041858c 00000000 c032e9f0 00000000 00000000 00000000 00000000
[    0.661729] 5fa0: 00000000 c032e9f8 00000000 c000f0f0 00000000 00000000 00000000 00000000
[    0.670020] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.678311] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    0.686673] (pxa2xx_configure_sockets) from pcmcia_lubbock_init (/drivers/pcmcia/sa1111_lubbock.c:161)
[    0.696026] (pcmcia_lubbock_init) from pcmcia_probe (/drivers/pcmcia/sa1111_generic.c:213)
[    0.704358] (pcmcia_probe) from driver_probe_device (/drivers/base/dd.c:378 /drivers/base/dd.c:499)
[    0.712848] (driver_probe_device) from __driver_attach (/./include/linux/device.h:983 /drivers/base/dd.c:733)
[    0.721414] (__driver_attach) from bus_for_each_dev (/drivers/base/bus.c:313)
[    0.729723] (bus_for_each_dev) from bus_add_driver (/drivers/base/bus.c:708)
[    0.738036] (bus_add_driver) from driver_register (/drivers/base/driver.c:169)
[    0.746185] (driver_register) from do_one_initcall (/init/main.c:778)
[    0.754561] (do_one_initcall) from kernel_init_freeable (/init/main.c:843 /init/main.c:851 /init/main.c:869 /init/main.c:1016)
[    0.763409] (kernel_init_freeable) from kernel_init (/init/main.c:944)
[    0.771660] (kernel_init) from ret_from_fork (/arch/arm/kernel/entry-common.S:119)
[ 0.779347] Code: c03c6305 c03c631e c03c632e e5903048 (e993000c)
All code
========
   0:	c03c6305 	eorsgt	r6, ip, r5, lsl #6
   4:	c03c631e 	eorsgt	r6, ip, lr, lsl r3
   8:	c03c632e 	eorsgt	r6, ip, lr, lsr #6
   c:	e5903048 	ldr	r3, [r0, #72]	; 0x48
  10:*	e993000c 	ldmib	r3, {r2, r3}		<-- trapping instruction

Code starting with the faulting instruction
===========================================
   0:	e993000c 	ldmib	r3, {r2, r3}
[    0.786319] ---[ end trace 5264be19ef367bea ]---
[    0.791201] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    0.791201]
[    0.800441] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pcmcia/pxa2xx_base.c    | 9 +++++----
 drivers/pcmcia/pxa2xx_base.h    | 2 +-
 drivers/pcmcia/sa1111_lubbock.c | 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 483f919e0d2e..91b5f5724cba 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -214,9 +214,8 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
 }
 #endif
 
-void pxa2xx_configure_sockets(struct device *dev)
+void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops)
 {
-	struct pcmcia_low_level *ops = dev->platform_data;
 	/*
 	 * We have at least one socket, so set MECR:CIT
 	 * (Card Is There)
@@ -322,7 +321,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 			goto err1;
 	}
 
-	pxa2xx_configure_sockets(&dev->dev);
+	pxa2xx_configure_sockets(&dev->dev, ops);
 	dev_set_drvdata(&dev->dev, sinfo);
 
 	return 0;
@@ -348,7 +347,9 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
 
 static int pxa2xx_drv_pcmcia_resume(struct device *dev)
 {
-	pxa2xx_configure_sockets(dev);
+	struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data;
+
+	pxa2xx_configure_sockets(dev, ops);
 	return 0;
 }
 
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
index b609b45469ed..e58c7a415418 100644
--- a/drivers/pcmcia/pxa2xx_base.h
+++ b/drivers/pcmcia/pxa2xx_base.h
@@ -1,4 +1,4 @@
 int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
-void pxa2xx_configure_sockets(struct device *dev);
+void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops);
 
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index 9d5ffc71ae51..7c1f0f6cd578 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -157,7 +157,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 
 	if (machine_is_lubbock()) {
 		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
-		pxa2xx_configure_sockets(&sadev->dev);
+		pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
 		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
 				pxa2xx_drv_pcmcia_add_one);
 	}
-- 
2.1.4


[3] Lubbock boot dmesg
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.8.0-rc3-00080-g1aaa68426f0c-dirty (rj@belgarion) (gcc version 4.9.2 ( 4.9.2-10) ) #2070 Wed Aug 31 23:51:13 CEST 2016
[    0.000000] CPU: XScale-PXA255 [69052d06] revision 6 (ARMv5TE), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: Intel DBPXA250 Development Platform (aka Lubbock)
[    0.000000] Ignoring tag cmdline (using the default kernel command line)
[    0.000000] earlycon: pxa0 at I/O port 0xf6200000 (options '115200n8')
[    0.000000] bootconsole [pxa0] enabled
[    0.000000] Memory policy: Data cache writeback
[    0.000000] Run Mode clock: 0.00MHz
[    0.000000] Turbo Mode clock: 0.00MHz
[    0.000000] Memory clock: 0.00MHz
[    0.000000] On node 0 totalpages: 16384
[    0.000000] free_area_init_node: node 0, pgdat c082816c, node_mem_map c3f79000
[    0.000000]   Normal zone: 128 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.230:192.168.1.5:192.168.1.1:255.255.255.0:lubbock nfsroot=/srv/nfs console=ttyS0,115200 mem=64M init=/init earlycon=pxa,io,0xf6200000,115200n8
[    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 56360K/65536K available (3239K kernel code, 138K rwdata, 796K rodata, 4024K init, 213K bss, 9176K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0331e10   (3240 kB)
[    0.000000]       .init : 0xc0418000 - 0xc0806000   (4024 kB)
[    0.000000]       .data : 0xc0806000 - 0xc0828900   ( 139 kB)
[    0.000000]        .bss : 0xc0828900 - 0xc085e000   ( 214 kB)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:16 nr_irqs:304 304
[    0.000114] sched_clock: 32 bits at 3686kHz, resolution 271ns, wraps every 582542222200ns
[    0.008566] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 518462577799 ns
[    0.018973] Console: colour dummy device 80x30
[    0.023584] Calibrating delay loop... 99.22 BogoMIPS (lpj=496128)
[    0.111082] pid_max: default: 32768 minimum: 301
[    0.116494] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.123275] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.135194] CPU: Testing write buffer coherency: ok
[    0.142953] Setting up static identity map for 0xa0008200 - 0xa000826c
[    0.158820] devtmpfs: initialized
[    0.174104] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.187473] NET: Registered protocol family 16
[    0.197820] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.230917] Lubbock configured to boot from Flash (bank 1)
[    0.244372] SA1111 Microprocessor Companion Chip: silicon revision 1, metal revision 1
[    0.256347] sa1111 sa1111: Providing IRQ336-390
[    0.341129] clocksource: Switched to clocksource oscr0
[    0.480900] NET: Registered protocol family 2
[    0.491029] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.498548] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.505134] TCP: Hash tables configured (established 1024 bind 1024)
[    0.512320] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.518318] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.526083] NET: Registered protocol family 1
[    0.533923] RPC: Registered named UNIX socket transport module.
[    0.539970] RPC: Registered udp transport module.
[    0.545013] RPC: Registered tcp transport module.
[    0.549769] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.611252] random: fast init done
[    4.602524] NetWinder Floating Point Emulator V0.97 (double precision)
[    4.618163] futex hash table entries: 256 (order: -1, 3072 bytes)
[    4.626714] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    4.744565] NFS: Registering the id_resolver key type
[    4.749885] Key type id_resolver registered
[    4.754304] Key type id_legacy registered
[    4.758459] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    4.765569] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    4.787241] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[    4.795072] io scheduler noop registered
[    4.799064] io scheduler deadline registered
[    4.805440] io scheduler cfq registered (default)
[    5.598819] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 921600) is a UART1
[    5.607998] console [ttyS0] enabled
[    5.615110] bootconsole [pxa0] disabled
[    5.626365] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 921600) is a UART2
[    5.638730] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 921600) is a UART3
[    5.794222] brd: module loaded
[    5.807555] Probing application-flash at physical address 0x00000000 (32-bit bankwidth)
[    5.816198] application-flash: Found 2 x16 devices at 0x0 in 32-bit bank. Manufacturer ID 0x000089 Chip ID 0x000018
[    5.826804] application-flash: Found an alias at 0x2000000 for the chip at 0x0
[    5.826893] Intel/Sharp Extended Query Table at 0x0031
[    5.832199] Intel/Sharp Extended Query Table at 0x0031
[    5.837431] Using buffer write method
[    5.841210] cfi_cmdset_0001: Erase suspend on write enabled
[    5.846884] erase region 0: offset=0x0,size=0x40000,blocks=128
[    5.847827] Searching for RedBoot partition table in application-flash at offset 0x1fc0000
[    5.866264] No RedBoot partition table detected in application-flash
[    5.873505] Creating 3 MTD partitions on "application-flash":
[    5.879560] 0x000000000000-0x000000040000 : "Bootloader"
[    5.897858] 0x000000040000-0x000000140000 : "Kernel"
[    5.915722] 0x000000140000-0x000002000000 : "Filesystem"
[    5.942646] Probing boot-rom at physical address 0x04000000 (32-bit bankwidth)
[    5.950187] boot-rom: Found 2 x16 devices at 0x0 in 32-bit bank. Manufacturer ID 0x000089 Chip ID 0x000018
[    5.960237] boot-rom: Found an alias at 0x2000000 for the chip at 0x0
[    5.960326] Intel/Sharp Extended Query Table at 0x0031
[    5.965630] Intel/Sharp Extended Query Table at 0x0031
[    5.970861] Using buffer write method
[    5.974639] cfi_cmdset_0001: Erase suspend on write enabled
[    5.980310] erase region 0: offset=0x0,size=0x40000,blocks=128
[    5.981318] Searching for RedBoot partition table in boot-rom at offset 0x1fc0000
[    5.998817] No RedBoot partition table detected in boot-rom
[    6.051635] smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@fluxnic.net>
[    6.065113] smc91x smc91x eth0: SMC91C94 (rev 9) at c4846c00 IRQ 307
[    6.071860]  [nowait]
[    6.074248] smc91x smc91x eth0: Ethernet addr: 00:02:b3:92:a8:21
[    6.081391] udc-core: couldn't find an available UDC - added [zero] to list of pending drivers
[    6.098363] mousedev: PS/2 mouse device common for all mice
[    6.116546] Key type dns_resolver registered
[    6.122655] XScale DSP coprocessor detected.
[    6.158065] smc91x smc91x eth0: link up
[    6.192158] IP-Config: Complete:
[    6.195595]      device=eth0, hwaddr=00:02:b3:92:a8:21, ipaddr=192.168.1.230, mask=255.255.255.0, gw=192.168.1.1
[    6.206072]      host=lubbock, domain=, nis-domain=(none)
[    6.211615]      bootserver=192.168.1.5, rootserver=192.168.1.5, rootpath=
[    6.280332] Freeing unused kernel memory: 4024K (c0418000 - c0806000)
[    6.287068] This architecture does not have kernel memory protection.
[    7.171675] atkbd serio0: keyboard reset failed on 0a00
[    7.177087] ------------[ cut here ]------------
[    7.181895] WARNING: CPU: 0 PID: 17 at kernel/irq/manage.c:527 enable_irq+0x58/0x70
[    7.189606] Unbalanced enable for IRQ 357
[    7.193662] Modules linked in:
[    7.196854] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2070
[    7.205878] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
[    7.213055] Workqueue: events_long serio_handle_event
[    7.218386] [<c0015260>] (unwind_backtrace) from [<c00122f0>] (show_stack+0x10/0x14)
[    7.226312] [<c00122f0>] (show_stack) from [<c001ea40>] (__warn+0xcc/0xf8)
[    7.233334] [<c001ea40>] (__warn) from [<c001eaa0>] (warn_slowpath_fmt+0x34/0x44)
[    7.240964] [<c001eaa0>] (warn_slowpath_fmt) from [<c0047d44>] (enable_irq+0x58/0x70)
[    7.248935] [<c0047d44>] (enable_irq) from [<c0250df4>] (ps2_write+0x4c/0x78)
[    7.256211] [<c0250df4>] (ps2_write) from [<c025107c>] (ps2_sendbyte+0x50/0x144)
[    7.263746] [<c025107c>] (ps2_sendbyte) from [<c02513b0>] (__ps2_command+0xc0/0x3c4)
[    7.271630] [<c02513b0>] (__ps2_command) from [<c02516d8>] (ps2_command+0x24/0x38)
[    7.279389] [<c02516d8>] (ps2_command) from [<c0259968>] (atkbd_probe+0x60/0x140)
[    7.287026] [<c0259968>] (atkbd_probe) from [<c025a950>] (atkbd_connect+0x130/0x238)
[    7.294901] [<c025a950>] (atkbd_connect) from [<c0250ae4>] (serio_driver_probe+0x28/0x3c)
[    7.303251] [<c0250ae4>] (serio_driver_probe) from [<c020c410>] (driver_probe_device+0x124/0x28c)
[    7.312276] [<c020c410>] (driver_probe_device) from [<c020c5f8>] (__driver_attach+0x80/0xa4)
[    7.320852] [<c020c5f8>] (__driver_attach) from [<c020ac5c>] (bus_for_each_dev+0x6c/0x90)
[    7.329167] [<c020ac5c>] (bus_for_each_dev) from [<c0250984>] (serio_handle_event+0x154/0x1a0)
[    7.337933] [<c0250984>] (serio_handle_event) from [<c0030638>] (process_one_work+0x1bc/0x300)
[    7.346688] [<c0030638>] (process_one_work) from [<c0030d1c>] (worker_thread+0x2bc/0x3f8)
[    7.355043] [<c0030d1c>] (worker_thread) from [<c0034da0>] (kthread+0xc4/0xd8)
[    7.362418] [<c0034da0>] (kthread) from [<c000f0f0>] (ret_from_fork+0x14/0x24)
[    7.369720] ---[ end trace 52001af966019111 ]---
[    9.091294] atkbd serio1: keyboard reset failed on 0c00
[    9.096726] ------------[ cut here ]------------
[    9.101541] WARNING: CPU: 0 PID: 17 at kernel/irq/manage.c:527 enable_irq+0x58/0x70
[    9.109261] Unbalanced enable for IRQ 354
[    9.113316] Modules linked in:
[    9.116506] CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G        W       4.8.0-rc3-00080-g1aaa68426f0c-dirty #2070
[    9.126747] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
[    9.133922] Workqueue: events_long serio_handle_event
[    9.139247] [<c0015260>] (unwind_backtrace) from [<c00122f0>] (show_stack+0x10/0x14)
[    9.147172] [<c00122f0>] (show_stack) from [<c001ea40>] (__warn+0xcc/0xf8)
[    9.154195] [<c001ea40>] (__warn) from [<c001eaa0>] (warn_slowpath_fmt+0x34/0x44)
[    9.161824] [<c001eaa0>] (warn_slowpath_fmt) from [<c0047d44>] (enable_irq+0x58/0x70)
[    9.169796] [<c0047d44>] (enable_irq) from [<c0250df4>] (ps2_write+0x4c/0x78)
[    9.177072] [<c0250df4>] (ps2_write) from [<c025107c>] (ps2_sendbyte+0x50/0x144)
[    9.184608] [<c025107c>] (ps2_sendbyte) from [<c02513b0>] (__ps2_command+0xc0/0x3c4)
[    9.192491] [<c02513b0>] (__ps2_command) from [<c02516d8>] (ps2_command+0x24/0x38)
[    9.200250] [<c02516d8>] (ps2_command) from [<c0259968>] (atkbd_probe+0x60/0x140)
[    9.207886] [<c0259968>] (atkbd_probe) from [<c025a950>] (atkbd_connect+0x130/0x238)
[    9.215770] [<c025a950>] (atkbd_connect) from [<c0250ae4>] (serio_driver_probe+0x28/0x3c)
[    9.224120] [<c0250ae4>] (serio_driver_probe) from [<c020c410>] (driver_probe_device+0x124/0x28c)
[    9.233143] [<c020c410>] (driver_probe_device) from [<c020c5f8>] (__driver_attach+0x80/0xa4)
[    9.241720] [<c020c5f8>] (__driver_attach) from [<c020ac5c>] (bus_for_each_dev+0x6c/0x90)
[    9.250037] [<c020ac5c>] (bus_for_each_dev) from [<c0250984>] (serio_handle_event+0x154/0x1a0)
[    9.258802] [<c0250984>] (serio_handle_event) from [<c0030638>] (process_one_work+0x1bc/0x300)
[    9.267556] [<c0030638>] (process_one_work) from [<c0030d1c>] (worker_thread+0x2bc/0x3f8)
[    9.275912] [<c0030d1c>] (worker_thread) from [<c0034da0>] (kthread+0xc4/0xd8)
[    9.283287] [<c0034da0>] (kthread) from [<c000f0f0>] (ret_from_fork+0x14/0x24)
[    9.290587] ---[ end trace 52001af966019112 ]---
[  118.294784] random: crng init done

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-01  7:19                     ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-01  7:19 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Wed, Aug 31, 2016 at 09:49:38AM +0100, Russell King - ARM Linux wrote:
>> On Tue, Aug 30, 2016 at 11:32:16PM +0200, Robert Jarzmik wrote:
>> > Russell King - ARM Linux <linux@armlinux.org.uk> writes:
>> > 
>> > > If you can wait a day or two, I'll push a branch out for everything in
>> > > all these multiple series.
>> > Sure, just ping me when you have something.
>> 
>> git://git.armlinux.org.uk/~rmk/linux-arm.git sa1100
>> 
>> should get you something suitable to test.  It's based on 4.7-rc3 plus
>> my fixes branch.
>> 
>> It would be great to have this tested on Lubbock, and get the PCMCIA
>> issues fixed.
Ok Russell, I run a first mini-test.

I used :
 - one trivial typo fix of your patches in [1]
 - one "make it better fix" in [2] to pass the pcmcia probe, without much
   thinking about it, just to have the probe finished

The result today is that my PCMCIA card inserted in Lubbock's slot is not
detected, but that's not really a surprise. As a matter of fact, I didn't look
much into it, the only data points I have are :
 - PCMCIA is probed now
   - this is based on dmesg in [3]
   - this is also based on ls /sys/bus/sa1111-rab/devices/1800
	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 driver -> ../../../../bus/sa1111-rab/drivers/sa1111-pcmcia
	drwxr-xr-x    2 root     root             0 Jan  1 00:15 power
	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 subsystem -> ../../../../bus/sa1111-rab
	-rw-r--r--    1 root     root          4096 Jan  1 00:15 uevent

 - PCMCIA sockets are not there
   - this is based on ls /sys/class/pcmcia_socket/ where there is nothing

 - MAX16xx gpio are not claimed, which is surprising
   - this is based on cat /sys/kernel/debug/gpio
	gpiochip0: GPIOs 0-84, gpio-pxa:
	gpiochip2: GPIOs 478-495, parent: platform/sa1111, sa1111:
	gpiochip1: GPIOs 496-511, lubbock:

I'm not familiar with drivers/pcmcia part of the kernel tree so I won't be fast
to go down to the problem, but I'll try in the next days. Maybe if I activate
debug logs in pcmcia related parts I'll find out more quickly what is happening.

> Maybe we can look at converting mainstone as well?
Yep.

> This follows the Cirrus code (also used by Lubbock.)  So, if we represent the
> MST_PCMCIA[01] registers as GPIOs, we can switch pxa2xx_mainstone.c to use the
> max1600.c code for power control.
Yes.

> There is a slight issue, which is that the interrupts can't be translated to
> an interrupt by gpio-reg, which will currently cause soc_common problems - but
> that's an easy fix, though leaves us with more code than I'd desire in
> pxa2xx_mainstone.c.  Maybe a solution there would be to have gpio-reg also
> take an array of interrupt numbers... not sure yet.
Normally these interrupts are already dealt with by
arch/arm/mach-pxa/pxa_cplds_irq.c, which adds an irqdomain for them. The missing
part is the "gpio to interrupt" translation part, right ? This is where your
array comes into play if I get your right, to be the input of the to_irq()
function of the gpiochip.

As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
so that your translation is only a linear irq = gpio + offset ?

> For IrDA, it looks like it has the same transceiver as the assabet, so I've
> (already) patches to split out the gpio-based transceiver control from
> sa1100_ir - maybe we can re-use that in pxaficp_ir too.
Once PCMCIA is over, sure.

Cheers.

--
Robert

[1] Typo fix
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index f034928b99a1..81a1de6fb46f 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -13,7 +13,7 @@
  */
 #include <linux/clkdev.h>
 #include <linux/gpio.h>
-#include <linux/gpip/gpio-reg.h>
+#include <linux/gpio/gpio-reg.h>
 #include <linux/gpio/machine.h>
 #include <linux/module.h>
 #include <linux/kernel.h>

[2] Kind-of fix for lubbock pcmcia probe
>From 977c16201a752aac8a8fb2da1f4271795f0b2122 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Thu, 1 Sep 2016 08:31:08 +0200
Subject: [PATCH] pcmcia: lubbock: fix sockets configuration

On lubbock board, the probe of the driver crashes by dereferencing very
early a platform_data structure which is not set, in
pxa2xx_configure_sockets().

This patch blindly fixes it without any analysis as to know if it's the
right fix or even if the fix doesn't break in suspend/resume.

The stack fixed is :
[    0.244353] SA1111 Microprocessor Companion Chip: silicon revision 1, metal revision 1
[    0.256321] sa1111 sa1111: Providing IRQ336-390
[    0.340899] clocksource: Switched to clocksource oscr0
[    0.472263] Unable to handle kernel NULL pointer dereference at virtual address 00000004
[    0.480469] pgd = c0004000
[    0.483432] [00000004] *pgd=00000000
[    0.487105] Internal error: Oops: f5 [#1] ARM
[    0.491497] Modules linked in:
[    0.494650] CPU: 0 PID: 1 Comm: swapper Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2068
[    0.503229] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
[    0.510344] task: c3e42000 task.stack: c3e44000
[    0.514984] PC is at pxa2xx_configure_sockets+0x4/0x24 (drivers/pcmcia/pxa2xx_base.c:227)
[    0.520193] LR is at pcmcia_lubbock_init+0x1c/0x38
[    0.525079] pc : [<c0247c30>]    lr : [<c02479b0>]    psr: a0000053
[    0.525079] sp : c3e45e70  ip : 100019ff  fp : 00000000
[    0.536651] r10: c0828900  r9 : c0434838  r8 : 00000000
[    0.541953] r7 : c0820700  r6 : c0857b30  r5 : c3ec1400  r4 : c0820758
[    0.548549] r3 : 00000000  r2 : 0000000c  r1 : c3c09c40  r0 : c3ec1400
[    0.555154] Flags: NzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
[    0.562450] Control: 0000397f  Table: a0004000  DAC: 00000053
[    0.568257] Process swapper (pid: 1, stack limit = 0xc3e44190)
[    0.574154] Stack: (0xc3e45e70 to 0xc3e46000)
[    0.578610] 5e60:                                     c4849800 00000000 c3ec1400 c024769c
[    0.586928] 5e80: 00000000 c3ec140c c3c0ee0c c3ec1400 c3ec1434 c020c410 c3ec1400 c3ec1434
[    0.595244] 5ea0: c0820700 c080b408 c0828900 c020c5f8 00000000 c0820700 c020c578 c020ac5c
[    0.603560] 5ec0: c3e687cc c3e71e10 c0820700 00000000 c3c02de0 c020bae4 c03c62f7 c03c62f7
[    0.611872] 5ee0: c3e68780 c0820700 c042e034 00000000 c043c440 c020cdec c080b408 00000005
[    0.620188] 5f00: c042e034 c00096c0 c0034440 c01c730c 20000053 ffffffff 00000000 00000000
[    0.628502] 5f20: 00000000 c3ffcb87 c3ffcb90 c00346ac c3e66ba0 c03f7914 00000092 00000005
[    0.636811] 5f40: 00000005 c03f847c 00000091 c03f847c 00000000 00000005 c0434828 00000005
[    0.645125] 5f60: c043482c 00000092 c043c440 c0828900 c0434838 c0418d2c 00000005 00000005
[    0.653430] 5f80: 00000000 c041858c 00000000 c032e9f0 00000000 00000000 00000000 00000000
[    0.661729] 5fa0: 00000000 c032e9f8 00000000 c000f0f0 00000000 00000000 00000000 00000000
[    0.670020] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    0.678311] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
[    0.686673] (pxa2xx_configure_sockets) from pcmcia_lubbock_init (/drivers/pcmcia/sa1111_lubbock.c:161)
[    0.696026] (pcmcia_lubbock_init) from pcmcia_probe (/drivers/pcmcia/sa1111_generic.c:213)
[    0.704358] (pcmcia_probe) from driver_probe_device (/drivers/base/dd.c:378 /drivers/base/dd.c:499)
[    0.712848] (driver_probe_device) from __driver_attach (/./include/linux/device.h:983 /drivers/base/dd.c:733)
[    0.721414] (__driver_attach) from bus_for_each_dev (/drivers/base/bus.c:313)
[    0.729723] (bus_for_each_dev) from bus_add_driver (/drivers/base/bus.c:708)
[    0.738036] (bus_add_driver) from driver_register (/drivers/base/driver.c:169)
[    0.746185] (driver_register) from do_one_initcall (/init/main.c:778)
[    0.754561] (do_one_initcall) from kernel_init_freeable (/init/main.c:843 /init/main.c:851 /init/main.c:869 /init/main.c:1016)
[    0.763409] (kernel_init_freeable) from kernel_init (/init/main.c:944)
[    0.771660] (kernel_init) from ret_from_fork (/arch/arm/kernel/entry-common.S:119)
[ 0.779347] Code: c03c6305 c03c631e c03c632e e5903048 (e993000c)
All code
========
   0:	c03c6305 	eorsgt	r6, ip, r5, lsl #6
   4:	c03c631e 	eorsgt	r6, ip, lr, lsl r3
   8:	c03c632e 	eorsgt	r6, ip, lr, lsr #6
   c:	e5903048 	ldr	r3, [r0, #72]	; 0x48
  10:*	e993000c 	ldmib	r3, {r2, r3}		<-- trapping instruction

Code starting with the faulting instruction
===========================================
   0:	e993000c 	ldmib	r3, {r2, r3}
[    0.786319] ---[ end trace 5264be19ef367bea ]---
[    0.791201] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    0.791201]
[    0.800441] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/pcmcia/pxa2xx_base.c    | 9 +++++----
 drivers/pcmcia/pxa2xx_base.h    | 2 +-
 drivers/pcmcia/sa1111_lubbock.c | 2 +-
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 483f919e0d2e..91b5f5724cba 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -214,9 +214,8 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
 }
 #endif
 
-void pxa2xx_configure_sockets(struct device *dev)
+void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops)
 {
-	struct pcmcia_low_level *ops = dev->platform_data;
 	/*
 	 * We have at least one socket, so set MECR:CIT
 	 * (Card Is There)
@@ -322,7 +321,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 			goto err1;
 	}
 
-	pxa2xx_configure_sockets(&dev->dev);
+	pxa2xx_configure_sockets(&dev->dev, ops);
 	dev_set_drvdata(&dev->dev, sinfo);
 
 	return 0;
@@ -348,7 +347,9 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
 
 static int pxa2xx_drv_pcmcia_resume(struct device *dev)
 {
-	pxa2xx_configure_sockets(dev);
+	struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data;
+
+	pxa2xx_configure_sockets(dev, ops);
 	return 0;
 }
 
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
index b609b45469ed..e58c7a415418 100644
--- a/drivers/pcmcia/pxa2xx_base.h
+++ b/drivers/pcmcia/pxa2xx_base.h
@@ -1,4 +1,4 @@
 int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
-void pxa2xx_configure_sockets(struct device *dev);
+void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops);
 
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
index 9d5ffc71ae51..7c1f0f6cd578 100644
--- a/drivers/pcmcia/sa1111_lubbock.c
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -157,7 +157,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
 
 	if (machine_is_lubbock()) {
 		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
-		pxa2xx_configure_sockets(&sadev->dev);
+		pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
 		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
 				pxa2xx_drv_pcmcia_add_one);
 	}
-- 
2.1.4


[3] Lubbock boot dmesg
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.8.0-rc3-00080-g1aaa68426f0c-dirty (rj at belgarion) (gcc version 4.9.2 ( 4.9.2-10) ) #2070 Wed Aug 31 23:51:13 CEST 2016
[    0.000000] CPU: XScale-PXA255 [69052d06] revision 6 (ARMv5TE), cr=0000397f
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] Machine: Intel DBPXA250 Development Platform (aka Lubbock)
[    0.000000] Ignoring tag cmdline (using the default kernel command line)
[    0.000000] earlycon: pxa0 at I/O port 0xf6200000 (options '115200n8')
[    0.000000] bootconsole [pxa0] enabled
[    0.000000] Memory policy: Data cache writeback
[    0.000000] Run Mode clock: 0.00MHz
[    0.000000] Turbo Mode clock: 0.00MHz
[    0.000000] Memory clock: 0.00MHz
[    0.000000] On node 0 totalpages: 16384
[    0.000000] free_area_init_node: node 0, pgdat c082816c, node_mem_map c3f79000
[    0.000000]   Normal zone: 128 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 16384 pages, LIFO batch:3
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
[    0.000000] Kernel command line: root=/dev/ram0 ip=192.168.1.230:192.168.1.5:192.168.1.1:255.255.255.0:lubbock nfsroot=/srv/nfs console=ttyS0,115200 mem=64M init=/init earlycon=pxa,io,0xf6200000,115200n8
[    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 56360K/65536K available (3239K kernel code, 138K rwdata, 796K rodata, 4024K init, 213K bss, 9176K reserved, 0K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xc4800000 - 0xff800000   ( 944 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
[    0.000000]     modules : 0xbf000000 - 0xc0000000   (  16 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0331e10   (3240 kB)
[    0.000000]       .init : 0xc0418000 - 0xc0806000   (4024 kB)
[    0.000000]       .data : 0xc0806000 - 0xc0828900   ( 139 kB)
[    0.000000]        .bss : 0xc0828900 - 0xc085e000   ( 214 kB)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:16 nr_irqs:304 304
[    0.000114] sched_clock: 32 bits at 3686kHz, resolution 271ns, wraps every 582542222200ns
[    0.008566] clocksource: oscr0: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 518462577799 ns
[    0.018973] Console: colour dummy device 80x30
[    0.023584] Calibrating delay loop... 99.22 BogoMIPS (lpj=496128)
[    0.111082] pid_max: default: 32768 minimum: 301
[    0.116494] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.123275] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.135194] CPU: Testing write buffer coherency: ok
[    0.142953] Setting up static identity map for 0xa0008200 - 0xa000826c
[    0.158820] devtmpfs: initialized
[    0.174104] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.187473] NET: Registered protocol family 16
[    0.197820] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.230917] Lubbock configured to boot from Flash (bank 1)
[    0.244372] SA1111 Microprocessor Companion Chip: silicon revision 1, metal revision 1
[    0.256347] sa1111 sa1111: Providing IRQ336-390
[    0.341129] clocksource: Switched to clocksource oscr0
[    0.480900] NET: Registered protocol family 2
[    0.491029] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.498548] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.505134] TCP: Hash tables configured (established 1024 bind 1024)
[    0.512320] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.518318] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.526083] NET: Registered protocol family 1
[    0.533923] RPC: Registered named UNIX socket transport module.
[    0.539970] RPC: Registered udp transport module.
[    0.545013] RPC: Registered tcp transport module.
[    0.549769] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    2.611252] random: fast init done
[    4.602524] NetWinder Floating Point Emulator V0.97 (double precision)
[    4.618163] futex hash table entries: 256 (order: -1, 3072 bytes)
[    4.626714] workingset: timestamp_bits=30 max_order=14 bucket_order=0
[    4.744565] NFS: Registering the id_resolver key type
[    4.749885] Key type id_resolver registered
[    4.754304] Key type id_legacy registered
[    4.758459] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    4.765569] jffs2: version 2.2. (NAND) ? 2001-2006 Red Hat, Inc.
[    4.787241] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[    4.795072] io scheduler noop registered
[    4.799064] io scheduler deadline registered
[    4.805440] io scheduler cfq registered (default)
[    5.598819] pxa2xx-uart.0: ttyS0 at MMIO 0x40100000 (irq = 38, base_baud = 921600) is a UART1
[    5.607998] console [ttyS0] enabled
[    5.615110] bootconsole [pxa0] disabled
[    5.626365] pxa2xx-uart.1: ttyS1 at MMIO 0x40200000 (irq = 37, base_baud = 921600) is a UART2
[    5.638730] pxa2xx-uart.2: ttyS2 at MMIO 0x40700000 (irq = 36, base_baud = 921600) is a UART3
[    5.794222] brd: module loaded
[    5.807555] Probing application-flash at physical address 0x00000000 (32-bit bankwidth)
[    5.816198] application-flash: Found 2 x16 devices at 0x0 in 32-bit bank. Manufacturer ID 0x000089 Chip ID 0x000018
[    5.826804] application-flash: Found an alias at 0x2000000 for the chip at 0x0
[    5.826893] Intel/Sharp Extended Query Table at 0x0031
[    5.832199] Intel/Sharp Extended Query Table at 0x0031
[    5.837431] Using buffer write method
[    5.841210] cfi_cmdset_0001: Erase suspend on write enabled
[    5.846884] erase region 0: offset=0x0,size=0x40000,blocks=128
[    5.847827] Searching for RedBoot partition table in application-flash at offset 0x1fc0000
[    5.866264] No RedBoot partition table detected in application-flash
[    5.873505] Creating 3 MTD partitions on "application-flash":
[    5.879560] 0x000000000000-0x000000040000 : "Bootloader"
[    5.897858] 0x000000040000-0x000000140000 : "Kernel"
[    5.915722] 0x000000140000-0x000002000000 : "Filesystem"
[    5.942646] Probing boot-rom at physical address 0x04000000 (32-bit bankwidth)
[    5.950187] boot-rom: Found 2 x16 devices at 0x0 in 32-bit bank. Manufacturer ID 0x000089 Chip ID 0x000018
[    5.960237] boot-rom: Found an alias at 0x2000000 for the chip at 0x0
[    5.960326] Intel/Sharp Extended Query Table at 0x0031
[    5.965630] Intel/Sharp Extended Query Table at 0x0031
[    5.970861] Using buffer write method
[    5.974639] cfi_cmdset_0001: Erase suspend on write enabled
[    5.980310] erase region 0: offset=0x0,size=0x40000,blocks=128
[    5.981318] Searching for RedBoot partition table in boot-rom at offset 0x1fc0000
[    5.998817] No RedBoot partition table detected in boot-rom
[    6.051635] smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@fluxnic.net>
[    6.065113] smc91x smc91x eth0: SMC91C94 (rev 9) at c4846c00 IRQ 307
[    6.071860]  [nowait]
[    6.074248] smc91x smc91x eth0: Ethernet addr: 00:02:b3:92:a8:21
[    6.081391] udc-core: couldn't find an available UDC - added [zero] to list of pending drivers
[    6.098363] mousedev: PS/2 mouse device common for all mice
[    6.116546] Key type dns_resolver registered
[    6.122655] XScale DSP coprocessor detected.
[    6.158065] smc91x smc91x eth0: link up
[    6.192158] IP-Config: Complete:
[    6.195595]      device=eth0, hwaddr=00:02:b3:92:a8:21, ipaddr=192.168.1.230, mask=255.255.255.0, gw=192.168.1.1
[    6.206072]      host=lubbock, domain=, nis-domain=(none)
[    6.211615]      bootserver=192.168.1.5, rootserver=192.168.1.5, rootpath=
[    6.280332] Freeing unused kernel memory: 4024K (c0418000 - c0806000)
[    6.287068] This architecture does not have kernel memory protection.
[    7.171675] atkbd serio0: keyboard reset failed on 0a00
[    7.177087] ------------[ cut here ]------------
[    7.181895] WARNING: CPU: 0 PID: 17 at kernel/irq/manage.c:527 enable_irq+0x58/0x70
[    7.189606] Unbalanced enable for IRQ 357
[    7.193662] Modules linked in:
[    7.196854] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2070
[    7.205878] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
[    7.213055] Workqueue: events_long serio_handle_event
[    7.218386] [<c0015260>] (unwind_backtrace) from [<c00122f0>] (show_stack+0x10/0x14)
[    7.226312] [<c00122f0>] (show_stack) from [<c001ea40>] (__warn+0xcc/0xf8)
[    7.233334] [<c001ea40>] (__warn) from [<c001eaa0>] (warn_slowpath_fmt+0x34/0x44)
[    7.240964] [<c001eaa0>] (warn_slowpath_fmt) from [<c0047d44>] (enable_irq+0x58/0x70)
[    7.248935] [<c0047d44>] (enable_irq) from [<c0250df4>] (ps2_write+0x4c/0x78)
[    7.256211] [<c0250df4>] (ps2_write) from [<c025107c>] (ps2_sendbyte+0x50/0x144)
[    7.263746] [<c025107c>] (ps2_sendbyte) from [<c02513b0>] (__ps2_command+0xc0/0x3c4)
[    7.271630] [<c02513b0>] (__ps2_command) from [<c02516d8>] (ps2_command+0x24/0x38)
[    7.279389] [<c02516d8>] (ps2_command) from [<c0259968>] (atkbd_probe+0x60/0x140)
[    7.287026] [<c0259968>] (atkbd_probe) from [<c025a950>] (atkbd_connect+0x130/0x238)
[    7.294901] [<c025a950>] (atkbd_connect) from [<c0250ae4>] (serio_driver_probe+0x28/0x3c)
[    7.303251] [<c0250ae4>] (serio_driver_probe) from [<c020c410>] (driver_probe_device+0x124/0x28c)
[    7.312276] [<c020c410>] (driver_probe_device) from [<c020c5f8>] (__driver_attach+0x80/0xa4)
[    7.320852] [<c020c5f8>] (__driver_attach) from [<c020ac5c>] (bus_for_each_dev+0x6c/0x90)
[    7.329167] [<c020ac5c>] (bus_for_each_dev) from [<c0250984>] (serio_handle_event+0x154/0x1a0)
[    7.337933] [<c0250984>] (serio_handle_event) from [<c0030638>] (process_one_work+0x1bc/0x300)
[    7.346688] [<c0030638>] (process_one_work) from [<c0030d1c>] (worker_thread+0x2bc/0x3f8)
[    7.355043] [<c0030d1c>] (worker_thread) from [<c0034da0>] (kthread+0xc4/0xd8)
[    7.362418] [<c0034da0>] (kthread) from [<c000f0f0>] (ret_from_fork+0x14/0x24)
[    7.369720] ---[ end trace 52001af966019111 ]---
[    9.091294] atkbd serio1: keyboard reset failed on 0c00
[    9.096726] ------------[ cut here ]------------
[    9.101541] WARNING: CPU: 0 PID: 17 at kernel/irq/manage.c:527 enable_irq+0x58/0x70
[    9.109261] Unbalanced enable for IRQ 354
[    9.113316] Modules linked in:
[    9.116506] CPU: 0 PID: 17 Comm: kworker/0:1 Tainted: G        W       4.8.0-rc3-00080-g1aaa68426f0c-dirty #2070
[    9.126747] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
[    9.133922] Workqueue: events_long serio_handle_event
[    9.139247] [<c0015260>] (unwind_backtrace) from [<c00122f0>] (show_stack+0x10/0x14)
[    9.147172] [<c00122f0>] (show_stack) from [<c001ea40>] (__warn+0xcc/0xf8)
[    9.154195] [<c001ea40>] (__warn) from [<c001eaa0>] (warn_slowpath_fmt+0x34/0x44)
[    9.161824] [<c001eaa0>] (warn_slowpath_fmt) from [<c0047d44>] (enable_irq+0x58/0x70)
[    9.169796] [<c0047d44>] (enable_irq) from [<c0250df4>] (ps2_write+0x4c/0x78)
[    9.177072] [<c0250df4>] (ps2_write) from [<c025107c>] (ps2_sendbyte+0x50/0x144)
[    9.184608] [<c025107c>] (ps2_sendbyte) from [<c02513b0>] (__ps2_command+0xc0/0x3c4)
[    9.192491] [<c02513b0>] (__ps2_command) from [<c02516d8>] (ps2_command+0x24/0x38)
[    9.200250] [<c02516d8>] (ps2_command) from [<c0259968>] (atkbd_probe+0x60/0x140)
[    9.207886] [<c0259968>] (atkbd_probe) from [<c025a950>] (atkbd_connect+0x130/0x238)
[    9.215770] [<c025a950>] (atkbd_connect) from [<c0250ae4>] (serio_driver_probe+0x28/0x3c)
[    9.224120] [<c0250ae4>] (serio_driver_probe) from [<c020c410>] (driver_probe_device+0x124/0x28c)
[    9.233143] [<c020c410>] (driver_probe_device) from [<c020c5f8>] (__driver_attach+0x80/0xa4)
[    9.241720] [<c020c5f8>] (__driver_attach) from [<c020ac5c>] (bus_for_each_dev+0x6c/0x90)
[    9.250037] [<c020ac5c>] (bus_for_each_dev) from [<c0250984>] (serio_handle_event+0x154/0x1a0)
[    9.258802] [<c0250984>] (serio_handle_event) from [<c0030638>] (process_one_work+0x1bc/0x300)
[    9.267556] [<c0030638>] (process_one_work) from [<c0030d1c>] (worker_thread+0x2bc/0x3f8)
[    9.275912] [<c0030d1c>] (worker_thread) from [<c0034da0>] (kthread+0xc4/0xd8)
[    9.283287] [<c0034da0>] (kthread) from [<c000f0f0>] (ret_from_fork+0x14/0x24)
[    9.290587] ---[ end trace 52001af966019112 ]---
[  118.294784] random: crng init done

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-09-01  7:19                     ` Robert Jarzmik
@ 2016-09-01  9:27                       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-01  9:27 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

On Thu, Sep 01, 2016 at 09:19:13AM +0200, Robert Jarzmik wrote:
> The result today is that my PCMCIA card inserted in Lubbock's slot is not
> detected, but that's not really a surprise. As a matter of fact, I didn't
> look much into it, the only data points I have are :
>  - PCMCIA is probed now
>    - this is based on dmesg in [3]
>    - this is also based on ls /sys/bus/sa1111-rab/devices/1800
> 	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 driver -> ../../../../bus/sa1111-rab/drivers/sa1111-pcmcia
> 	drwxr-xr-x    2 root     root             0 Jan  1 00:15 power
> 	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 subsystem -> ../../../../bus/sa1111-rab
> 	-rw-r--r--    1 root     root          4096 Jan  1 00:15 uevent
> 
>  - PCMCIA sockets are not there
>    - this is based on ls /sys/class/pcmcia_socket/ where there is nothing
> 
>  - MAX16xx gpio are not claimed, which is surprising
>    - this is based on cat /sys/kernel/debug/gpio
> 	gpiochip0: GPIOs 0-84, gpio-pxa:
> 	gpiochip2: GPIOs 478-495, parent: platform/sa1111, sa1111:
> 	gpiochip1: GPIOs 496-511, lubbock:

It looks like:

(a) pcmcia_probe() in drivers/pcmcia/sa1111_generic.c doesn't check the
    return value from the platform specific init functions, meaning if
    they fail, the driver still binds.  (note: they return -ENODEV to
    indicate that they should skip to the next platform.)
(b) there is no clock provided for the sa1111 pcmcia device (aka "1800").
    This should be the same clock as pxa2xx-pcmcia.

> > There is a slight issue, which is that the interrupts can't be translated to
> > an interrupt by gpio-reg, which will currently cause soc_common problems - but
> > that's an easy fix, though leaves us with more code than I'd desire in
> > pxa2xx_mainstone.c.  Maybe a solution there would be to have gpio-reg also
> > take an array of interrupt numbers... not sure yet.
>
> Normally these interrupts are already dealt with by
> arch/arm/mach-pxa/pxa_cplds_irq.c, which adds an irqdomain for them. The missing
> part is the "gpio to interrupt" translation part, right ? This is where your
> array comes into play if I get your right, to be the input of the to_irq()
> function of the gpiochip.

Yes.

> As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
> so that your translation is only a linear irq = gpio + offset ?

There isn't a linear translation here:

#define MST_PCMCIA_nIRQ         (1 << 10)  /* IRQ / ready signal */
#define MST_PCMCIA_nSPKR_BVD2   (1 << 9)   /* VDD sense / digital speaker */
#define MST_PCMCIA_nSTSCHG_BVD1 (1 << 8)   /* VDD sense / card status changed */#define MST_PCMCIA_nVS2         (1 << 7)   /* VSS voltage sense */
#define MST_PCMCIA_nVS1         (1 << 6)   /* VSS voltage sense */
#define MST_PCMCIA_nCD          (1 << 5)   /* Card detection signal */
#define MST_PCMCIA_RESET        (1 << 4)   /* Card reset signal */
#define MST_PCMCIA_PWR_MASK     (0x000f)   /* MAX1602 power-supply controls */

#define MAINSTONE_S0_CD_IRQ     MAINSTONE_IRQ(9)
#define MAINSTONE_S0_STSCHG_IRQ MAINSTONE_IRQ(10)
#define MAINSTONE_S0_IRQ        MAINSTONE_IRQ(11)
#define MAINSTONE_S1_CD_IRQ     MAINSTONE_IRQ(13)
#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
#define MAINSTONE_S1_IRQ        MAINSTONE_IRQ(15)

MST_PCMCIA_nCD		=> MAINSTONE_S0_CD_IRQ or MAINSTONE_S1_CD_IRQ
MST_PCMCIA_nSTSCHG_BVD1 => MAINSTONE_S0_STSCHG_IRQ or MAINSTONE_S1_STSCHG_IRQ
MST_PCMCIA_nIRQ		=> MAINSTONE_S0_IRQ or MAINSTONE_S1_IRQ

So they aren't linear, and every "gpio" doesn't have a corresponding
interrupt.

> [1] Typo fix
> diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
> index f034928b99a1..81a1de6fb46f 100644
> --- a/arch/arm/mach-pxa/lubbock.c
> +++ b/arch/arm/mach-pxa/lubbock.c
> @@ -13,7 +13,7 @@
>   */
>  #include <linux/clkdev.h>
>  #include <linux/gpio.h>
> -#include <linux/gpip/gpio-reg.h>
> +#include <linux/gpio/gpio-reg.h>
>  #include <linux/gpio/machine.h>
>  #include <linux/module.h>
>  #include <linux/kernel.h>

Fixed.

> [2] Kind-of fix for lubbock pcmcia probe
> >From 977c16201a752aac8a8fb2da1f4271795f0b2122 Mon Sep 17 00:00:00 2001
> From: Robert Jarzmik <robert.jarzmik@free.fr>
> Date: Thu, 1 Sep 2016 08:31:08 +0200
> Subject: [PATCH] pcmcia: lubbock: fix sockets configuration
> 
> On lubbock board, the probe of the driver crashes by dereferencing very
> early a platform_data structure which is not set, in
> pxa2xx_configure_sockets().
> 
> This patch blindly fixes it without any analysis as to know if it's the
> right fix or even if the fix doesn't break in suspend/resume.
> 
> The stack fixed is :
> [    0.244353] SA1111 Microprocessor Companion Chip: silicon revision 1, metal revision 1
> [    0.256321] sa1111 sa1111: Providing IRQ336-390
> [    0.340899] clocksource: Switched to clocksource oscr0
> [    0.472263] Unable to handle kernel NULL pointer dereference at virtual address 00000004
> [    0.480469] pgd = c0004000
> [    0.483432] [00000004] *pgd=00000000
> [    0.487105] Internal error: Oops: f5 [#1] ARM
> [    0.491497] Modules linked in:
> [    0.494650] CPU: 0 PID: 1 Comm: swapper Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2068
> [    0.503229] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
> [    0.510344] task: c3e42000 task.stack: c3e44000
> [    0.514984] PC is at pxa2xx_configure_sockets+0x4/0x24 (drivers/pcmcia/pxa2xx_base.c:227)
> [    0.520193] LR is at pcmcia_lubbock_init+0x1c/0x38
> [    0.525079] pc : [<c0247c30>]    lr : [<c02479b0>]    psr: a0000053
> [    0.525079] sp : c3e45e70  ip : 100019ff  fp : 00000000
> [    0.536651] r10: c0828900  r9 : c0434838  r8 : 00000000
> [    0.541953] r7 : c0820700  r6 : c0857b30  r5 : c3ec1400  r4 : c0820758
> [    0.548549] r3 : 00000000  r2 : 0000000c  r1 : c3c09c40  r0 : c3ec1400
> [    0.555154] Flags: NzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
> [    0.562450] Control: 0000397f  Table: a0004000  DAC: 00000053
> [    0.568257] Process swapper (pid: 1, stack limit = 0xc3e44190)
> [    0.574154] Stack: (0xc3e45e70 to 0xc3e46000)
> [    0.578610] 5e60:                                     c4849800 00000000 c3ec1400 c024769c
> [    0.586928] 5e80: 00000000 c3ec140c c3c0ee0c c3ec1400 c3ec1434 c020c410 c3ec1400 c3ec1434
> [    0.595244] 5ea0: c0820700 c080b408 c0828900 c020c5f8 00000000 c0820700 c020c578 c020ac5c
> [    0.603560] 5ec0: c3e687cc c3e71e10 c0820700 00000000 c3c02de0 c020bae4 c03c62f7 c03c62f7
> [    0.611872] 5ee0: c3e68780 c0820700 c042e034 00000000 c043c440 c020cdec c080b408 00000005
> [    0.620188] 5f00: c042e034 c00096c0 c0034440 c01c730c 20000053 ffffffff 00000000 00000000
> [    0.628502] 5f20: 00000000 c3ffcb87 c3ffcb90 c00346ac c3e66ba0 c03f7914 00000092 00000005
> [    0.636811] 5f40: 00000005 c03f847c 00000091 c03f847c 00000000 00000005 c0434828 00000005
> [    0.645125] 5f60: c043482c 00000092 c043c440 c0828900 c0434838 c0418d2c 00000005 00000005
> [    0.653430] 5f80: 00000000 c041858c 00000000 c032e9f0 00000000 00000000 00000000 00000000
> [    0.661729] 5fa0: 00000000 c032e9f8 00000000 c000f0f0 00000000 00000000 00000000 00000000
> [    0.670020] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [    0.678311] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
> [    0.686673] (pxa2xx_configure_sockets) from pcmcia_lubbock_init (/drivers/pcmcia/sa1111_lubbock.c:161)
> [    0.696026] (pcmcia_lubbock_init) from pcmcia_probe (/drivers/pcmcia/sa1111_generic.c:213)
> [    0.704358] (pcmcia_probe) from driver_probe_device (/drivers/base/dd.c:378 /drivers/base/dd.c:499)
> [    0.712848] (driver_probe_device) from __driver_attach (/./include/linux/device.h:983 /drivers/base/dd.c:733)
> [    0.721414] (__driver_attach) from bus_for_each_dev (/drivers/base/bus.c:313)
> [    0.729723] (bus_for_each_dev) from bus_add_driver (/drivers/base/bus.c:708)
> [    0.738036] (bus_add_driver) from driver_register (/drivers/base/driver.c:169)
> [    0.746185] (driver_register) from do_one_initcall (/init/main.c:778)
> [    0.754561] (do_one_initcall) from kernel_init_freeable (/init/main.c:843 /init/main.c:851 /init/main.c:869 /init/main.c:1016)
> [    0.763409] (kernel_init_freeable) from kernel_init (/init/main.c:944)
> [    0.771660] (kernel_init) from ret_from_fork (/arch/arm/kernel/entry-common.S:119)
> [ 0.779347] Code: c03c6305 c03c631e c03c632e e5903048 (e993000c)
> All code
> ========
>    0:	c03c6305 	eorsgt	r6, ip, r5, lsl #6
>    4:	c03c631e 	eorsgt	r6, ip, lr, lsl r3
>    8:	c03c632e 	eorsgt	r6, ip, lr, lsr #6
>    c:	e5903048 	ldr	r3, [r0, #72]	; 0x48
>   10:*	e993000c 	ldmib	r3, {r2, r3}		<-- trapping instruction
> 
> Code starting with the faulting instruction
> ===========================================
>    0:	e993000c 	ldmib	r3, {r2, r3}
> [    0.786319] ---[ end trace 5264be19ef367bea ]---
> [    0.791201] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> [    0.791201]
> [    0.800441] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> ---
>  drivers/pcmcia/pxa2xx_base.c    | 9 +++++----
>  drivers/pcmcia/pxa2xx_base.h    | 2 +-
>  drivers/pcmcia/sa1111_lubbock.c | 2 +-
>  3 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
> index 483f919e0d2e..91b5f5724cba 100644
> --- a/drivers/pcmcia/pxa2xx_base.c
> +++ b/drivers/pcmcia/pxa2xx_base.c
> @@ -214,9 +214,8 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
>  }
>  #endif
>  
> -void pxa2xx_configure_sockets(struct device *dev)
> +void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops)
>  {
> -	struct pcmcia_low_level *ops = dev->platform_data;
>  	/*
>  	 * We have at least one socket, so set MECR:CIT
>  	 * (Card Is There)
> @@ -322,7 +321,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
>  			goto err1;
>  	}
>  
> -	pxa2xx_configure_sockets(&dev->dev);
> +	pxa2xx_configure_sockets(&dev->dev, ops);
>  	dev_set_drvdata(&dev->dev, sinfo);
>  
>  	return 0;
> @@ -348,7 +347,9 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
>  
>  static int pxa2xx_drv_pcmcia_resume(struct device *dev)
>  {
> -	pxa2xx_configure_sockets(dev);
> +	struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data;
> +
> +	pxa2xx_configure_sockets(dev, ops);
>  	return 0;
>  }
>  
> diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
> index b609b45469ed..e58c7a415418 100644
> --- a/drivers/pcmcia/pxa2xx_base.h
> +++ b/drivers/pcmcia/pxa2xx_base.h
> @@ -1,4 +1,4 @@
>  int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
>  void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
> -void pxa2xx_configure_sockets(struct device *dev);
> +void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops);
>  
> diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
> index 9d5ffc71ae51..7c1f0f6cd578 100644
> --- a/drivers/pcmcia/sa1111_lubbock.c
> +++ b/drivers/pcmcia/sa1111_lubbock.c
> @@ -157,7 +157,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
>  
>  	if (machine_is_lubbock()) {
>  		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
> -		pxa2xx_configure_sockets(&sadev->dev);
> +		pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
>  		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
>  				pxa2xx_drv_pcmcia_add_one);
>  	}

I think the patch is sane - it's certainly saner than the current mess,
so I'll add it to my patch set, thanks.

> [    7.171675] atkbd serio0: keyboard reset failed on 0a00
> [    7.177087] ------------[ cut here ]------------
> [    7.181895] WARNING: CPU: 0 PID: 17 at kernel/irq/manage.c:527 enable_irq+0x58/0x70
> [    7.189606] Unbalanced enable for IRQ 357
> [    7.193662] Modules linked in:
> [    7.196854] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2070
> [    7.205878] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
> [    7.213055] Workqueue: events_long serio_handle_event
> [    7.218386] [<c0015260>] (unwind_backtrace) from [<c00122f0>] (show_stack+0x10/0x14)
> [    7.226312] [<c00122f0>] (show_stack) from [<c001ea40>] (__warn+0xcc/0xf8)
> [    7.233334] [<c001ea40>] (__warn) from [<c001eaa0>] (warn_slowpath_fmt+0x34/0x44)
> [    7.240964] [<c001eaa0>] (warn_slowpath_fmt) from [<c0047d44>] (enable_irq+0x58/0x70)
> [    7.248935] [<c0047d44>] (enable_irq) from [<c0250df4>] (ps2_write+0x4c/0x78)
> [    7.256211] [<c0250df4>] (ps2_write) from [<c025107c>] (ps2_sendbyte+0x50/0x144)
> [    7.263746] [<c025107c>] (ps2_sendbyte) from [<c02513b0>] (__ps2_command+0xc0/0x3c4)
> [    7.271630] [<c02513b0>] (__ps2_command) from [<c02516d8>] (ps2_command+0x24/0x38)
> [    7.279389] [<c02516d8>] (ps2_command) from [<c0259968>] (atkbd_probe+0x60/0x140)
> [    7.287026] [<c0259968>] (atkbd_probe) from [<c025a950>] (atkbd_connect+0x130/0x238)
> [    7.294901] [<c025a950>] (atkbd_connect) from [<c0250ae4>] (serio_driver_probe+0x28/0x3c)
> [    7.303251] [<c0250ae4>] (serio_driver_probe) from [<c020c410>] (driver_probe_device+0x124/0x28c)
> [    7.312276] [<c020c410>] (driver_probe_device) from [<c020c5f8>] (__driver_attach+0x80/0xa4)
> [    7.320852] [<c020c5f8>] (__driver_attach) from [<c020ac5c>] (bus_for_each_dev+0x6c/0x90)
> [    7.329167] [<c020ac5c>] (bus_for_each_dev) from [<c0250984>] (serio_handle_event+0x154/0x1a0)
> [    7.337933] [<c0250984>] (serio_handle_event) from [<c0030638>] (process_one_work+0x1bc/0x300)
> [    7.346688] [<c0030638>] (process_one_work) from [<c0030d1c>] (worker_thread+0x2bc/0x3f8)
> [    7.355043] [<c0030d1c>] (worker_thread) from [<c0034da0>] (kthread+0xc4/0xd8)
> [    7.362418] [<c0034da0>] (kthread) from [<c000f0f0>] (ret_from_fork+0x14/0x24)
> [    7.369720] ---[ end trace 52001af966019111 ]---

Hmm, I've not seen that one, I'll look into it.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-01  9:27                       ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-01  9:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2016 at 09:19:13AM +0200, Robert Jarzmik wrote:
> The result today is that my PCMCIA card inserted in Lubbock's slot is not
> detected, but that's not really a surprise. As a matter of fact, I didn't
> look much into it, the only data points I have are :
>  - PCMCIA is probed now
>    - this is based on dmesg in [3]
>    - this is also based on ls /sys/bus/sa1111-rab/devices/1800
> 	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 driver -> ../../../../bus/sa1111-rab/drivers/sa1111-pcmcia
> 	drwxr-xr-x    2 root     root             0 Jan  1 00:15 power
> 	lrwxrwxrwx    1 root     root             0 Jan  1 00:15 subsystem -> ../../../../bus/sa1111-rab
> 	-rw-r--r--    1 root     root          4096 Jan  1 00:15 uevent
> 
>  - PCMCIA sockets are not there
>    - this is based on ls /sys/class/pcmcia_socket/ where there is nothing
> 
>  - MAX16xx gpio are not claimed, which is surprising
>    - this is based on cat /sys/kernel/debug/gpio
> 	gpiochip0: GPIOs 0-84, gpio-pxa:
> 	gpiochip2: GPIOs 478-495, parent: platform/sa1111, sa1111:
> 	gpiochip1: GPIOs 496-511, lubbock:

It looks like:

(a) pcmcia_probe() in drivers/pcmcia/sa1111_generic.c doesn't check the
    return value from the platform specific init functions, meaning if
    they fail, the driver still binds.  (note: they return -ENODEV to
    indicate that they should skip to the next platform.)
(b) there is no clock provided for the sa1111 pcmcia device (aka "1800").
    This should be the same clock as pxa2xx-pcmcia.

> > There is a slight issue, which is that the interrupts can't be translated to
> > an interrupt by gpio-reg, which will currently cause soc_common problems - but
> > that's an easy fix, though leaves us with more code than I'd desire in
> > pxa2xx_mainstone.c.  Maybe a solution there would be to have gpio-reg also
> > take an array of interrupt numbers... not sure yet.
>
> Normally these interrupts are already dealt with by
> arch/arm/mach-pxa/pxa_cplds_irq.c, which adds an irqdomain for them. The missing
> part is the "gpio to interrupt" translation part, right ? This is where your
> array comes into play if I get your right, to be the input of the to_irq()
> function of the gpiochip.

Yes.

> As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
> so that your translation is only a linear irq = gpio + offset ?

There isn't a linear translation here:

#define MST_PCMCIA_nIRQ         (1 << 10)  /* IRQ / ready signal */
#define MST_PCMCIA_nSPKR_BVD2   (1 << 9)   /* VDD sense / digital speaker */
#define MST_PCMCIA_nSTSCHG_BVD1 (1 << 8)   /* VDD sense / card status changed */#define MST_PCMCIA_nVS2         (1 << 7)   /* VSS voltage sense */
#define MST_PCMCIA_nVS1         (1 << 6)   /* VSS voltage sense */
#define MST_PCMCIA_nCD          (1 << 5)   /* Card detection signal */
#define MST_PCMCIA_RESET        (1 << 4)   /* Card reset signal */
#define MST_PCMCIA_PWR_MASK     (0x000f)   /* MAX1602 power-supply controls */

#define MAINSTONE_S0_CD_IRQ     MAINSTONE_IRQ(9)
#define MAINSTONE_S0_STSCHG_IRQ MAINSTONE_IRQ(10)
#define MAINSTONE_S0_IRQ        MAINSTONE_IRQ(11)
#define MAINSTONE_S1_CD_IRQ     MAINSTONE_IRQ(13)
#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
#define MAINSTONE_S1_IRQ        MAINSTONE_IRQ(15)

MST_PCMCIA_nCD		=> MAINSTONE_S0_CD_IRQ or MAINSTONE_S1_CD_IRQ
MST_PCMCIA_nSTSCHG_BVD1 => MAINSTONE_S0_STSCHG_IRQ or MAINSTONE_S1_STSCHG_IRQ
MST_PCMCIA_nIRQ		=> MAINSTONE_S0_IRQ or MAINSTONE_S1_IRQ

So they aren't linear, and every "gpio" doesn't have a corresponding
interrupt.

> [1] Typo fix
> diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
> index f034928b99a1..81a1de6fb46f 100644
> --- a/arch/arm/mach-pxa/lubbock.c
> +++ b/arch/arm/mach-pxa/lubbock.c
> @@ -13,7 +13,7 @@
>   */
>  #include <linux/clkdev.h>
>  #include <linux/gpio.h>
> -#include <linux/gpip/gpio-reg.h>
> +#include <linux/gpio/gpio-reg.h>
>  #include <linux/gpio/machine.h>
>  #include <linux/module.h>
>  #include <linux/kernel.h>

Fixed.

> [2] Kind-of fix for lubbock pcmcia probe
> >From 977c16201a752aac8a8fb2da1f4271795f0b2122 Mon Sep 17 00:00:00 2001
> From: Robert Jarzmik <robert.jarzmik@free.fr>
> Date: Thu, 1 Sep 2016 08:31:08 +0200
> Subject: [PATCH] pcmcia: lubbock: fix sockets configuration
> 
> On lubbock board, the probe of the driver crashes by dereferencing very
> early a platform_data structure which is not set, in
> pxa2xx_configure_sockets().
> 
> This patch blindly fixes it without any analysis as to know if it's the
> right fix or even if the fix doesn't break in suspend/resume.
> 
> The stack fixed is :
> [    0.244353] SA1111 Microprocessor Companion Chip: silicon revision 1, metal revision 1
> [    0.256321] sa1111 sa1111: Providing IRQ336-390
> [    0.340899] clocksource: Switched to clocksource oscr0
> [    0.472263] Unable to handle kernel NULL pointer dereference at virtual address 00000004
> [    0.480469] pgd = c0004000
> [    0.483432] [00000004] *pgd=00000000
> [    0.487105] Internal error: Oops: f5 [#1] ARM
> [    0.491497] Modules linked in:
> [    0.494650] CPU: 0 PID: 1 Comm: swapper Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2068
> [    0.503229] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
> [    0.510344] task: c3e42000 task.stack: c3e44000
> [    0.514984] PC is at pxa2xx_configure_sockets+0x4/0x24 (drivers/pcmcia/pxa2xx_base.c:227)
> [    0.520193] LR is at pcmcia_lubbock_init+0x1c/0x38
> [    0.525079] pc : [<c0247c30>]    lr : [<c02479b0>]    psr: a0000053
> [    0.525079] sp : c3e45e70  ip : 100019ff  fp : 00000000
> [    0.536651] r10: c0828900  r9 : c0434838  r8 : 00000000
> [    0.541953] r7 : c0820700  r6 : c0857b30  r5 : c3ec1400  r4 : c0820758
> [    0.548549] r3 : 00000000  r2 : 0000000c  r1 : c3c09c40  r0 : c3ec1400
> [    0.555154] Flags: NzCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment none
> [    0.562450] Control: 0000397f  Table: a0004000  DAC: 00000053
> [    0.568257] Process swapper (pid: 1, stack limit = 0xc3e44190)
> [    0.574154] Stack: (0xc3e45e70 to 0xc3e46000)
> [    0.578610] 5e60:                                     c4849800 00000000 c3ec1400 c024769c
> [    0.586928] 5e80: 00000000 c3ec140c c3c0ee0c c3ec1400 c3ec1434 c020c410 c3ec1400 c3ec1434
> [    0.595244] 5ea0: c0820700 c080b408 c0828900 c020c5f8 00000000 c0820700 c020c578 c020ac5c
> [    0.603560] 5ec0: c3e687cc c3e71e10 c0820700 00000000 c3c02de0 c020bae4 c03c62f7 c03c62f7
> [    0.611872] 5ee0: c3e68780 c0820700 c042e034 00000000 c043c440 c020cdec c080b408 00000005
> [    0.620188] 5f00: c042e034 c00096c0 c0034440 c01c730c 20000053 ffffffff 00000000 00000000
> [    0.628502] 5f20: 00000000 c3ffcb87 c3ffcb90 c00346ac c3e66ba0 c03f7914 00000092 00000005
> [    0.636811] 5f40: 00000005 c03f847c 00000091 c03f847c 00000000 00000005 c0434828 00000005
> [    0.645125] 5f60: c043482c 00000092 c043c440 c0828900 c0434838 c0418d2c 00000005 00000005
> [    0.653430] 5f80: 00000000 c041858c 00000000 c032e9f0 00000000 00000000 00000000 00000000
> [    0.661729] 5fa0: 00000000 c032e9f8 00000000 c000f0f0 00000000 00000000 00000000 00000000
> [    0.670020] 5fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [    0.678311] 5fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
> [    0.686673] (pxa2xx_configure_sockets) from pcmcia_lubbock_init (/drivers/pcmcia/sa1111_lubbock.c:161)
> [    0.696026] (pcmcia_lubbock_init) from pcmcia_probe (/drivers/pcmcia/sa1111_generic.c:213)
> [    0.704358] (pcmcia_probe) from driver_probe_device (/drivers/base/dd.c:378 /drivers/base/dd.c:499)
> [    0.712848] (driver_probe_device) from __driver_attach (/./include/linux/device.h:983 /drivers/base/dd.c:733)
> [    0.721414] (__driver_attach) from bus_for_each_dev (/drivers/base/bus.c:313)
> [    0.729723] (bus_for_each_dev) from bus_add_driver (/drivers/base/bus.c:708)
> [    0.738036] (bus_add_driver) from driver_register (/drivers/base/driver.c:169)
> [    0.746185] (driver_register) from do_one_initcall (/init/main.c:778)
> [    0.754561] (do_one_initcall) from kernel_init_freeable (/init/main.c:843 /init/main.c:851 /init/main.c:869 /init/main.c:1016)
> [    0.763409] (kernel_init_freeable) from kernel_init (/init/main.c:944)
> [    0.771660] (kernel_init) from ret_from_fork (/arch/arm/kernel/entry-common.S:119)
> [ 0.779347] Code: c03c6305 c03c631e c03c632e e5903048 (e993000c)
> All code
> ========
>    0:	c03c6305 	eorsgt	r6, ip, r5, lsl #6
>    4:	c03c631e 	eorsgt	r6, ip, lr, lsl r3
>    8:	c03c632e 	eorsgt	r6, ip, lr, lsr #6
>    c:	e5903048 	ldr	r3, [r0, #72]	; 0x48
>   10:*	e993000c 	ldmib	r3, {r2, r3}		<-- trapping instruction
> 
> Code starting with the faulting instruction
> ===========================================
>    0:	e993000c 	ldmib	r3, {r2, r3}
> [    0.786319] ---[ end trace 5264be19ef367bea ]---
> [    0.791201] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> [    0.791201]
> [    0.800441] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> ---
>  drivers/pcmcia/pxa2xx_base.c    | 9 +++++----
>  drivers/pcmcia/pxa2xx_base.h    | 2 +-
>  drivers/pcmcia/sa1111_lubbock.c | 2 +-
>  3 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
> index 483f919e0d2e..91b5f5724cba 100644
> --- a/drivers/pcmcia/pxa2xx_base.c
> +++ b/drivers/pcmcia/pxa2xx_base.c
> @@ -214,9 +214,8 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
>  }
>  #endif
>  
> -void pxa2xx_configure_sockets(struct device *dev)
> +void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops)
>  {
> -	struct pcmcia_low_level *ops = dev->platform_data;
>  	/*
>  	 * We have at least one socket, so set MECR:CIT
>  	 * (Card Is There)
> @@ -322,7 +321,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
>  			goto err1;
>  	}
>  
> -	pxa2xx_configure_sockets(&dev->dev);
> +	pxa2xx_configure_sockets(&dev->dev, ops);
>  	dev_set_drvdata(&dev->dev, sinfo);
>  
>  	return 0;
> @@ -348,7 +347,9 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
>  
>  static int pxa2xx_drv_pcmcia_resume(struct device *dev)
>  {
> -	pxa2xx_configure_sockets(dev);
> +	struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data;
> +
> +	pxa2xx_configure_sockets(dev, ops);
>  	return 0;
>  }
>  
> diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
> index b609b45469ed..e58c7a415418 100644
> --- a/drivers/pcmcia/pxa2xx_base.h
> +++ b/drivers/pcmcia/pxa2xx_base.h
> @@ -1,4 +1,4 @@
>  int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
>  void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
> -void pxa2xx_configure_sockets(struct device *dev);
> +void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops);
>  
> diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
> index 9d5ffc71ae51..7c1f0f6cd578 100644
> --- a/drivers/pcmcia/sa1111_lubbock.c
> +++ b/drivers/pcmcia/sa1111_lubbock.c
> @@ -157,7 +157,7 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
>  
>  	if (machine_is_lubbock()) {
>  		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
> -		pxa2xx_configure_sockets(&sadev->dev);
> +		pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops);
>  		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
>  				pxa2xx_drv_pcmcia_add_one);
>  	}

I think the patch is sane - it's certainly saner than the current mess,
so I'll add it to my patch set, thanks.

> [    7.171675] atkbd serio0: keyboard reset failed on 0a00
> [    7.177087] ------------[ cut here ]------------
> [    7.181895] WARNING: CPU: 0 PID: 17 at kernel/irq/manage.c:527 enable_irq+0x58/0x70
> [    7.189606] Unbalanced enable for IRQ 357
> [    7.193662] Modules linked in:
> [    7.196854] CPU: 0 PID: 17 Comm: kworker/0:1 Not tainted 4.8.0-rc3-00080-g1aaa68426f0c-dirty #2070
> [    7.205878] Hardware name: Intel DBPXA250 Development Platform (aka Lubbock)
> [    7.213055] Workqueue: events_long serio_handle_event
> [    7.218386] [<c0015260>] (unwind_backtrace) from [<c00122f0>] (show_stack+0x10/0x14)
> [    7.226312] [<c00122f0>] (show_stack) from [<c001ea40>] (__warn+0xcc/0xf8)
> [    7.233334] [<c001ea40>] (__warn) from [<c001eaa0>] (warn_slowpath_fmt+0x34/0x44)
> [    7.240964] [<c001eaa0>] (warn_slowpath_fmt) from [<c0047d44>] (enable_irq+0x58/0x70)
> [    7.248935] [<c0047d44>] (enable_irq) from [<c0250df4>] (ps2_write+0x4c/0x78)
> [    7.256211] [<c0250df4>] (ps2_write) from [<c025107c>] (ps2_sendbyte+0x50/0x144)
> [    7.263746] [<c025107c>] (ps2_sendbyte) from [<c02513b0>] (__ps2_command+0xc0/0x3c4)
> [    7.271630] [<c02513b0>] (__ps2_command) from [<c02516d8>] (ps2_command+0x24/0x38)
> [    7.279389] [<c02516d8>] (ps2_command) from [<c0259968>] (atkbd_probe+0x60/0x140)
> [    7.287026] [<c0259968>] (atkbd_probe) from [<c025a950>] (atkbd_connect+0x130/0x238)
> [    7.294901] [<c025a950>] (atkbd_connect) from [<c0250ae4>] (serio_driver_probe+0x28/0x3c)
> [    7.303251] [<c0250ae4>] (serio_driver_probe) from [<c020c410>] (driver_probe_device+0x124/0x28c)
> [    7.312276] [<c020c410>] (driver_probe_device) from [<c020c5f8>] (__driver_attach+0x80/0xa4)
> [    7.320852] [<c020c5f8>] (__driver_attach) from [<c020ac5c>] (bus_for_each_dev+0x6c/0x90)
> [    7.329167] [<c020ac5c>] (bus_for_each_dev) from [<c0250984>] (serio_handle_event+0x154/0x1a0)
> [    7.337933] [<c0250984>] (serio_handle_event) from [<c0030638>] (process_one_work+0x1bc/0x300)
> [    7.346688] [<c0030638>] (process_one_work) from [<c0030d1c>] (worker_thread+0x2bc/0x3f8)
> [    7.355043] [<c0030d1c>] (worker_thread) from [<c0034da0>] (kthread+0xc4/0xd8)
> [    7.362418] [<c0034da0>] (kthread) from [<c000f0f0>] (ret_from_fork+0x14/0x24)
> [    7.369720] ---[ end trace 52001af966019111 ]---

Hmm, I've not seen that one, I'll look into it.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)
  2016-08-30 21:31     ` Linus Walleij
@ 2016-09-01 15:34       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-01 15:34 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Robert Jarzmik

On Tue, Aug 30, 2016 at 11:31:58PM +0200, Linus Walleij wrote:
> For all the GPIO patches:
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> 
> With the smallish changes needed to patch 5/33 that one is acked too.
> 
> In fact I would ACK it anyway, because the net total cleanup is so
> nice on the kernel at large... SA11x0 has never been prettier than
> after this series.

Thanks, ack applied to all the gpio patches.

> I suspect you want to keep the series together and queue it in the ARM
> tree? Else tell me what to apply in the GPIO tree.

Yes, I need to keep the series together because of the dependencies -
trying to split it up will lead to conflicts and breakage from missing
include files, and when it's not from missing include files, it'll be
non-functional.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [RFC PATCH 00/33] SA11x0/PXA GPIO rework (Core + PCMCIA only)
@ 2016-09-01 15:34       ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-01 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 30, 2016 at 11:31:58PM +0200, Linus Walleij wrote:
> For all the GPIO patches:
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> 
> With the smallish changes needed to patch 5/33 that one is acked too.
> 
> In fact I would ACK it anyway, because the net total cleanup is so
> nice on the kernel at large... SA11x0 has never been prettier than
> after this series.

Thanks, ack applied to all the gpio patches.

> I suspect you want to keep the series together and queue it in the ARM
> tree? Else tell me what to apply in the GPIO tree.

Yes, I need to keep the series together because of the dependencies -
trying to split it up will lead to conflicts and breakage from missing
include files, and when it's not from missing include files, it'll be
non-functional.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-09-01  9:27                       ` Russell King - ARM Linux
@ 2016-09-01 21:58                         ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-01 21:58 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Thu, Sep 01, 2016 at 09:19:13AM +0200, Robert Jarzmik wrote:
> It looks like:
>
> (a) pcmcia_probe() in drivers/pcmcia/sa1111_generic.c doesn't check the
>     return value from the platform specific init functions, meaning if
>     they fail, the driver still binds.  (note: they return -ENODEV to
>     indicate that they should skip to the next platform.)
You're right, I submitted a patch for that, and I confirm it actually happens on
lubbock.

> (b) there is no clock provided for the sa1111 pcmcia device (aka "1800").
>     This should be the same clock as pxa2xx-pcmcia.
Again right in the spot.
I added temporarily a clock until I have a more complete understanding in
lubbock.c :
+	clk_add_alias(NULL, "1800", "SA1111_CLK", NULL);

With this, things look way better :
[    1.507480] pcmcia_socket pcmcia_socket1: pccard: PCMCIA card inserted into slot 1

I'm still investigating the new message errors:
[    0.479157] genirq: Setting trigger mode 3 for irq 387 failed (sa1111_type_highirq+0x0/0x6c)
[    0.488213] genirq: Setting trigger mode 3 for irq 389 failed (sa1111_type_highirq+0x0/0x6c)
[    0.507449] genirq: Setting trigger mode 3 for irq 388 failed (sa1111_type_highirq+0x0/0x6c)
[    0.516492] genirq: Setting trigger mode 3 for irq 390 failed (sa1111_type_highirq+0x0/0x6c)

Moreover, I have a bit of homework as I also see :
 - no SA1111 interrupts at all, especially nothing when I insert/remove my
   CompactFlash card
   This might be an effect of pxa_cplds_irqs.c I created, I must have a look.
 - cat /sys/class/pcmcia_socket/pcmcia_socket1/cis 
   cat: read error: Input/output error
   That will cost me a review of the memory timings registers MCIO1/MECR/xxx,
   the power lines, etc ...
 - cat /sys/class/pcmcia_socket/pcmcia_socket1/status 
slot     : 1
status   : SS_READY SS_DETECT SS_POWERON SS_3VCARD
csc_mask : SS_DETECT
cs_flags : SS_OUTPUT_ENA
Vcc      : 33
Vpp      : 33
IRQ      : 0 (386)

>> As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
>> so that your translation is only a linear irq = gpio + offset ?
>
> There isn't a linear translation here:
...zip...
> MST_PCMCIA_nCD		=> MAINSTONE_S0_CD_IRQ or MAINSTONE_S1_CD_IRQ
> MST_PCMCIA_nSTSCHG_BVD1 => MAINSTONE_S0_STSCHG_IRQ or MAINSTONE_S1_STSCHG_IRQ
> MST_PCMCIA_nIRQ		=> MAINSTONE_S0_IRQ or MAINSTONE_S1_IRQ
>
> So they aren't linear, and every "gpio" doesn't have a corresponding
> interrupt.
Ah yes, too bad, it would have been so much simpler.

Cheers.

-- 
Robert

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-01 21:58                         ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-01 21:58 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Thu, Sep 01, 2016 at 09:19:13AM +0200, Robert Jarzmik wrote:
> It looks like:
>
> (a) pcmcia_probe() in drivers/pcmcia/sa1111_generic.c doesn't check the
>     return value from the platform specific init functions, meaning if
>     they fail, the driver still binds.  (note: they return -ENODEV to
>     indicate that they should skip to the next platform.)
You're right, I submitted a patch for that, and I confirm it actually happens on
lubbock.

> (b) there is no clock provided for the sa1111 pcmcia device (aka "1800").
>     This should be the same clock as pxa2xx-pcmcia.
Again right in the spot.
I added temporarily a clock until I have a more complete understanding in
lubbock.c :
+	clk_add_alias(NULL, "1800", "SA1111_CLK", NULL);

With this, things look way better :
[    1.507480] pcmcia_socket pcmcia_socket1: pccard: PCMCIA card inserted into slot 1

I'm still investigating the new message errors:
[    0.479157] genirq: Setting trigger mode 3 for irq 387 failed (sa1111_type_highirq+0x0/0x6c)
[    0.488213] genirq: Setting trigger mode 3 for irq 389 failed (sa1111_type_highirq+0x0/0x6c)
[    0.507449] genirq: Setting trigger mode 3 for irq 388 failed (sa1111_type_highirq+0x0/0x6c)
[    0.516492] genirq: Setting trigger mode 3 for irq 390 failed (sa1111_type_highirq+0x0/0x6c)

Moreover, I have a bit of homework as I also see :
 - no SA1111 interrupts at all, especially nothing when I insert/remove my
   CompactFlash card
   This might be an effect of pxa_cplds_irqs.c I created, I must have a look.
 - cat /sys/class/pcmcia_socket/pcmcia_socket1/cis 
   cat: read error: Input/output error
   That will cost me a review of the memory timings registers MCIO1/MECR/xxx,
   the power lines, etc ...
 - cat /sys/class/pcmcia_socket/pcmcia_socket1/status 
slot     : 1
status   : SS_READY SS_DETECT SS_POWERON SS_3VCARD
csc_mask : SS_DETECT
cs_flags : SS_OUTPUT_ENA
Vcc      : 33
Vpp      : 33
IRQ      : 0 (386)

>> As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
>> so that your translation is only a linear irq = gpio + offset ?
>
> There isn't a linear translation here:
...zip...
> MST_PCMCIA_nCD		=> MAINSTONE_S0_CD_IRQ or MAINSTONE_S1_CD_IRQ
> MST_PCMCIA_nSTSCHG_BVD1 => MAINSTONE_S0_STSCHG_IRQ or MAINSTONE_S1_STSCHG_IRQ
> MST_PCMCIA_nIRQ		=> MAINSTONE_S0_IRQ or MAINSTONE_S1_IRQ
>
> So they aren't linear, and every "gpio" doesn't have a corresponding
> interrupt.
Ah yes, too bad, it would have been so much simpler.

Cheers.

-- 
Robert

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-09-01 21:58                         ` Robert Jarzmik
@ 2016-09-01 23:02                           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-01 23:02 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

On Thu, Sep 01, 2016 at 11:58:28PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > On Thu, Sep 01, 2016 at 09:19:13AM +0200, Robert Jarzmik wrote:
> > It looks like:
> >
> > (a) pcmcia_probe() in drivers/pcmcia/sa1111_generic.c doesn't check the
> >     return value from the platform specific init functions, meaning if
> >     they fail, the driver still binds.  (note: they return -ENODEV to
> >     indicate that they should skip to the next platform.)
> You're right, I submitted a patch for that, and I confirm it actually happens on
> lubbock.

That'll work fine for lubbock, but not the others (we can have several
of the others enabled on sa11x0 platforms - eg, badge4 with neponset.)

> > (b) there is no clock provided for the sa1111 pcmcia device (aka "1800").
> >     This should be the same clock as pxa2xx-pcmcia.
> Again right in the spot.
> I added temporarily a clock until I have a more complete understanding in
> lubbock.c :
> +	clk_add_alias(NULL, "1800", "SA1111_CLK", NULL);
> 
> With this, things look way better :
> [    1.507480] pcmcia_socket pcmcia_socket1: pccard: PCMCIA card inserted into slot 1

Yay!

> I'm still investigating the new message errors:
> [    0.479157] genirq: Setting trigger mode 3 for irq 387 failed (sa1111_type_highirq+0x0/0x6c)
> [    0.488213] genirq: Setting trigger mode 3 for irq 389 failed (sa1111_type_highirq+0x0/0x6c)
> [    0.507449] genirq: Setting trigger mode 3 for irq 388 failed (sa1111_type_highirq+0x0/0x6c)
> [    0.516492] genirq: Setting trigger mode 3 for irq 390 failed (sa1111_type_highirq+0x0/0x6c)

Ignore those for now - the old ARM IRQ stuff was silent on that, but genirq
is more noisy.  I should probably make the sa1111 irqchip handle the both-
edge case itself.

> Moreover, I have a bit of homework as I also see :
>  - no SA1111 interrupts at all, especially nothing when I insert/remove my
>    CompactFlash card
>    This might be an effect of pxa_cplds_irqs.c I created, I must have a look.

Do you get other SA1111 interrupts (eg, the PS/2 interrupts) delivered?

>  - cat /sys/class/pcmcia_socket/pcmcia_socket1/cis 
>    cat: read error: Input/output error
>    That will cost me a review of the memory timings registers MCIO1/MECR/xxx,
>    the power lines, etc ...

Hmm, on Neponset with a CF card inserted, I can cat that, and it reports
the CIS.  Any error messages in the kernel log?

>  - cat /sys/class/pcmcia_socket/pcmcia_socket1/status 
> slot     : 1
> status   : SS_READY SS_DETECT SS_POWERON SS_3VCARD
> csc_mask : SS_DETECT
> cs_flags : SS_OUTPUT_ENA
> Vcc      : 33
> Vpp      : 33
> IRQ      : 0 (386)

That looks hopeful, but the IRQ hasn't been properly assigned (probably
because no driver has bound to the card.)

> >> As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
> >> so that your translation is only a linear irq = gpio + offset ?
> >
> > There isn't a linear translation here:
> ...zip...
> > MST_PCMCIA_nCD		=> MAINSTONE_S0_CD_IRQ or MAINSTONE_S1_CD_IRQ
> > MST_PCMCIA_nSTSCHG_BVD1 => MAINSTONE_S0_STSCHG_IRQ or MAINSTONE_S1_STSCHG_IRQ
> > MST_PCMCIA_nIRQ		=> MAINSTONE_S0_IRQ or MAINSTONE_S1_IRQ
> >
> > So they aren't linear, and every "gpio" doesn't have a corresponding
> > interrupt.
> Ah yes, too bad, it would have been so much simpler.

Indeed, but a tabular approach isn't that painful, especially if we
also insist on knowing an irqdomain as well, which relieves us of
having to know absolute interrupt numbers, which may end up being
dynamically allocated eventually.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-01 23:02                           ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-01 23:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2016 at 11:58:28PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> > On Thu, Sep 01, 2016 at 09:19:13AM +0200, Robert Jarzmik wrote:
> > It looks like:
> >
> > (a) pcmcia_probe() in drivers/pcmcia/sa1111_generic.c doesn't check the
> >     return value from the platform specific init functions, meaning if
> >     they fail, the driver still binds.  (note: they return -ENODEV to
> >     indicate that they should skip to the next platform.)
> You're right, I submitted a patch for that, and I confirm it actually happens on
> lubbock.

That'll work fine for lubbock, but not the others (we can have several
of the others enabled on sa11x0 platforms - eg, badge4 with neponset.)

> > (b) there is no clock provided for the sa1111 pcmcia device (aka "1800").
> >     This should be the same clock as pxa2xx-pcmcia.
> Again right in the spot.
> I added temporarily a clock until I have a more complete understanding in
> lubbock.c :
> +	clk_add_alias(NULL, "1800", "SA1111_CLK", NULL);
> 
> With this, things look way better :
> [    1.507480] pcmcia_socket pcmcia_socket1: pccard: PCMCIA card inserted into slot 1

Yay!

> I'm still investigating the new message errors:
> [    0.479157] genirq: Setting trigger mode 3 for irq 387 failed (sa1111_type_highirq+0x0/0x6c)
> [    0.488213] genirq: Setting trigger mode 3 for irq 389 failed (sa1111_type_highirq+0x0/0x6c)
> [    0.507449] genirq: Setting trigger mode 3 for irq 388 failed (sa1111_type_highirq+0x0/0x6c)
> [    0.516492] genirq: Setting trigger mode 3 for irq 390 failed (sa1111_type_highirq+0x0/0x6c)

Ignore those for now - the old ARM IRQ stuff was silent on that, but genirq
is more noisy.  I should probably make the sa1111 irqchip handle the both-
edge case itself.

> Moreover, I have a bit of homework as I also see :
>  - no SA1111 interrupts at all, especially nothing when I insert/remove my
>    CompactFlash card
>    This might be an effect of pxa_cplds_irqs.c I created, I must have a look.

Do you get other SA1111 interrupts (eg, the PS/2 interrupts) delivered?

>  - cat /sys/class/pcmcia_socket/pcmcia_socket1/cis 
>    cat: read error: Input/output error
>    That will cost me a review of the memory timings registers MCIO1/MECR/xxx,
>    the power lines, etc ...

Hmm, on Neponset with a CF card inserted, I can cat that, and it reports
the CIS.  Any error messages in the kernel log?

>  - cat /sys/class/pcmcia_socket/pcmcia_socket1/status 
> slot     : 1
> status   : SS_READY SS_DETECT SS_POWERON SS_3VCARD
> csc_mask : SS_DETECT
> cs_flags : SS_OUTPUT_ENA
> Vcc      : 33
> Vpp      : 33
> IRQ      : 0 (386)

That looks hopeful, but the IRQ hasn't been properly assigned (probably
because no driver has bound to the card.)

> >> As your gpios are contiguous (0 .. 31), why an array instead of a simple offset
> >> so that your translation is only a linear irq = gpio + offset ?
> >
> > There isn't a linear translation here:
> ...zip...
> > MST_PCMCIA_nCD		=> MAINSTONE_S0_CD_IRQ or MAINSTONE_S1_CD_IRQ
> > MST_PCMCIA_nSTSCHG_BVD1 => MAINSTONE_S0_STSCHG_IRQ or MAINSTONE_S1_STSCHG_IRQ
> > MST_PCMCIA_nIRQ		=> MAINSTONE_S0_IRQ or MAINSTONE_S1_IRQ
> >
> > So they aren't linear, and every "gpio" doesn't have a corresponding
> > interrupt.
> Ah yes, too bad, it would have been so much simpler.

Indeed, but a tabular approach isn't that painful, especially if we
also insist on knowing an irqdomain as well, which relieves us of
having to know absolute interrupt numbers, which may end up being
dynamically allocated eventually.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
  2016-08-30 10:51             ` Russell King - ARM Linux
@ 2016-09-01 23:32               ` David Miller
  -1 siblings, 0 replies; 235+ messages in thread
From: David Miller @ 2016-09-01 23:32 UTC (permalink / raw)
  To: linux; +Cc: linux-arm-kernel, netdev, nico

From: Russell King - ARM Linux <linux@armlinux.org.uk>
Date: Tue, 30 Aug 2016 11:51:17 +0100

> Please ack these changes; due to the dependencies, I wish to merge
> them through my tree.  Thanks.

Acked-by: David S. Miller <davem@davemloft.net>

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

* [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
@ 2016-09-01 23:32               ` David Miller
  0 siblings, 0 replies; 235+ messages in thread
From: David Miller @ 2016-09-01 23:32 UTC (permalink / raw)
  To: linux-arm-kernel

From: Russell King - ARM Linux <linux@armlinux.org.uk>
Date: Tue, 30 Aug 2016 11:51:17 +0100

> Please ack these changes; due to the dependencies, I wish to merge
> them through my tree.  Thanks.

Acked-by: David S. Miller <davem@davemloft.net>

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-08-30 21:47           ` Linus Walleij
@ 2016-09-02 17:00             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 17:00 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-arm-kernel, linux-gpio, linux-pcmcia, Alexandre Courbot,
	Daniel Mack, Haojian Zhuang, Kristoffer Ericson, Robert Jarzmik

Linus,

There's a change I'd like to merge into patch 5 - overall it looks
like the below, and allows us to use gpio-reg with the PXA mainstone
MST_PCMCIA[01] registers.  Some of these GPIO signals have hardware
interrupts associated with them, but not all.

Do you approve?

Thanks.

8<====
From: Russell King <rmk+kernel@armlinux.org.uk>
Subject: [PATCH] gpio: gpio-reg: add irq mapping for gpio-reg users

Add support for mapping gpio-reg gpios to interrupts.  This may be a
non-linear mapping - some gpios in the register may not even have
corresponding interrupts associated with them, so we need to pass an
array.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/lubbock.c     |  2 +-
 arch/arm/mach-sa1100/assabet.c  |  2 +-
 arch/arm/mach-sa1100/neponset.c |  2 +-
 drivers/gpio/gpio-reg.c         | 25 +++++++++++++++++++++++--
 include/linux/gpio/gpio-reg.h   |  3 ++-
 5 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1f7bfabfa4eb..cd401546cea8 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -477,7 +477,7 @@ static void __init lubbock_init(void)
 
 	lubbock_misc_wr_gc = gpio_reg_init(NULL, (void *)&LUB_MISC_WR,
 					   -1, 16, "lubbock", 0, LUB_MISC_WR,
-					   NULL);
+					   NULL, NULL, NULL);
 	if (IS_ERR(lubbock_misc_wr_gc)) {
 		pr_err("Lubbock: unable to register lubbock GPIOs: %ld\n",
 		       PTR_ERR(lubbock_misc_wr_gc));
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 51950454afac..e086c609551c 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -120,7 +120,7 @@ static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
 	writel_relaxed(def_val, reg);
 
 	gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
-			   assabet_names);
+			   assabet_names, NULL, NULL);
 
 	if (IS_ERR(gc))
 		return PTR_ERR(gc);
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 5abc04fb196d..b16de1f0d5d0 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -240,7 +240,7 @@ static int neponset_init_gpio(struct gpio_chip **gcp,
 	struct gpio_chip *gc;
 
 	gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
-			   readl_relaxed(reg), names);
+			   readl_relaxed(reg), names, NULL, NULL);
 	if (IS_ERR(gc))
 		return PTR_ERR(gc);
 
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
index 561e28b4d3aa..39175d373871 100644
--- a/drivers/gpio/gpio-reg.c
+++ b/drivers/gpio/gpio-reg.c
@@ -19,6 +19,8 @@ struct gpio_reg {
 	u32 direction;
 	u32 out;
 	void __iomem *reg;
+	struct irq_domain *irqdomain;
+	const int *irqs;
 };
 
 #define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
@@ -96,6 +98,17 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 	spin_unlock_irqrestore(&r->lock, flags);
 }
 
+static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	int irq = r->irqs[offset];
+
+	if (irq >= 0 && r->irqdomain)
+		irq = irq_find_mapping(r->irqdomain, irq);
+
+	return irq;
+}
+
 /**
  * gpio_reg_init - add a fixed in/out register as gpio
  * @dev: optional struct device associated with this register
@@ -104,7 +117,12 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
  * @label: GPIO chip label
  * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in
  * @def_out: initial GPIO output value
- * @names: array of %num strings describing each GPIO signal
+ * @names: array of %num strings describing each GPIO signal or %NULL
+ * @irqdom: irq domain or %NULL
+ * @irqs: array of %num ints describing the interrupt mapping for each
+ *        GPIO signal, or %NULL.  If @irqdom is %NULL, then this
+ *        describes the Linux interrupt number, otherwise it describes
+ *        the hardware interrupt number in the specified irq domain.
  *
  * Add a single-register GPIO device containing up to 32 GPIO signals,
  * where each GPIO has a fixed input or output configuration.  Only
@@ -114,7 +132,7 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
  */
 struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	int base, int num, const char *label, u32 direction, u32 def_out,
-	const char *const *names)
+	const char *const *names, struct irq_domain *irqdom, const int *irqs)
 {
 	struct gpio_reg *r;
 	int ret;
@@ -136,12 +154,15 @@ struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	r->gc.set = gpio_reg_set;
 	r->gc.get = gpio_reg_get;
 	r->gc.set_multiple = gpio_reg_set_multiple;
+	if (irqs)
+		r->gc.to_irq = gpio_reg_to_irq;
 	r->gc.base = base;
 	r->gc.ngpio = num;
 	r->gc.names = names;
 	r->direction = direction;
 	r->out = def_out;
 	r->reg = reg;
+	r->irqs = irqs;
 
 	if (dev)
 		ret = devm_gpiochip_add_data(dev, &r->gc, r);
diff --git a/include/linux/gpio/gpio-reg.h b/include/linux/gpio/gpio-reg.h
index 0352bec7319a..90e0b9060e6d 100644
--- a/include/linux/gpio/gpio-reg.h
+++ b/include/linux/gpio/gpio-reg.h
@@ -2,10 +2,11 @@
 #define GPIO_REG_H
 
 struct device;
+struct irq_domain;
 
 struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	int base, int num, const char *label, u32 direction, u32 def_out,
-	const char *const *names);
+	const char *const *names, struct irq_domain *irqdom, const int *irqs);
 
 int gpio_reg_resume(struct gpio_chip *gc);
 
-- 
2.1.0


-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-02 17:00             ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

Linus,

There's a change I'd like to merge into patch 5 - overall it looks
like the below, and allows us to use gpio-reg with the PXA mainstone
MST_PCMCIA[01] registers.  Some of these GPIO signals have hardware
interrupts associated with them, but not all.

Do you approve?

Thanks.

8<====
From: Russell King <rmk+kernel@armlinux.org.uk>
Subject: [PATCH] gpio: gpio-reg: add irq mapping for gpio-reg users

Add support for mapping gpio-reg gpios to interrupts.  This may be a
non-linear mapping - some gpios in the register may not even have
corresponding interrupts associated with them, so we need to pass an
array.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/mach-pxa/lubbock.c     |  2 +-
 arch/arm/mach-sa1100/assabet.c  |  2 +-
 arch/arm/mach-sa1100/neponset.c |  2 +-
 drivers/gpio/gpio-reg.c         | 25 +++++++++++++++++++++++--
 include/linux/gpio/gpio-reg.h   |  3 ++-
 5 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1f7bfabfa4eb..cd401546cea8 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -477,7 +477,7 @@ static void __init lubbock_init(void)
 
 	lubbock_misc_wr_gc = gpio_reg_init(NULL, (void *)&LUB_MISC_WR,
 					   -1, 16, "lubbock", 0, LUB_MISC_WR,
-					   NULL);
+					   NULL, NULL, NULL);
 	if (IS_ERR(lubbock_misc_wr_gc)) {
 		pr_err("Lubbock: unable to register lubbock GPIOs: %ld\n",
 		       PTR_ERR(lubbock_misc_wr_gc));
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 51950454afac..e086c609551c 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -120,7 +120,7 @@ static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
 	writel_relaxed(def_val, reg);
 
 	gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
-			   assabet_names);
+			   assabet_names, NULL, NULL);
 
 	if (IS_ERR(gc))
 		return PTR_ERR(gc);
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 5abc04fb196d..b16de1f0d5d0 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -240,7 +240,7 @@ static int neponset_init_gpio(struct gpio_chip **gcp,
 	struct gpio_chip *gc;
 
 	gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
-			   readl_relaxed(reg), names);
+			   readl_relaxed(reg), names, NULL, NULL);
 	if (IS_ERR(gc))
 		return PTR_ERR(gc);
 
diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c
index 561e28b4d3aa..39175d373871 100644
--- a/drivers/gpio/gpio-reg.c
+++ b/drivers/gpio/gpio-reg.c
@@ -19,6 +19,8 @@ struct gpio_reg {
 	u32 direction;
 	u32 out;
 	void __iomem *reg;
+	struct irq_domain *irqdomain;
+	const int *irqs;
 };
 
 #define to_gpio_reg(x) container_of(x, struct gpio_reg, gc)
@@ -96,6 +98,17 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
 	spin_unlock_irqrestore(&r->lock, flags);
 }
 
+static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+	struct gpio_reg *r = to_gpio_reg(gc);
+	int irq = r->irqs[offset];
+
+	if (irq >= 0 && r->irqdomain)
+		irq = irq_find_mapping(r->irqdomain, irq);
+
+	return irq;
+}
+
 /**
  * gpio_reg_init - add a fixed in/out register as gpio
  * @dev: optional struct device associated with this register
@@ -104,7 +117,12 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
  * @label: GPIO chip label
  * @direction: bitmask of fixed direction, one per GPIO signal, 1 = in
  * @def_out: initial GPIO output value
- * @names: array of %num strings describing each GPIO signal
+ * @names: array of %num strings describing each GPIO signal or %NULL
+ * @irqdom: irq domain or %NULL
+ * @irqs: array of %num ints describing the interrupt mapping for each
+ *        GPIO signal, or %NULL.  If @irqdom is %NULL, then this
+ *        describes the Linux interrupt number, otherwise it describes
+ *        the hardware interrupt number in the specified irq domain.
  *
  * Add a single-register GPIO device containing up to 32 GPIO signals,
  * where each GPIO has a fixed input or output configuration.  Only
@@ -114,7 +132,7 @@ static void gpio_reg_set_multiple(struct gpio_chip *gc, unsigned long *mask,
  */
 struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	int base, int num, const char *label, u32 direction, u32 def_out,
-	const char *const *names)
+	const char *const *names, struct irq_domain *irqdom, const int *irqs)
 {
 	struct gpio_reg *r;
 	int ret;
@@ -136,12 +154,15 @@ struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	r->gc.set = gpio_reg_set;
 	r->gc.get = gpio_reg_get;
 	r->gc.set_multiple = gpio_reg_set_multiple;
+	if (irqs)
+		r->gc.to_irq = gpio_reg_to_irq;
 	r->gc.base = base;
 	r->gc.ngpio = num;
 	r->gc.names = names;
 	r->direction = direction;
 	r->out = def_out;
 	r->reg = reg;
+	r->irqs = irqs;
 
 	if (dev)
 		ret = devm_gpiochip_add_data(dev, &r->gc, r);
diff --git a/include/linux/gpio/gpio-reg.h b/include/linux/gpio/gpio-reg.h
index 0352bec7319a..90e0b9060e6d 100644
--- a/include/linux/gpio/gpio-reg.h
+++ b/include/linux/gpio/gpio-reg.h
@@ -2,10 +2,11 @@
 #define GPIO_REG_H
 
 struct device;
+struct irq_domain;
 
 struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg,
 	int base, int num, const char *label, u32 direction, u32 def_out,
-	const char *const *names);
+	const char *const *names, struct irq_domain *irqdom, const int *irqs);
 
 int gpio_reg_resume(struct gpio_chip *gc);
 
-- 
2.1.0


-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-09-01 23:02                           ` Russell King - ARM Linux
@ 2016-09-02 17:50                             ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-02 17:50 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, Daniel Mack, linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

>> You're right, I submitted a patch for that, and I confirm it actually happens on
>> lubbock.
>
> That'll work fine for lubbock, but not the others (we can have several
> of the others enabled on sa11x0 platforms - eg, badge4 with neponset.)
Ah, I see. Let's drop the patch then, I won't be able to know what to return in
this function if 2 initialisations fail, nor if the first failure should be
fatal or not, nor if a rollback is possible after 1 success (badge4) and 1
failure (neponset).

> Ignore those for now - the old ARM IRQ stuff was silent on that, but genirq
> is more noisy.  I should probably make the sa1111 irqchip handle the both-
> edge case itself.
Ok.

>> Moreover, I have a bit of homework as I also see :
>>  - no SA1111 interrupts at all, especially nothing when I insert/remove my
>>    CompactFlash card
>>    This might be an effect of pxa_cplds_irqs.c I created, I must have a look.
>
> Do you get other SA1111 interrupts (eg, the PS/2 interrupts) delivered?
I see no other interrupts at all.
Actually I see no interrupt claimed in /proc/interrupts, where I would have
expected interrupt 305.
	cat /proc/interrupts
	           CPU0       
	 24:       1419        SC   8 Edge      gpio-0
	 25:          0        SC   9 Edge      gpio-1
	 26:          0        SC  10 Edge      gpio-mux
	 38:        118        SC  22 Edge      UART1
	 41:          0        SC  25 Edge      DMA
	 42:      40224        SC  26 Edge      ost0
	112:       1419      GPIO   0 Edge      pxa_cplds_irqs
	307:       1419  pxa_cplds   3 Edge      eth0
	387:          0  SA1111-h Edge      SA1111 PCMCIA card detect
	388:          0  SA1111-h Edge      SA1111 CF card detect
	389:          0  SA1111-h Edge      SA1111 PCMCIA BVD1
	390:          0  SA1111-h Edge      SA1111 CF BVD1
	Err:          0

Actually this leads me to think that this interrupt 305 is not "requested" nor
activated. I see in sa1111.c:506 :
  "irq_set_chained_handler_and_data(sachip->irq, sa1111_irq_handler, ..."
This puts in the handler and data, but I don't this is "enables" the interrupt,
right ?

I traced the code in the interrupt controller (pxa_cplds_irqs), the SA1111
physical line is not set (even with an AT/2 keyboard connected, and I don't
think anybody tried this AT/2 on a lubbock for a long time).

The interrupt is for sure masked, and therefore the SA1111 interrupts are not
fired. Even if they would have been enabled, the "pending interrupts register"
doesn't show any sa1111 interrupt pending, so there is something else.

As I don't know if "enable_irq()" in sa1111.c would be an option as I have no
sight on sa1111.c requirements, I would take any advice here.

> Hmm, on Neponset with a CF card inserted, I can cat that, and it reports
> the CIS.  Any error messages in the kernel log?
None.
I have an ever more suprising thing.
I tried again this morning, without changing a single line of code (excepting in
pxa_cplds_irqs.c) nor touching the CF card, and now it really rocks !!! :
hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
00000000  01 04 df 79 01 ff 1c 04  02 db 01 ff 18 02 df 01  |...y............|
00000010  20 04 45 00 01 04 15 0b  04 01 00 43 46 43 41 52  | .E........CFCAR|
00000020  44 00 ff 21 02 04 01 22  02 01 01 22 03 02 0c 0f  |D..!..."..."....|
00000030  1a 05 01 03 00 02 0f 1b  08 c0 40 a1 01 55 08 00  |..........@..U..|
00000040  20 1b 06 00 01 21 b5 1e  4d 1b 0a c1 41 99 01 55  | ....!..M...A..U|
00000050  64 f0 ff ff 20 1b 06 01  01 21 b5 1e 4d 1b 0f c2  |d... ....!..M...|
00000060  41 99 01 55 ea 61 f0 01  07 f6 03 01 ee 20 1b 06  |A..U.a....... ..|
00000070  02 01 21 b5 1e 4d 1b 0f  c3 41 99 01 55 ea 61 70  |..!..M...A..U.ap|
00000080  01 07 76 03 01 ee 20 1b  06 03 01 21 b5 1e 4d 14  |..v... ....!..M.|
00000090  00                                                |.|

I think this proves that your patches related to lubbock pcmcia conversion to
max1602 is fully functional !

Only the interrupt part to fight a bit, and then I'll try to make a couple of
tests on the IRDA part.

Cheers.

-- 
Robert

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-02 17:50                             ` Robert Jarzmik
  0 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-02 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

>> You're right, I submitted a patch for that, and I confirm it actually happens on
>> lubbock.
>
> That'll work fine for lubbock, but not the others (we can have several
> of the others enabled on sa11x0 platforms - eg, badge4 with neponset.)
Ah, I see. Let's drop the patch then, I won't be able to know what to return in
this function if 2 initialisations fail, nor if the first failure should be
fatal or not, nor if a rollback is possible after 1 success (badge4) and 1
failure (neponset).

> Ignore those for now - the old ARM IRQ stuff was silent on that, but genirq
> is more noisy.  I should probably make the sa1111 irqchip handle the both-
> edge case itself.
Ok.

>> Moreover, I have a bit of homework as I also see :
>>  - no SA1111 interrupts at all, especially nothing when I insert/remove my
>>    CompactFlash card
>>    This might be an effect of pxa_cplds_irqs.c I created, I must have a look.
>
> Do you get other SA1111 interrupts (eg, the PS/2 interrupts) delivered?
I see no other interrupts at all.
Actually I see no interrupt claimed in /proc/interrupts, where I would have
expected interrupt 305.
	cat /proc/interrupts
	           CPU0       
	 24:       1419        SC   8 Edge      gpio-0
	 25:          0        SC   9 Edge      gpio-1
	 26:          0        SC  10 Edge      gpio-mux
	 38:        118        SC  22 Edge      UART1
	 41:          0        SC  25 Edge      DMA
	 42:      40224        SC  26 Edge      ost0
	112:       1419      GPIO   0 Edge      pxa_cplds_irqs
	307:       1419  pxa_cplds   3 Edge      eth0
	387:          0  SA1111-h Edge      SA1111 PCMCIA card detect
	388:          0  SA1111-h Edge      SA1111 CF card detect
	389:          0  SA1111-h Edge      SA1111 PCMCIA BVD1
	390:          0  SA1111-h Edge      SA1111 CF BVD1
	Err:          0

Actually this leads me to think that this interrupt 305 is not "requested" nor
activated. I see in sa1111.c:506 :
  "irq_set_chained_handler_and_data(sachip->irq, sa1111_irq_handler, ..."
This puts in the handler and data, but I don't this is "enables" the interrupt,
right ?

I traced the code in the interrupt controller (pxa_cplds_irqs), the SA1111
physical line is not set (even with an AT/2 keyboard connected, and I don't
think anybody tried this AT/2 on a lubbock for a long time).

The interrupt is for sure masked, and therefore the SA1111 interrupts are not
fired. Even if they would have been enabled, the "pending interrupts register"
doesn't show any sa1111 interrupt pending, so there is something else.

As I don't know if "enable_irq()" in sa1111.c would be an option as I have no
sight on sa1111.c requirements, I would take any advice here.

> Hmm, on Neponset with a CF card inserted, I can cat that, and it reports
> the CIS.  Any error messages in the kernel log?
None.
I have an ever more suprising thing.
I tried again this morning, without changing a single line of code (excepting in
pxa_cplds_irqs.c) nor touching the CF card, and now it really rocks !!! :
hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
00000000  01 04 df 79 01 ff 1c 04  02 db 01 ff 18 02 df 01  |...y............|
00000010  20 04 45 00 01 04 15 0b  04 01 00 43 46 43 41 52  | .E........CFCAR|
00000020  44 00 ff 21 02 04 01 22  02 01 01 22 03 02 0c 0f  |D..!..."..."....|
00000030  1a 05 01 03 00 02 0f 1b  08 c0 40 a1 01 55 08 00  |.......... at ..U..|
00000040  20 1b 06 00 01 21 b5 1e  4d 1b 0a c1 41 99 01 55  | ....!..M...A..U|
00000050  64 f0 ff ff 20 1b 06 01  01 21 b5 1e 4d 1b 0f c2  |d... ....!..M...|
00000060  41 99 01 55 ea 61 f0 01  07 f6 03 01 ee 20 1b 06  |A..U.a....... ..|
00000070  02 01 21 b5 1e 4d 1b 0f  c3 41 99 01 55 ea 61 70  |..!..M...A..U.ap|
00000080  01 07 76 03 01 ee 20 1b  06 03 01 21 b5 1e 4d 14  |..v... ....!..M.|
00000090  00                                                |.|

I think this proves that your patches related to lubbock pcmcia conversion to
max1602 is fully functional !

Only the interrupt part to fight a bit, and then I'll try to make a couple of
tests on the IRDA part.

Cheers.

-- 
Robert

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-09-02 17:50                             ` Robert Jarzmik
@ 2016-09-02 18:56                               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 18:56 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

On Fri, Sep 02, 2016 at 07:50:35PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> >> Moreover, I have a bit of homework as I also see :
> >>  - no SA1111 interrupts at all, especially nothing when I insert/remove my
> >>    CompactFlash card
> >>    This might be an effect of pxa_cplds_irqs.c I created, I must have a look.
> >
> > Do you get other SA1111 interrupts (eg, the PS/2 interrupts) delivered?
> I see no other interrupts at all.
> Actually I see no interrupt claimed in /proc/interrupts, where I would have
> expected interrupt 305.
> 	cat /proc/interrupts
> 	           CPU0       
> 	 24:       1419        SC   8 Edge      gpio-0
> 	 25:          0        SC   9 Edge      gpio-1
> 	 26:          0        SC  10 Edge      gpio-mux
> 	 38:        118        SC  22 Edge      UART1
> 	 41:          0        SC  25 Edge      DMA
> 	 42:      40224        SC  26 Edge      ost0
> 	112:       1419      GPIO   0 Edge      pxa_cplds_irqs
> 	307:       1419  pxa_cplds   3 Edge      eth0
> 	387:          0  SA1111-h Edge      SA1111 PCMCIA card detect
> 	388:          0  SA1111-h Edge      SA1111 CF card detect
> 	389:          0  SA1111-h Edge      SA1111 PCMCIA BVD1
> 	390:          0  SA1111-h Edge      SA1111 CF BVD1
> 	Err:          0
> 
> Actually this leads me to think that this interrupt 305 is not "requested" nor
> activated. I see in sa1111.c:506 :
>   "irq_set_chained_handler_and_data(sachip->irq, sa1111_irq_handler, ..."
> This puts in the handler and data, but I don't this is "enables" the interrupt,
> right ?

It should enable the interrupt - the end of that does:

        if (handle != handle_bad_irq && is_chained) {
                irq_settings_set_noprobe(desc);
                irq_settings_set_norequest(desc);
                irq_settings_set_nothread(desc);
                desc->action = &chained_action;
                irq_startup(desc, true);
        }

and indeed, I see that it gets enabled on Assabet.  That irq_startup()
should result in the irqchip's irq_startup, irq_enable, or irq_unmask
method being called.

So, that should result in the IRQ to which the sa1111 is connected
being unmasked.

Chained interrupts don't appear in /proc/interrupts.

> I traced the code in the interrupt controller (pxa_cplds_irqs), the SA1111
> physical line is not set (even with an AT/2 keyboard connected, and I don't
> think anybody tried this AT/2 on a lubbock for a long time).

Hmm.  Looking at pxa_cplds_irqs, that's trying to support the CPLD
interrupts using a very very old and inefficient technique.  The
whole point of the chained interrupt system is to avoid several
overheads in the system...  I'm curious why PXA moved away from that.

One of the problems is that we end up nesting irq_entry()/irq_exit()
which contains a lot of code, eg trying to run softirqs.  All that
stuff is pure overhead because we'll never get to run anything like
that in this path.

I'm also very concerned that the conversion is wrong.  The old code
has this comment in the irq_unmask function:

-       /* the irq can be acknowledged only if deasserted, so it's done here */
-       LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);

In other words, we "acknowledge" (really clear the latched status) of
the interrupt _after_ we've serviced the peripheral, not before.
The new code tries to clear down the interrupt when masking it - in
other words, before the peripheral handler has had a chance to clear
down its interrupt.

I suspect you're seeing about twice as many interrupt counts on your
ethernet interface because of this - you'll be entering the handler
once for the real interrupt, but because the clear-down was ineffective,
you end up re-entering it a second time when hopefully the peripheral
is no longer asserting the interrupt.

> The interrupt is for sure masked, and therefore the SA1111 interrupts are not
> fired. Even if they would have been enabled, the "pending interrupts register"
> doesn't show any sa1111 interrupt pending, so there is something else.

Masked where though - in the SA1111 or FPGA?

> As I don't know if "enable_irq()" in sa1111.c would be an option as I have no
> sight on sa1111.c requirements, I would take any advice here.

It shouldn't be required, as I say above, irq_set_chained_handler_and_data()
deals with unmasking the IRQ already.

> > Hmm, on Neponset with a CF card inserted, I can cat that, and it reports
> > the CIS.  Any error messages in the kernel log?
> None.
> I have an ever more suprising thing.
> I tried again this morning, without changing a single line of code (excepting in
> pxa_cplds_irqs.c) nor touching the CF card, and now it really rocks !!! :
> hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
> hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
> 00000000  01 04 df 79 01 ff 1c 04  02 db 01 ff 18 02 df 01  |...y............|
> 00000010  20 04 45 00 01 04 15 0b  04 01 00 43 46 43 41 52  | .E........CFCAR|
> 00000020  44 00 ff 21 02 04 01 22  02 01 01 22 03 02 0c 0f  |D..!..."..."....|
> 00000030  1a 05 01 03 00 02 0f 1b  08 c0 40 a1 01 55 08 00  |..........@..U..|
> 00000040  20 1b 06 00 01 21 b5 1e  4d 1b 0a c1 41 99 01 55  | ....!..M...A..U|
> 00000050  64 f0 ff ff 20 1b 06 01  01 21 b5 1e 4d 1b 0f c2  |d... ....!..M...|
> 00000060  41 99 01 55 ea 61 f0 01  07 f6 03 01 ee 20 1b 06  |A..U.a....... ..|
> 00000070  02 01 21 b5 1e 4d 1b 0f  c3 41 99 01 55 ea 61 70  |..!..M...A..U.ap|
> 00000080  01 07 76 03 01 ee 20 1b  06 03 01 21 b5 1e 4d 14  |..v... ....!..M.|
> 00000090  00                                                |.|
> 
> I think this proves that your patches related to lubbock pcmcia conversion to
> max1602 is fully functional !

That is good news...

> Only the interrupt part to fight a bit, and then I'll try to make a couple of
> tests on the IRDA part.

I've some patches to convert mainstone, but they're not ready yet...

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
@ 2016-09-02 18:56                               ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 18:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Sep 02, 2016 at 07:50:35PM +0200, Robert Jarzmik wrote:
> Russell King - ARM Linux <linux@armlinux.org.uk> writes:
> >> Moreover, I have a bit of homework as I also see :
> >>  - no SA1111 interrupts at all, especially nothing when I insert/remove my
> >>    CompactFlash card
> >>    This might be an effect of pxa_cplds_irqs.c I created, I must have a look.
> >
> > Do you get other SA1111 interrupts (eg, the PS/2 interrupts) delivered?
> I see no other interrupts at all.
> Actually I see no interrupt claimed in /proc/interrupts, where I would have
> expected interrupt 305.
> 	cat /proc/interrupts
> 	           CPU0       
> 	 24:       1419        SC   8 Edge      gpio-0
> 	 25:          0        SC   9 Edge      gpio-1
> 	 26:          0        SC  10 Edge      gpio-mux
> 	 38:        118        SC  22 Edge      UART1
> 	 41:          0        SC  25 Edge      DMA
> 	 42:      40224        SC  26 Edge      ost0
> 	112:       1419      GPIO   0 Edge      pxa_cplds_irqs
> 	307:       1419  pxa_cplds   3 Edge      eth0
> 	387:          0  SA1111-h Edge      SA1111 PCMCIA card detect
> 	388:          0  SA1111-h Edge      SA1111 CF card detect
> 	389:          0  SA1111-h Edge      SA1111 PCMCIA BVD1
> 	390:          0  SA1111-h Edge      SA1111 CF BVD1
> 	Err:          0
> 
> Actually this leads me to think that this interrupt 305 is not "requested" nor
> activated. I see in sa1111.c:506 :
>   "irq_set_chained_handler_and_data(sachip->irq, sa1111_irq_handler, ..."
> This puts in the handler and data, but I don't this is "enables" the interrupt,
> right ?

It should enable the interrupt - the end of that does:

        if (handle != handle_bad_irq && is_chained) {
                irq_settings_set_noprobe(desc);
                irq_settings_set_norequest(desc);
                irq_settings_set_nothread(desc);
                desc->action = &chained_action;
                irq_startup(desc, true);
        }

and indeed, I see that it gets enabled on Assabet.  That irq_startup()
should result in the irqchip's irq_startup, irq_enable, or irq_unmask
method being called.

So, that should result in the IRQ to which the sa1111 is connected
being unmasked.

Chained interrupts don't appear in /proc/interrupts.

> I traced the code in the interrupt controller (pxa_cplds_irqs), the SA1111
> physical line is not set (even with an AT/2 keyboard connected, and I don't
> think anybody tried this AT/2 on a lubbock for a long time).

Hmm.  Looking at pxa_cplds_irqs, that's trying to support the CPLD
interrupts using a very very old and inefficient technique.  The
whole point of the chained interrupt system is to avoid several
overheads in the system...  I'm curious why PXA moved away from that.

One of the problems is that we end up nesting irq_entry()/irq_exit()
which contains a lot of code, eg trying to run softirqs.  All that
stuff is pure overhead because we'll never get to run anything like
that in this path.

I'm also very concerned that the conversion is wrong.  The old code
has this comment in the irq_unmask function:

-       /* the irq can be acknowledged only if deasserted, so it's done here */
-       LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);

In other words, we "acknowledge" (really clear the latched status) of
the interrupt _after_ we've serviced the peripheral, not before.
The new code tries to clear down the interrupt when masking it - in
other words, before the peripheral handler has had a chance to clear
down its interrupt.

I suspect you're seeing about twice as many interrupt counts on your
ethernet interface because of this - you'll be entering the handler
once for the real interrupt, but because the clear-down was ineffective,
you end up re-entering it a second time when hopefully the peripheral
is no longer asserting the interrupt.

> The interrupt is for sure masked, and therefore the SA1111 interrupts are not
> fired. Even if they would have been enabled, the "pending interrupts register"
> doesn't show any sa1111 interrupt pending, so there is something else.

Masked where though - in the SA1111 or FPGA?

> As I don't know if "enable_irq()" in sa1111.c would be an option as I have no
> sight on sa1111.c requirements, I would take any advice here.

It shouldn't be required, as I say above, irq_set_chained_handler_and_data()
deals with unmasking the IRQ already.

> > Hmm, on Neponset with a CF card inserted, I can cat that, and it reports
> > the CIS.  Any error messages in the kernel log?
> None.
> I have an ever more suprising thing.
> I tried again this morning, without changing a single line of code (excepting in
> pxa_cplds_irqs.c) nor touching the CF card, and now it really rocks !!! :
> hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
> hexdump -C /sys/class/pcmcia_socket/pcmcia_socket1/cis
> 00000000  01 04 df 79 01 ff 1c 04  02 db 01 ff 18 02 df 01  |...y............|
> 00000010  20 04 45 00 01 04 15 0b  04 01 00 43 46 43 41 52  | .E........CFCAR|
> 00000020  44 00 ff 21 02 04 01 22  02 01 01 22 03 02 0c 0f  |D..!..."..."....|
> 00000030  1a 05 01 03 00 02 0f 1b  08 c0 40 a1 01 55 08 00  |.......... at ..U..|
> 00000040  20 1b 06 00 01 21 b5 1e  4d 1b 0a c1 41 99 01 55  | ....!..M...A..U|
> 00000050  64 f0 ff ff 20 1b 06 01  01 21 b5 1e 4d 1b 0f c2  |d... ....!..M...|
> 00000060  41 99 01 55 ea 61 f0 01  07 f6 03 01 ee 20 1b 06  |A..U.a....... ..|
> 00000070  02 01 21 b5 1e 4d 1b 0f  c3 41 99 01 55 ea 61 70  |..!..M...A..U.ap|
> 00000080  01 07 76 03 01 ee 20 1b  06 03 01 21 b5 1e 4d 14  |..v... ....!..M.|
> 00000090  00                                                |.|
> 
> I think this proves that your patches related to lubbock pcmcia conversion to
> max1602 is fully functional !

That is good news...

> Only the interrupt part to fight a bit, and then I'll try to make a couple of
> tests on the IRDA part.

I've some patches to convert mainstone, but they're not ready yet...

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
  2016-09-01 23:32               ` David Miller
@ 2016-09-02 18:59                 ` Russell King - ARM Linux
  -1 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 18:59 UTC (permalink / raw)
  To: David Miller; +Cc: linux-arm-kernel, netdev, nico

On Thu, Sep 01, 2016 at 04:32:41PM -0700, David Miller wrote:
> From: Russell King - ARM Linux <linux@armlinux.org.uk>
> Date: Tue, 30 Aug 2016 11:51:17 +0100
> 
> > Please ack these changes; due to the dependencies, I wish to merge
> > them through my tree.  Thanks.
> 
> Acked-by: David S. Miller <davem@davemloft.net>

Many thanks David, I'll add that only to the two SMC91x patches.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* [PATCH 0/4] SA11x0 Clocks and removal of Neponset SMC91x hack
@ 2016-09-02 18:59                 ` Russell King - ARM Linux
  0 siblings, 0 replies; 235+ messages in thread
From: Russell King - ARM Linux @ 2016-09-02 18:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2016 at 04:32:41PM -0700, David Miller wrote:
> From: Russell King - ARM Linux <linux@armlinux.org.uk>
> Date: Tue, 30 Aug 2016 11:51:17 +0100
> 
> > Please ack these changes; due to the dependencies, I wish to merge
> > them through my tree.  Thanks.
> 
> Acked-by: David S. Miller <davem@davemloft.net>

Many thanks David, I'll add that only to the two SMC91x patches.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.

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

* Re: [PATCH 05/33] gpio: add generic single-register fixed-direction GPIO driver
  2016-09-02 18:56                               ` Russell King - ARM Linux
@ 2016-09-02 21:21                                 ` Robert Jarzmik
  -1 siblings, 0 replies; 235+ messages in thread
From: Robert Jarzmik @ 2016-09-02 21:21 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Alexandre Courbot, Linus Walleij, linux-pcmcia, Haojian Zhuang,
	linux-gpio, Kristoffer Ericson, linux-arm-kernel, Daniel Mack

Russell King - ARM Linux <linux@armlinux.org.uk> writes:

> On Fri, Sep 02, 2016 at 07:50:35PM +0200, Robert Jarzmik wrote:
> It should enable the interrupt - the end of that does:
>
>         if (handle != handle_bad_irq && is_chained) {
>                 irq_settings_set_noprobe(desc);
>                 irq_settings_set_norequest(desc);
>                 irq_settings_set_nothread(desc);
>                 desc->action = &chained_action;
>                 irq_startup(desc, true);
>         }
>
> and indeed, I see that it gets enabled on Assabet.  That irq_startup()
> should result in the irqchip's irq_startup, irq_enable, or irq_unmask
> method being called.
In my case, irq_startup() is never called for irq 305, ie. LUBBOCK_SA1111_IRQ.
See deep down the mail for the cause ...

> So, that should result in the IRQ to which the sa1111 is connected
> being unmasked.
Hmm, it never happens to me ...

> Chained interrupts don't appear in /proc/interrupts.
Ah ok.

>> I traced the code in the interrupt controller (pxa_cplds_irqs), the SA1111
>> physical line is not set (even with an AT/2 keyboard connected, and I don't
>> think anybody tried this AT/2 on a lubbock for a long time).
>
> Hmm.  Looking at pxa_cplds_irqs, that's trying to support the CPLD
> interrupts using a very very old and inefficient technique.  The
> whole point of the chained interrupt system is to avoid several
> overheads