Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1244745 > unrolled thread

[PATCH v2 00/14] ARM: at91: PMC driver rework

Started byAlexandre Belloni <alexandre.belloni@free-electrons.com>
First post2015-10-12 16:30 +0200
Last post2015-10-12 16:40 +0200
Articles 10 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 00/14] ARM: at91: PMC driver rework Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:30 +0200
    [PATCH v2 11/14] ARM: at91: pm: move idle functions to pm.c Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 12/14] ARM: at91: remove useless includes and function prototypes Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 08/14] clk: at91: pmc: move pmc structures to C file Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 06/14] clk: at91: only disable available IRQs Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 10/14] ARM: at91: pm: find and remap the pmc Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 01/14] ARM: at91/dt: use syscon for PMC Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 04/14] clk: at91: clk-main: factorize irq handling Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 07/14] clk: at91: pmc: merge at91_pmc_init in atmel_pmc_probe Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200
    [PATCH v2 13/14] usb: gadget: atmel: access the PMC using regmap Alexandre Belloni <alexandre.belloni@free-electrons.com> - 2015-10-12 16:40 +0200

#1244745 — [PATCH v2 00/14] ARM: at91: PMC driver rework

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:30 +0200
Subject[PATCH v2 00/14] ARM: at91: PMC driver rework
Message-ID<qiMgW-1zC-7@gated-at.bofh.it>
Hi,

This patch set is a cleanup that properly separate drivers needing to access the
PMC (PM and USB) from the clock driver by exposing the PMC as a syscon.

This also allows to implement a fix for preempt-rt. Currently, at91 platform are
crashing when using preempt-rt because the irq handler are transformed in
threaded irq handler but at the time the pmc registers its clocks, it is not
possible to creat threads, leading to a NULL pointer dereference in the kernel.

The new infrastructure uses polling until it is late enough to register threaded
irqs.


Changes in v2:
 - added Felipe's ack
 - dropped the first two patches as they are already in clk-next
 - reworked struct clk_main as suggested by Boris
 - changed the commit descritpion for "clk: at91: only disable available IRQs"
   as suggested by Ludovic
 - added Stephen's ack on patch 2

Alexandre Belloni (11):
  ARM: at91/dt: use syscon for PMC
  clk: at91: clk-main: factorize irq handling
  clk: at91: make IRQ optional and register them later
  clk: at91: pmc: merge at91_pmc_init in atmel_pmc_probe
  clk: at91: pmc: move pmc structures to C file
  ARM: at91: pm: simply call at91_pm_init
  ARM: at91: pm: find and remap the pmc
  ARM: at91: pm: move idle functions to pm.c
  ARM: at91: remove useless includes and function prototypes
  usb: gadget: atmel: access the PMC using regmap
  clk: at91: pmc: drop at91_pmc_base

Boris Brezillon (3):
  clk: at91: make use of syscon to share PMC registers in several
    drivers
  clk: at91: make use of syscon/regmap internally
  clk: at91: only disable available IRQs

 arch/arm/boot/dts/at91rm9200.dtsi       |   2 +-
 arch/arm/boot/dts/at91sam9260.dtsi      |   2 +-
 arch/arm/boot/dts/at91sam9261.dtsi      |   2 +-
 arch/arm/boot/dts/at91sam9263.dtsi      |   2 +-
 arch/arm/boot/dts/at91sam9g45.dtsi      |   2 +-
 arch/arm/boot/dts/at91sam9n12.dtsi      |   2 +-
 arch/arm/boot/dts/at91sam9rl.dtsi       |   2 +-
 arch/arm/boot/dts/at91sam9x5.dtsi       |   2 +-
 arch/arm/boot/dts/sama5d2.dtsi          |   2 +-
 arch/arm/boot/dts/sama5d3.dtsi          |   2 +-
 arch/arm/boot/dts/sama5d4.dtsi          |   2 +-
 arch/arm/mach-at91/Kconfig              |   1 +
 arch/arm/mach-at91/at91rm9200.c         |   2 -
 arch/arm/mach-at91/at91sam9.c           |   2 -
 arch/arm/mach-at91/generic.h            |  13 +-
 arch/arm/mach-at91/pm.c                 |  69 ++++-
 arch/arm/mach-at91/sama5.c              |   2 +-
 drivers/clk/at91/clk-h32mx.c            |  33 ++-
 drivers/clk/at91/clk-main.c             | 430 ++++++++++++++++++--------------
 drivers/clk/at91/clk-master.c           | 134 ++++++----
 drivers/clk/at91/clk-peripheral.c       | 131 ++++++----
 drivers/clk/at91/clk-pll.c              | 190 +++++++++-----
 drivers/clk/at91/clk-plldiv.c           |  42 ++--
 drivers/clk/at91/clk-programmable.c     |  92 ++++---
 drivers/clk/at91/clk-slow.c             |  27 +-
 drivers/clk/at91/clk-smd.c              |  54 ++--
 drivers/clk/at91/clk-system.c           | 129 +++++++---
 drivers/clk/at91/clk-usb.c              | 121 +++++----
 drivers/clk/at91/clk-utmi.c             | 116 ++++++---
 drivers/clk/at91/pmc.c                  | 300 +++++-----------------
 drivers/clk/at91/pmc.h                  |  93 +------
 drivers/usb/gadget/udc/atmel_usba_udc.c |  20 +-
 drivers/usb/gadget/udc/atmel_usba_udc.h |   2 +
 include/linux/clk/at91_pmc.h            |  12 -
 34 files changed, 1069 insertions(+), 968 deletions(-)

-- 
2.1.4

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

[toc] | [next] | [standalone]


#1244752 — [PATCH v2 11/14] ARM: at91: pm: move idle functions to pm.c

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 11/14] ARM: at91: pm: move idle functions to pm.c
Message-ID<qiMqB-1Ld-5@gated-at.bofh.it>
In reply to#1244745
Avoid using code from clk/at91 for PM.
This also has the bonus effect of setting arm_pm_idle for sama5 platforms.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/at91rm9200.c |  2 --
 arch/arm/mach-at91/at91sam9.c   |  2 --
 arch/arm/mach-at91/generic.h    |  6 ++----
 arch/arm/mach-at91/pm.c         | 37 ++++++++++++++++++++++++++++++++-----
 arch/arm/mach-at91/sama5.c      |  2 +-
 drivers/clk/at91/pmc.c          | 15 ---------------
 6 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index c1a7c6cc00e1..63b4fa25b48a 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -12,7 +12,6 @@
 #include <linux/of_platform.h>
 
 #include <asm/mach/arch.h>
-#include <asm/system_misc.h>
 
 #include "generic.h"
 #include "soc.h"
@@ -33,7 +32,6 @@ static void __init at91rm9200_dt_device_init(void)
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
 
-	arm_pm_idle = at91rm9200_idle;
 	at91rm9200_pm_init();
 }
 
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
index 7eb64f763034..cada2a6412b3 100644
--- a/arch/arm/mach-at91/at91sam9.c
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -62,8 +62,6 @@ static void __init at91sam9_common_init(void)
 		soc_dev = soc_device_to_device(soc);
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
-
-	arm_pm_idle = at91sam9_idle;
 }
 
 static void __init at91sam9_dt_device_init(void)
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index b0fa7dc7286d..d224e195706a 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -18,20 +18,18 @@
 extern void __init at91_map_io(void);
 extern void __init at91_alt_map_io(void);
 
-/* idle */
-extern void at91rm9200_idle(void);
-extern void at91sam9_idle(void);
-
 #ifdef CONFIG_PM
 extern void __init at91rm9200_pm_init(void);
 extern void __init at91sam9260_pm_init(void);
 extern void __init at91sam9g45_pm_init(void);
 extern void __init at91sam9x5_pm_init(void);
+extern void __init sama5_pm_init(void);
 #else
 static inline void __init at91rm9200_pm_init(void) { }
 static inline void __init at91sam9260_pm_init(void) { }
 static inline void __init at91sam9g45_pm_init(void) { }
 static inline void __init at91sam9x5_pm_init(void) { }
+static inline void __init sama5_pm_init(void) { }
 #endif
 
 #endif /* _AT91_GENERIC_H */
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 1dee29b33ff9..34f7f034c589 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -31,6 +31,7 @@
 #include <asm/mach/irq.h>
 #include <asm/fncpy.h>
 #include <asm/cacheflush.h>
+#include <asm/system_misc.h>
 
 #include "generic.h"
 #include "pm.h"
@@ -349,6 +350,21 @@ static __init void at91_dt_ramc(void)
 	at91_pm_set_standby(standby);
 }
 
+void at91rm9200_idle(void)
+{
+	/*
+	 * Disable the processor clock.  The processor will be automatically
+	 * re-enabled by an interrupt or by a reset.
+	 */
+	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+}
+
+void at91sam9_idle(void)
+{
+	writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR);
+	cpu_do_idle();
+}
+
 static void __init at91_pm_sram_init(void)
 {
 	struct gen_pool *sram_pool;
@@ -405,7 +421,7 @@ static const struct of_device_id atmel_pmc_ids[] = {
 	{ /* sentinel */ },
 };
 
-static void __init at91_pm_init(void)
+static void __init at91_pm_init(void (*pm_idle)(void))
 {
 	struct device_node *pmc_np;
 
@@ -419,6 +435,9 @@ static void __init at91_pm_init(void)
 		return;
 	}
 
+	if (pm_idle)
+		arm_pm_idle = pm_idle;
+
 	at91_pm_sram_init();
 
 	if (at91_suspend_sram_fn)
@@ -439,7 +458,7 @@ void __init at91rm9200_pm_init(void)
 	at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
 	at91_pm_data.memctrl = AT91_MEMCTRL_MC;
 
-	at91_pm_init();
+	at91_pm_init(at91rm9200_idle);
 }
 
 void __init at91sam9260_pm_init(void)
@@ -447,7 +466,7 @@ void __init at91sam9260_pm_init(void)
 	at91_dt_ramc();
 	at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
 	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
-	at91_pm_init();
+	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9g45_pm_init(void)
@@ -455,7 +474,7 @@ void __init at91sam9g45_pm_init(void)
 	at91_dt_ramc();
 	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
 	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
-	at91_pm_init();
+	at91_pm_init(at91sam9_idle);
 }
 
 void __init at91sam9x5_pm_init(void)
@@ -463,5 +482,13 @@ void __init at91sam9x5_pm_init(void)
 	at91_dt_ramc();
 	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
 	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
-	at91_pm_init();
+	at91_pm_init(at91sam9_idle);
+}
+
+void __init sama5_pm_init(void)
+{
+	at91_dt_ramc();
+	at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+	at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+	at91_pm_init(NULL);
 }
diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c
index d9cf6799aec0..df8fdf1cf66d 100644
--- a/arch/arm/mach-at91/sama5.c
+++ b/arch/arm/mach-at91/sama5.c
@@ -51,7 +51,7 @@ static void __init sama5_dt_device_init(void)
 		soc_dev = soc_device_to_device(soc);
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev);
-	at91sam9x5_pm_init();
+	sama5_pm_init();
 }
 
 static const char *const sama5_dt_board_compat[] __initconst = {
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 3aa886849304..3e150967b45e 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -44,21 +44,6 @@ struct at91_pmc {
 void __iomem *at91_pmc_base;
 EXPORT_SYMBOL_GPL(at91_pmc_base);
 
-void at91rm9200_idle(void)
-{
-	/*
-	 * Disable the processor clock.  The processor will be automatically
-	 * re-enabled by an interrupt or by a reset.
-	 */
-	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-}
-
-void at91sam9_idle(void)
-{
-	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-	cpu_do_idle();
-}
-
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
 			  struct clk_range *range)
 {
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244755 — [PATCH v2 12/14] ARM: at91: remove useless includes and function prototypes

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 12/14] ARM: at91: remove useless includes and function prototypes
Message-ID<qiMqB-1Ld-17@gated-at.bofh.it>
In reply to#1244745
Remove leftover from the previous cleanup

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/generic.h | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index d224e195706a..28ca57a2060f 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -11,13 +11,6 @@
 #ifndef _AT91_GENERIC_H
 #define _AT91_GENERIC_H
 
-#include <linux/of.h>
-#include <linux/reboot.h>
-
- /* Map io */
-extern void __init at91_map_io(void);
-extern void __init at91_alt_map_io(void);
-
 #ifdef CONFIG_PM
 extern void __init at91rm9200_pm_init(void);
 extern void __init at91sam9260_pm_init(void);
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244759 — [PATCH v2 08/14] clk: at91: pmc: move pmc structures to C file

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 08/14] clk: at91: pmc: move pmc structures to C file
Message-ID<qiMqC-1Ld-23@gated-at.bofh.it>
In reply to#1244745
pmc.c is now the only user of struct at91_pmc*, move their definition in
the C file.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/clk/at91/pmc.c | 12 ++++++++++++
 drivers/clk/at91/pmc.h | 12 ------------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index acc8f518b392..3aa886849304 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -29,6 +29,18 @@
 
 #include "pmc.h"
 
+struct at91_pmc_caps {
+	u32 available_irqs;
+};
+
+struct at91_pmc {
+	struct regmap *regmap;
+	int virq;
+	const struct at91_pmc_caps *caps;
+	struct irq_domain *irqdomain;
+	u32 imr;
+};
+
 void __iomem *at91_pmc_base;
 EXPORT_SYMBOL_GPL(at91_pmc_base);
 
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h
index 3b96c53c194c..550a461c7201 100644
--- a/drivers/clk/at91/pmc.h
+++ b/drivers/clk/at91/pmc.h
@@ -24,18 +24,6 @@ struct clk_range {
 
 #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
 
-struct at91_pmc_caps {
-	u32 available_irqs;
-};
-
-struct at91_pmc {
-	struct regmap *regmap;
-	int virq;
-	const struct at91_pmc_caps *caps;
-	struct irq_domain *irqdomain;
-	u32 imr;
-};
-
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
 			  struct clk_range *range);
 
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244767 — [PATCH v2 06/14] clk: at91: only disable available IRQs

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 06/14] clk: at91: only disable available IRQs
Message-ID<qiMqC-1Ld-33@gated-at.bofh.it>
In reply to#1244745
From: Boris Brezillon <boris.brezillon@free-electrons.com>

Only disable available IRQs in case writing to a reserved bit has a harmful
effect.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/clk/at91/pmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 6c1f08a73373..45dd32bf2531 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -287,7 +287,7 @@ static int __init atmel_pmc_probe(struct platform_device *pdev)
 	if (!pmc->irqdomain)
 		return 0;
 
-	regmap_write(pmc->regmap, AT91_PMC_IDR, 0xffffffff);
+	regmap_write(pmc->regmap, AT91_PMC_IDR, pmc->caps->available_irqs);
 	ret = request_irq(pmc->virq, pmc_irq_handler,
 			  IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc);
 	if (ret)
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244768 — [PATCH v2 10/14] ARM: at91: pm: find and remap the pmc

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 10/14] ARM: at91: pm: find and remap the pmc
Message-ID<qiMqC-1Ld-35@gated-at.bofh.it>
In reply to#1244745
To avoid relying on at91_pmc_read(), find the pmc node and remap it
locally.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/pm.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 5c2b60c5a2a1..1dee29b33ff9 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -35,6 +35,8 @@
 #include "generic.h"
 #include "pm.h"
 
+void __iomem *pmc;
+
 /*
  * FIXME: this is needed to communicate between the pinctrl driver and
  * the PM implementation in the machine. Possibly part of the PM
@@ -85,7 +87,7 @@ static int at91_pm_verify_clocks(void)
 	unsigned long scsr;
 	int i;
 
-	scsr = at91_pmc_read(AT91_PMC_SCSR);
+	scsr = readl(pmc + AT91_PMC_SCSR);
 
 	/* USB must not be using PLLB */
 	if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
@@ -99,8 +101,7 @@ static int at91_pm_verify_clocks(void)
 
 		if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
 			continue;
-
-		css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+		css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
 			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
@@ -143,8 +144,8 @@ static void at91_pm_suspend(suspend_state_t state)
 	flush_cache_all();
 	outer_disable();
 
-	at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0],
-				at91_ramc_base[1], pm_data);
+	at91_suspend_sram_fn(pmc, at91_ramc_base[0],
+			     at91_ramc_base[1], pm_data);
 
 	outer_resume();
 }
@@ -394,13 +395,32 @@ static void __init at91_pm_sram_init(void)
 			&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz);
 }
 
+static const struct of_device_id atmel_pmc_ids[] = {
+	{ .compatible = "atmel,at91rm9200-pmc"  },
+	{ .compatible = "atmel,at91sam9260-pmc" },
+	{ .compatible = "atmel,at91sam9g45-pmc" },
+	{ .compatible = "atmel,at91sam9n12-pmc" },
+	{ .compatible = "atmel,at91sam9x5-pmc" },
+	{ .compatible = "atmel,sama5d3-pmc" },
+	{ /* sentinel */ },
+};
+
 static void __init at91_pm_init(void)
 {
-	at91_pm_sram_init();
+	struct device_node *pmc_np;
 
 	if (at91_cpuidle_device.dev.platform_data)
 		platform_device_register(&at91_cpuidle_device);
 
+	pmc_np = of_find_matching_node(NULL, atmel_pmc_ids);
+	pmc = of_iomap(pmc_np, 0);
+	if (!pmc) {
+		pr_info("AT91: PM not supported, PMC not found");
+		return;
+	}
+
+	at91_pm_sram_init();
+
 	if (at91_suspend_sram_fn)
 		suspend_set_ops(&at91_pm_ops);
 	else
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244774 — [PATCH v2 01/14] ARM: at91/dt: use syscon for PMC

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 01/14] ARM: at91/dt: use syscon for PMC
Message-ID<qiMqD-1Ld-53@gated-at.bofh.it>
In reply to#1244745
The PMC is not only used to drive the clocks but also has some registers
related to other functions. One of those is for example the USB gadget
bias.
Using a syscon allows to properly separate those functions.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/boot/dts/at91rm9200.dtsi  | 2 +-
 arch/arm/boot/dts/at91sam9260.dtsi | 2 +-
 arch/arm/boot/dts/at91sam9261.dtsi | 2 +-
 arch/arm/boot/dts/at91sam9263.dtsi | 2 +-
 arch/arm/boot/dts/at91sam9g45.dtsi | 2 +-
 arch/arm/boot/dts/at91sam9n12.dtsi | 2 +-
 arch/arm/boot/dts/at91sam9rl.dtsi  | 2 +-
 arch/arm/boot/dts/at91sam9x5.dtsi  | 2 +-
 arch/arm/boot/dts/sama5d2.dtsi     | 2 +-
 arch/arm/boot/dts/sama5d3.dtsi     | 2 +-
 arch/arm/boot/dts/sama5d4.dtsi     | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index 60edd8baebb8..39eb1e3fc6b8 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -97,7 +97,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91rm9200-pmc";
+				compatible = "atmel,at91rm9200-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index be9c027ddd97..d4884dd1c243 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -100,7 +100,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91sam9260-pmc";
+				compatible = "atmel,at91sam9260-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9261.dtsi b/arch/arm/boot/dts/at91sam9261.dtsi
index ce1e3e94a40c..5e09de4eb9cd 100644
--- a/arch/arm/boot/dts/at91sam9261.dtsi
+++ b/arch/arm/boot/dts/at91sam9261.dtsi
@@ -568,7 +568,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91rm9200-pmc";
+				compatible = "atmel,at91rm9200-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index f1f5fa3a9e6e..93446420af25 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -93,7 +93,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91rm9200-pmc";
+				compatible = "atmel,at91rm9200-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 18b8b9e29704..af8b708ac312 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -114,7 +114,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91sam9g45-pmc";
+				compatible = "atmel,at91sam9g45-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index 32bc9a189db0..95569a87b6c9 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -97,7 +97,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91sam9n12-pmc";
+				compatible = "atmel,at91sam9n12-pmc", "syscon";
 				reg = <0xfffffc00 0x200>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9rl.dtsi b/arch/arm/boot/dts/at91sam9rl.dtsi
index a0b90aedd3b8..6d829db4e887 100644
--- a/arch/arm/boot/dts/at91sam9rl.dtsi
+++ b/arch/arm/boot/dts/at91sam9rl.dtsi
@@ -814,7 +814,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91sam9g45-pmc";
+				compatible = "atmel,at91sam9g45-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 747d8f070a5c..0a0ea6bce1b9 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -105,7 +105,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,at91sam9x5-pmc";
+				compatible = "atmel,at91sam9x5-pmc", "syscon";
 				reg = <0xfffffc00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 034cd48ae28b..780c8afc7600 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -286,7 +286,7 @@
 			};
 
 			pmc: pmc@f0014000 {
-				compatible = "atmel,sama5d2-pmc";
+				compatible = "atmel,sama5d2-pmc", "syscon";
 				reg = <0xf0014000 0x160>;
 				interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi
index 7fa276515f11..fa054b28c2c3 100644
--- a/arch/arm/boot/dts/sama5d3.dtsi
+++ b/arch/arm/boot/dts/sama5d3.dtsi
@@ -906,7 +906,7 @@
 			};
 
 			pmc: pmc@fffffc00 {
-				compatible = "atmel,sama5d3-pmc";
+				compatible = "atmel,sama5d3-pmc", "syscon";
 				reg = <0xfffffc00 0x120>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 8d1de29e8da1..3ab2c83ecc8b 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -386,7 +386,7 @@
 			};
 
 			pmc: pmc@f0018000 {
-				compatible = "atmel,sama5d3-pmc";
+				compatible = "atmel,sama5d3-pmc", "syscon";
 				reg = <0xf0018000 0x120>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 				interrupt-controller;
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244779 — [PATCH v2 04/14] clk: at91: clk-main: factorize irq handling

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 04/14] clk: at91: clk-main: factorize irq handling
Message-ID<qiMqD-1Ld-69@gated-at.bofh.it>
In reply to#1244745
The three different irq handlers are doing the same thing, factorize their
code in a generic irq handler.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/clk/at91/clk-main.c | 144 +++++++++++++++++++-------------------------
 1 file changed, 63 insertions(+), 81 deletions(-)

diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c
index c1f119748bdc..5841eb958f83 100644
--- a/drivers/clk/at91/clk-main.c
+++ b/drivers/clk/at91/clk-main.c
@@ -34,25 +34,28 @@
 
 #define MOR_KEY_MASK		(0xff << 16)
 
-struct clk_main_osc {
+struct clk_main {
 	struct clk_hw hw;
 	struct regmap *regmap;
 	unsigned int irq;
 	wait_queue_head_t wait;
 };
 
-#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
+#define to_clk_main(hw) container_of(hw, struct clk_main, hw)
+
+struct clk_main_osc {
+	struct clk_main base;
+};
+
+#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, base.hw)
 
 struct clk_main_rc_osc {
-	struct clk_hw hw;
-	struct regmap *regmap;
-	unsigned int irq;
-	wait_queue_head_t wait;
+	struct clk_main base;
 	unsigned long frequency;
 	unsigned long accuracy;
 };
 
-#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
+#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, base.hw)
 
 struct clk_rm9200_main {
 	struct clk_hw hw;
@@ -62,21 +65,20 @@ struct clk_rm9200_main {
 #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
 
 struct clk_sam9x5_main {
-	struct clk_hw hw;
-	struct regmap *regmap;
-	unsigned int irq;
-	wait_queue_head_t wait;
+	struct clk_main base;
 	u8 parent;
 };
 
-#define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw)
+#define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, base.hw)
 
-static irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id)
+/* Generic structure */
+
+static irqreturn_t clk_main_irq_handler(int irq, void *dev_id)
 {
-	struct clk_main_osc *osc = dev_id;
+	struct clk_main *clkmain = dev_id;
 
-	wake_up(&osc->wait);
-	disable_irq_nosync(osc->irq);
+	wake_up(&clkmain->wait);
+	disable_irq_nosync(clkmain->irq);
 
 	return IRQ_HANDLED;
 }
@@ -93,7 +95,7 @@ static inline bool clk_main_osc_ready(struct regmap *regmap)
 static int clk_main_osc_prepare(struct clk_hw *hw)
 {
 	struct clk_main_osc *osc = to_clk_main_osc(hw);
-	struct regmap *regmap = osc->regmap;
+	struct regmap *regmap = osc->base.regmap;
 	u32 tmp;
 
 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
@@ -108,8 +110,8 @@ static int clk_main_osc_prepare(struct clk_hw *hw)
 	}
 
 	while (!clk_main_osc_ready(regmap)) {
-		enable_irq(osc->irq);
-		wait_event(osc->wait,
+		enable_irq(osc->base.irq);
+		wait_event(osc->base.wait,
 			   clk_main_osc_ready(regmap));
 	}
 
@@ -119,7 +121,7 @@ static int clk_main_osc_prepare(struct clk_hw *hw)
 static void clk_main_osc_unprepare(struct clk_hw *hw)
 {
 	struct clk_main_osc *osc = to_clk_main_osc(hw);
-	struct regmap *regmap = osc->regmap;
+	struct regmap *regmap = osc->base.regmap;
 	u32 tmp;
 
 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
@@ -136,7 +138,7 @@ static void clk_main_osc_unprepare(struct clk_hw *hw)
 static int clk_main_osc_is_prepared(struct clk_hw *hw)
 {
 	struct clk_main_osc *osc = to_clk_main_osc(hw);
-	struct regmap *regmap = osc->regmap;
+	struct regmap *regmap = osc->base.regmap;
 	u32 tmp, status;
 
 	regmap_read(regmap, AT91_CKGR_MOR, &tmp);
@@ -179,14 +181,14 @@ at91_clk_register_main_osc(struct regmap *regmap,
 	init.num_parents = 1;
 	init.flags = CLK_IGNORE_UNUSED;
 
-	osc->hw.init = &init;
-	osc->regmap = regmap;
-	osc->irq = irq;
+	osc->base.hw.init = &init;
+	osc->base.regmap = regmap;
+	osc->base.irq = irq;
 
-	init_waitqueue_head(&osc->wait);
-	irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
-	ret = request_irq(osc->irq, clk_main_osc_irq_handler,
-			  IRQF_TRIGGER_HIGH, name, osc);
+	init_waitqueue_head(&osc->base.wait);
+	irq_set_status_flags(irq, IRQ_NOAUTOEN);
+	ret = request_irq(irq, clk_main_irq_handler,
+			  IRQF_TRIGGER_HIGH, name, &osc->base);
 	if (ret) {
 		kfree(osc);
 		return ERR_PTR(ret);
@@ -198,7 +200,7 @@ at91_clk_register_main_osc(struct regmap *regmap,
 				   AT91_PMC_MOSCEN,
 				   AT91_PMC_OSCBYPASS | AT91_PMC_KEY);
 
-	clk = clk_register(NULL, &osc->hw);
+	clk = clk_register(NULL, &osc->base.hw);
 	if (IS_ERR(clk)) {
 		free_irq(irq, osc);
 		kfree(osc);
@@ -237,16 +239,6 @@ static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
 CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
 	       of_at91rm9200_clk_main_osc_setup);
 
-static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id)
-{
-	struct clk_main_rc_osc *osc = dev_id;
-
-	wake_up(&osc->wait);
-	disable_irq_nosync(osc->irq);
-
-	return IRQ_HANDLED;
-}
-
 static bool clk_main_rc_osc_ready(struct regmap *regmap)
 {
 	unsigned int status;
@@ -259,7 +251,7 @@ static bool clk_main_rc_osc_ready(struct regmap *regmap)
 static int clk_main_rc_osc_prepare(struct clk_hw *hw)
 {
 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
-	struct regmap *regmap = osc->regmap;
+	struct regmap *regmap = osc->base.regmap;
 	unsigned int mor;
 
 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
@@ -270,8 +262,8 @@ static int clk_main_rc_osc_prepare(struct clk_hw *hw)
 				   AT91_PMC_MOSCRCEN | AT91_PMC_KEY);
 
 	while (!clk_main_rc_osc_ready(regmap)) {
-		enable_irq(osc->irq);
-		wait_event(osc->wait,
+		enable_irq(osc->base.irq);
+		wait_event(osc->base.wait,
 			   clk_main_rc_osc_ready(regmap));
 	}
 
@@ -281,7 +273,7 @@ static int clk_main_rc_osc_prepare(struct clk_hw *hw)
 static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
 {
 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
-	struct regmap *regmap = osc->regmap;
+	struct regmap *regmap = osc->base.regmap;
 	unsigned int mor;
 
 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
@@ -296,7 +288,7 @@ static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
 static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
 {
 	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
-	struct regmap *regmap = osc->regmap;
+	struct regmap *regmap = osc->base.regmap;
 	unsigned int mor, status;
 
 	regmap_read(regmap, AT91_CKGR_MOR, &mor);
@@ -353,20 +345,20 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
 	init.num_parents = 0;
 	init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED;
 
-	osc->hw.init = &init;
-	osc->regmap = regmap;
-	osc->irq = irq;
+	osc->base.hw.init = &init;
+	osc->base.regmap = regmap;
+	osc->base.irq = irq;
 	osc->frequency = frequency;
 	osc->accuracy = accuracy;
 
-	init_waitqueue_head(&osc->wait);
-	irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
-	ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler,
-			  IRQF_TRIGGER_HIGH, name, osc);
+	init_waitqueue_head(&osc->base.wait);
+	irq_set_status_flags(irq, IRQ_NOAUTOEN);
+	ret = request_irq(irq, clk_main_irq_handler,
+			  IRQF_TRIGGER_HIGH, name, &osc->base);
 	if (ret)
 		return ERR_PTR(ret);
 
-	clk = clk_register(NULL, &osc->hw);
+	clk = clk_register(NULL, &osc->base.hw);
 	if (IS_ERR(clk)) {
 		free_irq(irq, osc);
 		kfree(osc);
@@ -529,16 +521,6 @@ static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
 CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
 	       of_at91rm9200_clk_main_setup);
 
-static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id)
-{
-	struct clk_sam9x5_main *clkmain = dev_id;
-
-	wake_up(&clkmain->wait);
-	disable_irq_nosync(clkmain->irq);
-
-	return IRQ_HANDLED;
-}
-
 static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
 {
 	unsigned int status;
@@ -551,11 +533,11 @@ static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
 static int clk_sam9x5_main_prepare(struct clk_hw *hw)
 {
 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
-	struct regmap *regmap = clkmain->regmap;
+	struct regmap *regmap = clkmain->base.regmap;
 
 	while (!clk_sam9x5_main_ready(regmap)) {
-		enable_irq(clkmain->irq);
-		wait_event(clkmain->wait,
+		enable_irq(clkmain->base.irq);
+		wait_event(clkmain->base.wait,
 			   clk_sam9x5_main_ready(regmap));
 	}
 
@@ -566,7 +548,7 @@ static int clk_sam9x5_main_is_prepared(struct clk_hw *hw)
 {
 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 
-	return clk_sam9x5_main_ready(clkmain->regmap);
+	return clk_sam9x5_main_ready(clkmain->base.regmap);
 }
 
 static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
@@ -574,13 +556,13 @@ static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw,
 {
 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 
-	return clk_main_recalc_rate(clkmain->regmap, parent_rate);
+	return clk_main_recalc_rate(clkmain->base.regmap, parent_rate);
 }
 
 static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
 {
 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
-	struct regmap *regmap = clkmain->regmap;
+	struct regmap *regmap = clkmain->base.regmap;
 	unsigned int tmp;
 
 	if (index > 1)
@@ -595,8 +577,8 @@ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
 		regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
 
 	while (!clk_sam9x5_main_ready(regmap)) {
-		enable_irq(clkmain->irq);
-		wait_event(clkmain->wait,
+		enable_irq(clkmain->base.irq);
+		wait_event(clkmain->base.wait,
 			   clk_sam9x5_main_ready(regmap));
 	}
 
@@ -608,7 +590,7 @@ static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw)
 	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
 	unsigned int status;
 
-	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
+	regmap_read(clkmain->base.regmap, AT91_CKGR_MOR, &status);
 
 	return status & AT91_PMC_MOSCEN ? 1 : 0;
 }
@@ -650,21 +632,21 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
 	init.num_parents = num_parents;
 	init.flags = CLK_SET_PARENT_GATE;
 
-	clkmain->hw.init = &init;
-	clkmain->regmap = regmap;
-	clkmain->irq = irq;
-	regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status);
+	clkmain->base.hw.init = &init;
+	clkmain->base.regmap = regmap;
+	clkmain->base.irq = irq;
+	regmap_read(clkmain->base.regmap, AT91_CKGR_MOR, &status);
 	clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0;
-	init_waitqueue_head(&clkmain->wait);
-	irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
-	ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler,
-			  IRQF_TRIGGER_HIGH, name, clkmain);
+	init_waitqueue_head(&clkmain->base.wait);
+	irq_set_status_flags(irq, IRQ_NOAUTOEN);
+	ret = request_irq(irq, clk_main_irq_handler,
+			  IRQF_TRIGGER_HIGH, name, &clkmain->base);
 	if (ret)
 		return ERR_PTR(ret);
 
-	clk = clk_register(NULL, &clkmain->hw);
+	clk = clk_register(NULL, &clkmain->base.hw);
 	if (IS_ERR(clk)) {
-		free_irq(clkmain->irq, clkmain);
+		free_irq(irq, clkmain);
 		kfree(clkmain);
 	}
 
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244781 — [PATCH v2 07/14] clk: at91: pmc: merge at91_pmc_init in atmel_pmc_probe

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 07/14] clk: at91: pmc: merge at91_pmc_init in atmel_pmc_probe
Message-ID<qiMqE-1Ld-75@gated-at.bofh.it>
In reply to#1244745
at91_pmc_init() doesn't do much anymore, merge it in atmel_pmc_probe().

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/clk/at91/pmc.c | 31 ++++++-------------------------
 1 file changed, 6 insertions(+), 25 deletions(-)

diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c
index 45dd32bf2531..acc8f518b392 100644
--- a/drivers/clk/at91/pmc.c
+++ b/drivers/clk/at91/pmc.c
@@ -223,29 +223,6 @@ static const struct at91_pmc_caps sama5d3_caps = {
 			  AT91_PMC_CFDEV,
 };
 
-static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
-					     struct regmap *regmap,
-					     void __iomem *regbase, int virq,
-					     const struct at91_pmc_caps *caps)
-{
-	struct at91_pmc *pmc;
-
-	if (!regbase || !virq ||  !caps)
-		return NULL;
-
-	at91_pmc_base = regbase;
-
-	pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
-	if (!pmc)
-		return NULL;
-
-	pmc->regmap = regmap;
-	pmc->virq = virq;
-	pmc->caps = caps;
-
-	return pmc;
-}
-
 static const struct of_device_id atmel_pmc_dt_ids[] = {
 	{ .compatible = "atmel,at91rm9200-pmc", .data = &at91rm9200_caps },
 	{ .compatible = "atmel,at91sam9260-pmc", .data = &at91sam9260_caps },
@@ -262,11 +239,12 @@ static int __init atmel_pmc_probe(struct platform_device *pdev)
 	const struct at91_pmc_caps *caps;
 	struct device_node *np = pdev->dev.of_node;
 	struct at91_pmc *pmc;
-	void __iomem *regbase = of_iomap(np, 0);
 	struct regmap *regmap;
 	int virq;
 	int ret = 0;
 
+	at91_pmc_base = of_iomap(np, 0);
+
 	regmap = syscon_node_to_regmap(np);
 	if (IS_ERR(regmap))
 		panic("Could not retrieve syscon regmap");
@@ -278,10 +256,13 @@ static int __init atmel_pmc_probe(struct platform_device *pdev)
 	of_id = of_match_device(atmel_pmc_dt_ids, &pdev->dev);
 	caps = of_id->data;
 
-	pmc = at91_pmc_init(np, regmap, regbase, virq, caps);
+	pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
 	if (!pmc)
 		return 0;
 
+	pmc->regmap = regmap;
+	pmc->virq = virq;
+	pmc->caps = caps;
 	pmc->irqdomain = irq_domain_add_linear(pdev->dev.of_node, 32,
 					       &pmc_irq_ops, pmc);
 	if (!pmc->irqdomain)
-- 
2.1.4

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

[toc] | [prev] | [next] | [standalone]


#1244782 — [PATCH v2 13/14] usb: gadget: atmel: access the PMC using regmap

FromAlexandre Belloni <alexandre.belloni@free-electrons.com>
Date2015-10-12 16:40 +0200
Subject[PATCH v2 13/14] usb: gadget: atmel: access the PMC using regmap
Message-ID<qiMqE-1Ld-77@gated-at.bofh.it>
In reply to#1244745
Use regmap to access the PMC to avoid using at91_pmc_read and
at91_pmc_write.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/udc/atmel_usba_udc.c | 20 ++++++++++----------
 drivers/usb/gadget/udc/atmel_usba_udc.h |  2 ++
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
index 3dfada8d6061..40977cd832af 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
@@ -17,7 +17,9 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
+#include <linux/mfd/syscon.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/atmel_usba_udc.h>
@@ -1888,20 +1890,15 @@ static int atmel_usba_stop(struct usb_gadget *gadget)
 #ifdef CONFIG_OF
 static void at91sam9rl_toggle_bias(struct usba_udc *udc, int is_on)
 {
-	unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
-
-	if (is_on)
-		at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
-	else
-		at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
+	regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN,
+			   is_on ? AT91_PMC_BIASEN : 0);
 }
 
 static void at91sam9g45_pulse_bias(struct usba_udc *udc)
 {
-	unsigned int uckr = at91_pmc_read(AT91_CKGR_UCKR);
-
-	at91_pmc_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN));
-	at91_pmc_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN);
+	regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN, 0);
+	regmap_update_bits(udc->pmc, AT91_CKGR_UCKR, AT91_PMC_BIASEN,
+			   AT91_PMC_BIASEN);
 }
 
 static const struct usba_udc_errata at91sam9rl_errata = {
@@ -1938,6 +1935,9 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
 		return ERR_PTR(-EINVAL);
 
 	udc->errata = match->data;
+	udc->pmc = syscon_regmap_lookup_by_compatible("atmel,at91sam9g45-pmc");
+	if (udc->errata && IS_ERR(udc->pmc))
+		return ERR_CAST(udc->pmc);
 
 	udc->num_ep = 0;
 
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.h b/drivers/usb/gadget/udc/atmel_usba_udc.h
index ea448a344767..3e1c9d589dfa 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.h
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.h
@@ -354,6 +354,8 @@ struct usba_udc {
 	struct dentry *debugfs_root;
 	struct dentry *debugfs_regs;
 #endif
+
+	struct regmap *pmc;
 };
 
 static inline struct usba_ep *to_usba_ep(struct usb_ep *ep)
-- 
2.1.4

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

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web