Some Integrator patches that matured for v3.14:

- Use PATCH_PHYS_TO_VIRT and AUTO_ZRELADDR.
 
 - Support cascaded interrupts on the SIC.
 
 - Complete clock implementation for the IM-PD1.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJSxyvwAAoJEEEQszewGV1zObQQAI7bN0/vmtZkoBbIeoXTAolZ
 KTEqf+Gdtlny4AvW4PUeutDRr4zvFHKYo5uBbr9bQFl4S89ke29nLXhyrvJbAWJs
 tujyX0mWb38fosEGeVo3YGbDIw9+O3CMRM+zaHyt/yzcHANnPeecpt3dFNheaTKs
 W7Axw5YFszpfxs5xQYMrrudbXd6TbsZWSn1pJpNlPvoo8b0HV72ARZNDAM2NO2rY
 rOSUzl8MKb0tAW7Nj4D8vLqAtYkjA7lX6sdXQBbqpUyTINR5/35ifW/K74q1miMS
 3T5ECbwrW9CHSW2jrTt28knafasAsJKCMdJ9SXu7uzOZogglTuBSw52MIhP2QvHS
 mxOXBHkCazCMum4WndLe1ygSigQZR2SAufmjzESsE82RBF2UmkgqR34aaxag9x/X
 avxUM/3Opgosa12AD8buSP5NfYqMjvqXzwdNs6YbC1UPqRYIgn9FcJ6cFzkVXoKi
 GWgz6Ko6MiR9HVDBqw8uHrIBKuaa3oZ5+jt0x54ZuI3tOxV1wUxR3AcgWQsF2tSN
 nPg8GTvZNiEfo6fWSIx7V2H/txFfAj1Z3JG6tFQTfLtE5G7MssxyNitoxZsIeWuB
 x1+tnsOQRpBlkUb92LS37ndLJoFfknbCgFUAIgMozntfCRQi/6REWAKGDo0fTOmG
 +uN+Q6JMFj62jZ6dgumd
 =cCZc
 -----END PGP SIGNATURE-----

Merge tag 'integrator-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator into next/drivers

From Linus Walleij:
Some Integrator patches that matured for v3.14:

- Use PATCH_PHYS_TO_VIRT and AUTO_ZRELADDR.
- Support cascaded interrupts on the SIC.
- Complete clock implementation for the IM-PD1.

* tag 'integrator-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator:
  clk: versatile: fixup IM-PD1 clock implementation
  clk: versatile: pass a name to ICST clock provider
  ARM: integrator: pass parent IRQ to the SIC
  irqchip: versatile FPGA: support cascaded interrupts from DT
  ARM: integrator: Default enable ARM_PATCH_PHYS_VIRT, AUTO_ZRELADDR

Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2014-01-03 21:55:29 -08:00
commit 3d7e0207ce
9 changed files with 103 additions and 22 deletions

View File

@ -29,3 +29,8 @@ pic: pic@14000000 {
clear-mask = <0xffffffff>;
valid-mask = <0x003fffff>;
};
Optional properties:
- interrupts: if the FPGA IRQ controller is cascaded, i.e. if its IRQ
output is simply connected to the input of another IRQ controller,
then the parent IRQ shall be specified in this property.

View File

@ -313,6 +313,8 @@ config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARCH_HAS_CPUFREQ
select ARM_AMBA
select ARM_PATCH_PHYS_VIRT
select AUTO_ZRELADDR
select COMMON_CLK
select COMMON_CLK_VERSATILE
select GENERIC_CLOCKEVENTS

View File

@ -47,8 +47,11 @@ cic: cic@10000040 {
valid-mask = <0x00000007>;
};
/* The SIC is cascaded off IRQ 26 on the PIC */
sic: sic@ca000000 {
compatible = "arm,versatile-fpga-irq";
interrupt-parent = <&pic>;
interrupts = <26>;
#interrupt-cells = <1>;
interrupt-controller;
reg = <0xca000000 0x100>;

View File

@ -119,6 +119,7 @@ static const struct clk_ops icst_ops = {
struct clk *icst_clk_register(struct device *dev,
const struct clk_icst_desc *desc,
const char *name,
void __iomem *base)
{
struct clk *clk;
@ -130,7 +131,7 @@ struct clk *icst_clk_register(struct device *dev,
pr_err("could not allocate ICST clock!\n");
return ERR_PTR(-ENOMEM);
}
init.name = "icst";
init.name = name;
init.ops = &icst_ops;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;

View File

@ -15,4 +15,5 @@ struct clk_icst_desc {
struct clk *icst_clk_register(struct device *dev,
const struct clk_icst_desc *desc,
const char *name,
void __iomem *base);

View File

@ -1,6 +1,6 @@
/*
* Clock driver for the ARM Integrator/IM-PD1 board
* Copyright (C) 2012 Linus Walleij
* Copyright (C) 2012-2013 Linus Walleij
*
* 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
@ -18,20 +18,28 @@
#include "clk-icst.h"
struct impd1_clk {
struct clk *vcoclk;
char *vco1name;
struct clk *vco1clk;
char *vco2name;
struct clk *vco2clk;
struct clk *mmciclk;
char *uartname;
struct clk *uartclk;
struct clk_lookup *clks[3];
char *spiname;
struct clk *spiclk;
char *scname;
struct clk *scclk;
struct clk_lookup *clks[6];
};
/* One entry for each connected IM-PD1 LM */
static struct impd1_clk impd1_clks[4];
/*
* There are two VCO's on the IM-PD1 but only one is used by the
* kernel, that is why we are only implementing the control of
* IMPD1_OSC1 here.
* There are two VCO's on the IM-PD1
*/
static const struct icst_params impd1_vco_params = {
static const struct icst_params impd1_vco1_params = {
.ref = 24000000, /* 24 MHz */
.vco_max = ICST525_VCO_MAX_3V,
.vco_min = ICST525_VCO_MIN,
@ -44,11 +52,29 @@ static const struct icst_params impd1_vco_params = {
};
static const struct clk_icst_desc impd1_icst1_desc = {
.params = &impd1_vco_params,
.params = &impd1_vco1_params,
.vco_offset = IMPD1_OSC1,
.lock_offset = IMPD1_LOCK,
};
static const struct icst_params impd1_vco2_params = {
.ref = 24000000, /* 24 MHz */
.vco_max = ICST525_VCO_MAX_3V,
.vco_min = ICST525_VCO_MIN,
.vd_min = 12,
.vd_max = 519,
.rd_min = 3,
.rd_max = 120,
.s2div = icst525_s2div,
.idx2s = icst525_idx2s,
};
static const struct clk_icst_desc impd1_icst2_desc = {
.params = &impd1_vco2_params,
.vco_offset = IMPD1_OSC2,
.lock_offset = IMPD1_LOCK,
};
/**
* integrator_impd1_clk_init() - set up the integrator clock tree
* @base: base address of the logic module (LM)
@ -66,16 +92,39 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
}
imc = &impd1_clks[id];
clk = icst_clk_register(NULL, &impd1_icst1_desc, base);
imc->vcoclk = clk;
imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id);
clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, base);
imc->vco1clk = clk;
imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
/* UART reference clock */
clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT,
14745600);
/* VCO2 is also called "CLK2" */
imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id);
clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, base);
imc->vco2clk = clk;
/* MMCI uses CLK2 right off */
imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00700", id);
/* UART reference clock divides CLK2 by a fixed factor 4 */
imc->uartname = kasprintf(GFP_KERNEL, "lm%x-uartclk", id);
clk = clk_register_fixed_factor(NULL, imc->uartname, imc->vco2name,
CLK_IGNORE_UNUSED, 1, 4);
imc->uartclk = clk;
imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id);
imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id);
imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00100", id);
imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00200", id);
/* SPI PL022 clock divides CLK2 by a fixed factor 64 */
imc->spiname = kasprintf(GFP_KERNEL, "lm%x-spiclk", id);
clk = clk_register_fixed_factor(NULL, imc->spiname, imc->vco2name,
CLK_IGNORE_UNUSED, 1, 64);
imc->clks[4] = clkdev_alloc(clk, NULL, "lm%x:00300", id);
/* Smart Card clock divides CLK2 by a fixed factor 4 */
imc->scname = kasprintf(GFP_KERNEL, "lm%x-scclk", id);
clk = clk_register_fixed_factor(NULL, imc->scname, imc->vco2name,
CLK_IGNORE_UNUSED, 1, 4);
imc->scclk = clk;
imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00600", id);
for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
clkdev_add(imc->clks[i]);
@ -92,6 +141,13 @@ void integrator_impd1_clk_exit(unsigned int id)
for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
clkdev_drop(imc->clks[i]);
clk_unregister(imc->spiclk);
clk_unregister(imc->uartclk);
clk_unregister(imc->vcoclk);
clk_unregister(imc->vco2clk);
clk_unregister(imc->vco1clk);
kfree(imc->scname);
kfree(imc->spiname);
kfree(imc->uartname);
kfree(imc->vco2name);
kfree(imc->vco1name);
}

View File

@ -78,7 +78,7 @@ void __init integrator_clk_init(bool is_cp)
clk_register_clkdev(clk, NULL, "sp804");
/* ICST VCO clock used on the Integrator/CP CLCD */
clk = icst_clk_register(NULL, &cp_icst_desc,
clk = icst_clk_register(NULL, &cp_icst_desc, "icst",
__io_address(INTEGRATOR_HDR_BASE));
clk_register_clkdev(clk, NULL, "clcd");
}

View File

@ -84,9 +84,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
/* ICST VCO clock */
if (is_pb1176)
clk = icst_clk_register(NULL, &realview_osc0_desc, sysbase);
clk = icst_clk_register(NULL, &realview_osc0_desc,
"osc0", sysbase);
else
clk = icst_clk_register(NULL, &realview_osc4_desc, sysbase);
clk = icst_clk_register(NULL, &realview_osc4_desc,
"osc4", sysbase);
clk_register_clkdev(clk, NULL, "dev:clcd");
clk_register_clkdev(clk, NULL, "issp:clcd");

View File

@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <asm/exception.h>
#include <asm/mach/irq.h>
@ -167,8 +168,12 @@ void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
f->used_irqs++;
}
pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs",
fpga_irq_id, name, base, f->used_irqs);
if (parent_irq != -1)
pr_cont(", parent IRQ: %d\n", parent_irq);
else
pr_cont("\n");
fpga_irq_id++;
}
@ -180,6 +185,7 @@ int __init fpga_irq_of_init(struct device_node *node,
void __iomem *base;
u32 clear_mask;
u32 valid_mask;
int parent_irq;
if (WARN_ON(!node))
return -ENODEV;
@ -193,7 +199,12 @@ int __init fpga_irq_of_init(struct device_node *node,
if (of_property_read_u32(node, "valid-mask", &valid_mask))
valid_mask = 0;
fpga_irq_init(base, node->name, 0, -1, valid_mask, node);
/* Some chips are cascaded from a parent IRQ */
parent_irq = irq_of_parse_and_map(node, 0);
if (!parent_irq)
parent_irq = -1;
fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node);
writel(clear_mask, base + IRQ_ENABLE_CLEAR);
writel(clear_mask, base + FIQ_ENABLE_CLEAR);