[PATCH 2/5] fbdev: sa1100fb: make use of device clock

2013-11-11 Thread Dmitry Eremin-Solenikov
Use per-device clock (instead of calling cpufreq_get(0), which can
return 0 if no cpu frequency driver is selected) to program timings.

Signed-off-by: Dmitry Eremin-Solenikov dbarysh...@gmail.com
---
 drivers/video/sa1100fb.c | 24 +---
 drivers/video/sa1100fb.h |  1 +
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index de76da0..05d1b37 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -178,6 +178,7 @@
 #include linux/dma-mapping.h
 #include linux/mutex.h
 #include linux/io.h
+#include linux/clk.h
 
 #include video/sa1100fb.h
 
@@ -413,9 +414,9 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct 
fb_info *info)
var-transp.offset);
 
 #ifdef CONFIG_CPU_FREQ
-   dev_dbg(fbi-dev, dma period = %d ps, clock = %d kHz\n,
+   dev_dbg(fbi-dev, dma period = %d ps, clock = %ld kHz\n,
sa1100fb_display_dma_period(var),
-   cpufreq_get(smp_processor_id()));
+   clk_get_rate(fbi-clk) / 1000);
 #endif
 
return 0;
@@ -586,9 +587,10 @@ static struct fb_ops sa1100fb_ops = {
  * Calculate the PCD value from the clock rate (in picoseconds).
  * We take account of the PPCR clock setting.
  */
-static inline unsigned int get_pcd(unsigned int pixclock, unsigned int 
cpuclock)
+static inline unsigned int get_pcd(struct sa1100fb_info *fbi,
+   unsigned int pixclock)
 {
-   unsigned int pcd = cpuclock / 100;
+   unsigned int pcd = clk_get_rate(fbi-clk) / 100 / 1000;
 
pcd *= pixclock;
pcd /= 1000;
@@ -667,7 +669,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo 
*var, struct sa1100fb_
LCCR2_BegFrmDel(var-upper_margin) +
LCCR2_EndFrmDel(var-lower_margin);
 
-   pcd = get_pcd(var-pixclock, cpufreq_get(0));
+   pcd = get_pcd(fbi, var-pixclock);
new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi-inf-lccr3 |
(var-sync  FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : 
LCCR3_HorSnchL) |
(var-sync  FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : 
LCCR3_VrtSnchL);
@@ -1003,7 +1005,6 @@ sa1100fb_freq_transition(struct notifier_block *nb, 
unsigned long val,
 void *data)
 {
struct sa1100fb_info *fbi = TO_INF(nb, freq_transition);
-   struct cpufreq_freqs *f = data;
u_int pcd;
 
switch (val) {
@@ -1012,7 +1013,7 @@ sa1100fb_freq_transition(struct notifier_block *nb, 
unsigned long val,
break;
 
case CPUFREQ_POSTCHANGE:
-   pcd = get_pcd(fbi-fb.var.pixclock, f-new);
+   pcd = get_pcd(fbi, fbi-fb.var.pixclock);
fbi-reg_lccr3 = (fbi-reg_lccr3  ~0xff) | 
LCCR3_PixClkDiv(pcd);
set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
break;
@@ -1219,6 +1220,13 @@ static int sa1100fb_probe(struct platform_device *pdev)
if (!fbi)
goto failed;
 
+   fbi-clk = clk_get(pdev-dev, NULL);
+   if (IS_ERR(fbi-clk)) {
+   ret = PTR_ERR(fbi-clk);
+   fbi-clk = NULL;
+   goto failed;
+   }
+
fbi-base = ioremap(res-start, resource_size(res));
if (!fbi-base)
goto failed;
@@ -1271,6 +1279,8 @@ static int sa1100fb_probe(struct platform_device *pdev)
  failed:
if (fbi)
iounmap(fbi-base);
+   if (fbi-clk)
+   clk_put(fbi-clk);
kfree(fbi);
release_mem_region(res-start, resource_size(res));
return ret;
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index fc5d429..0139d13 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -68,6 +68,7 @@ struct sa1100fb_info {
 #endif
 
const struct sa1100fb_mach_info *inf;
+   struct clk *clk;
 };
 
 #define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member)
-- 
1.8.4.2


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


[PATCH 3/5] pcmcia: sa1100: make use of device clock

2013-11-11 Thread Dmitry Eremin-Solenikov
Use per-device clock (instead of calling cpufreq_get(0), which can
return 0 if no cpu frequency driver is selected) to program timings.

Signed-off-by: Dmitry Eremin-Solenikov dbarysh...@gmail.com
---
 drivers/pcmcia/sa1100_generic.c |  1 +
 drivers/pcmcia/sa11xx_base.c| 14 --
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index ff8a027..d2ab060 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -93,6 +93,7 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device 
*dev)
for (i = 0; i  sinfo-nskt; i++)
soc_pcmcia_remove_one(sinfo-skt[i]);
 
+   clk_put(sinfo-clk);
kfree(sinfo);
return 0;
 }
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 6eecd7c..aef0e69 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -38,6 +38,7 @@
 #include linux/spinlock.h
 #include linux/io.h
 #include linux/slab.h
+#include linux/clk.h
 
 #include mach/hardware.h
 #include asm/irq.h
@@ -138,14 +139,15 @@ sa1100_pcmcia_frequency_change(struct soc_pcmcia_socket 
*skt,
 static int
 sa1100_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
 {
-   return sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
+   unsigned long clk = clk_get_rate(skt-clk);
+   return sa1100_pcmcia_set_mecr(skt, clk / 1000);
 }
 
 static int
 sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
 {
struct soc_pcmcia_timing timing;
-   unsigned int clock = cpufreq_get(0);
+   unsigned int clock = clk_get_rate(skt-clk);
unsigned long mecr = MECR;
char *p = buf;
 
@@ -221,6 +223,11 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct 
pcmcia_low_level *ops,
struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
int i, ret = 0;
+   struct clk *clk;
+
+   clk = clk_get(dev, NULL);
+   if (IS_ERR(clk))
+   return -ENODEV;
 
sa11xx_drv_pcmcia_ops(ops);
 
@@ -229,12 +236,14 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct 
pcmcia_low_level *ops,
return -ENOMEM;
 
sinfo-nskt = nr;
+   sinfo-clk = clk;
 
/* Initialize processor specific parameters */
for (i = 0; i  nr; i++) {
skt = sinfo-skt[i];
 
skt-nr = first + i;
+   skt-clk = clk;
soc_pcmcia_init_one(skt, ops, dev);
 
ret = sa11xx_drv_pcmcia_add_one(skt);
@@ -245,6 +254,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct 
pcmcia_low_level *ops,
if (ret) {
while (--i = 0)
soc_pcmcia_remove_one(sinfo-skt[i]);
+   clk_put(clk);
kfree(sinfo);
} else {
dev_set_drvdata(dev, sinfo);
-- 
1.8.4.2


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


[PATCH 5/5] pcmcia: sa1111: make use of device clock

2013-11-11 Thread Dmitry Eremin-Solenikov
Use per-device clock (instead of calling cpufreq_get(0), which can
return 0 if no cpu frequency driver is selected) to program timings.

Signed-off-by: Dmitry Eremin-Solenikov dbarysh...@gmail.com
---
 drivers/pcmcia/sa_generic.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/pcmcia/sa_generic.c b/drivers/pcmcia/sa_generic.c
index 65b02c3..c5988be 100644
--- a/drivers/pcmcia/sa_generic.c
+++ b/drivers/pcmcia/sa_generic.c
@@ -145,6 +145,9 @@ int sa_pcmcia_add(struct sa_dev *dev, struct 
pcmcia_low_level *ops,
return -ENOMEM;
 
s-soc.nr = ops-first + i;
+   s-soc.clk = clk_get(dev-dev, NULL);
+   if (IS_ERR(s-soc.clk))
+   return -ENODEV;
soc_pcmcia_init_one(s-soc, ops, dev-dev);
s-dev = dev;
if (s-soc.nr) {
@@ -220,6 +223,7 @@ static int pcmcia_remove(struct sa_dev *dev)
for (; s; s = next) {
next = s-next;
soc_pcmcia_remove_one(s-soc);
+   clk_put(s-soc.clk);
kfree(s);
}
 
-- 
1.8.4.2


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


[PATCH 4/5] arm: sa1100: add a clock alias for sa1111 pcmcia device

2013-11-11 Thread Dmitry Eremin-Solenikov
Signed-off-by: Dmitry Eremin-Solenikov dbarysh...@gmail.com
---
 arch/arm/mach-sa1100/clock.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index abf1dc1..cd4762d 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -124,6 +124,7 @@ 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(1600, NULL, clk_cpu), /* sa pcmcia */
 };
 
 static int __init sa11xx_clk_init(void)
-- 
1.8.4.2


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


[PATCH 1/5] arm: sa1100: add cpu clock

2013-11-11 Thread Dmitry Eremin-Solenikov
Both SA1100 framebuffer and PCMCIA drivers require knowledge of cpu
frequency to correctly program timings.  Currently they receive timing
information by calling cpufreq_get(0).  However if cpu frequency driver
is not enabled (e.g. due to unsupported DRAM chip/board on sa1110)
cpufreq_get(0) returns 0, causing incorrect timings to be programmed.

Add cpu clock returning cpu frequency, to be used by sa11x0 fb and
pcmcia drivers.

Signed-off-by: Dmitry Eremin-Solenikov dbarysh...@gmail.com
---
 arch/arm/mach-sa1100/clock.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 172ebd0..abf1dc1 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -15,10 +15,12 @@
 #include linux/clkdev.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 {
@@ -51,6 +53,19 @@ static void clk_gpio27_disable(struct clk *clk)
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;
@@ -80,16 +95,35 @@ void clk_disable(struct clk *clk)
 }
 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);
+   else
+   return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
 const struct clkops 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 DEFINE_CLK(gpio27, clk_gpio27_ops);
 
+static DEFINE_CLK(cpu, clk_cpu_ops);
+
 static struct clk_lookup sa11xx_clkregs[] = {
CLKDEV_INIT(sa.0, NULL, clk_gpio27),
CLKDEV_INIT(sa1100-rtc, NULL, NULL),
+   CLKDEV_INIT(sa11x0-fb, NULL, clk_cpu),
+   CLKDEV_INIT(sa11x0-pcmcia, NULL, clk_cpu),
 };
 
 static int __init sa11xx_clk_init(void)
-- 
1.8.4.2


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