From: kernel@martin.sperl.org (kernel at martin.sperl.org)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 06/20] clk: bcm2835: remove use of BCM2835_CLOCK_COUNT in driver
Date: Sun, 28 Feb 2016 15:36:57 +0000 [thread overview]
Message-ID: <1456673831-2408-7-git-send-email-kernel@martin.sperl.org> (raw)
In-Reply-To: <1456673831-2408-1-git-send-email-kernel@martin.sperl.org>
From: Martin Sperl <kernel@martin.sperl.org>
As the use of BCM2835_CLOCK_COUNT in
include/dt-bindings/clock/bcm2835.h is frowned upon as
it needs to get modified every time a new clock gets introduced
this patch changes the clk-bcm2835 driver to use a different
scheme for registration of clocks and pll, so that there
is no more need for BCM2835_CLOCK_COUNT to be defined.
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
---
drivers/clk/bcm/clk-bcm2835.c | 167 ++++++++++++++++++++---------------
include/dt-bindings/clock/bcm2835.h | 2 -
2 files changed, 94 insertions(+), 75 deletions(-)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 14ff81e..59219f9 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c
@@ -299,7 +299,7 @@ struct bcm2835_cprman {
const char *osc_name;
struct clk_onecell_data onecell;
- struct clk *clks[BCM2835_CLOCK_COUNT];
+ struct clk *clks[];
};
static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
@@ -811,6 +811,25 @@ static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
.frac_bits = 12,
};
+struct bcm2835_gate_data {
+ const char *name;
+ const char *parent;
+
+ u32 ctl_reg;
+};
+
+/*
+ * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
+ * you have the debug bit set in the power manager, which we
+ * don't bother exposing) are individual gates off of the
+ * non-stop vpu clock.
+ */
+static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = {
+ .name = "peri_image",
+ .parent = "vpu",
+ .ctl_reg = CM_PERIICTL,
+};
+
struct bcm2835_pll {
struct clk_hw hw;
struct bcm2835_cprman *cprman;
@@ -1506,14 +1525,81 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
return clk;
}
+static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman,
+ const struct bcm2835_gate_data *data)
+{
+ return clk_register_gate(cprman->dev, data->name, data->parent,
+ CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
+ cprman->regs + data->ctl_reg,
+ CM_GATE_BIT, 0, &cprman->regs_lock);
+}
+
+typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
+ const void *data);
+struct bcm2835_clk_desc {
+ bcm2835_clk_register clk_register;
+ const void *data;
+};
+
+#define _REGISTER(f, d) { .clk_register = (bcm2835_clk_register)f, \
+ .data = d }
+#define REGISTER_PLL(d) _REGISTER(&bcm2835_register_pll, d)
+#define REGISTER_PLL_DIV(d) _REGISTER(&bcm2835_register_pll_divider, d)
+#define REGISTER_CLK(d) _REGISTER(&bcm2835_register_clock, d)
+#define REGISTER_GATE(d) _REGISTER(&bcm2835_register_gate, d)
+
+static const struct bcm2835_clk_desc clk_desc_array[] = {
+ /* register PLL */
+ [BCM2835_PLLA] = REGISTER_PLL(&bcm2835_plla_data),
+ [BCM2835_PLLB] = REGISTER_PLL(&bcm2835_pllb_data),
+ [BCM2835_PLLC] = REGISTER_PLL(&bcm2835_pllc_data),
+ [BCM2835_PLLD] = REGISTER_PLL(&bcm2835_plld_data),
+ [BCM2835_PLLH] = REGISTER_PLL(&bcm2835_pllh_data),
+ /* the PLL dividers */
+ [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV(&bcm2835_plla_core_data),
+ [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(&bcm2835_plla_per_data),
+ [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV(&bcm2835_pllc_core0_data),
+ [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(&bcm2835_pllc_core1_data),
+ [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(&bcm2835_pllc_core2_data),
+ [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(&bcm2835_pllc_per_data),
+ [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV(&bcm2835_plld_core_data),
+ [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(&bcm2835_plld_per_data),
+ [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV(&bcm2835_pllh_rcal_data),
+ [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(&bcm2835_pllh_aux_data),
+ [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(&bcm2835_pllh_pix_data),
+ /* the clocks */
+ [BCM2835_CLOCK_TIMER] = REGISTER_CLK(&bcm2835_clock_timer_data),
+ [BCM2835_CLOCK_OTP] = REGISTER_CLK(&bcm2835_clock_otp_data),
+ [BCM2835_CLOCK_TSENS] = REGISTER_CLK(&bcm2835_clock_tsens_data),
+ [BCM2835_CLOCK_VPU] = REGISTER_CLK(&bcm2835_clock_vpu_data),
+ [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
+ [BCM2835_CLOCK_ISP] = REGISTER_CLK(&bcm2835_clock_isp_data),
+ [BCM2835_CLOCK_H264] = REGISTER_CLK(&bcm2835_clock_h264_data),
+ [BCM2835_CLOCK_V3D] = REGISTER_CLK(&bcm2835_clock_v3d_data),
+ [BCM2835_CLOCK_SDRAM] = REGISTER_CLK(&bcm2835_clock_sdram_data),
+ [BCM2835_CLOCK_UART] = REGISTER_CLK(&bcm2835_clock_uart_data),
+ [BCM2835_CLOCK_VEC] = REGISTER_CLK(&bcm2835_clock_vec_data),
+ [BCM2835_CLOCK_HSM] = REGISTER_CLK(&bcm2835_clock_hsm_data),
+ [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data),
+ [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data),
+ /* the gates */
+ [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
+ &bcm2835_clock_peri_image_data),
+};
+
static int bcm2835_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct clk **clks;
struct bcm2835_cprman *cprman;
struct resource *res;
+ const struct bcm2835_clk_desc *desc;
+ const size_t asize = ARRAY_SIZE(clk_desc_array);
+ size_t i;
- cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL);
+ cprman = devm_kzalloc(dev,
+ sizeof(*cprman) + asize * sizeof(*clks),
+ GFP_KERNEL);
if (!cprman)
return -ENOMEM;
@@ -1530,80 +1616,15 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, cprman);
- cprman->onecell.clk_num = BCM2835_CLOCK_COUNT;
+ cprman->onecell.clk_num = asize;
cprman->onecell.clks = cprman->clks;
clks = cprman->clks;
- clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data);
- clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data);
- clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data);
- clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data);
- clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data);
-
- clks[BCM2835_PLLA_CORE] =
- bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data);
- clks[BCM2835_PLLA_PER] =
- bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data);
- clks[BCM2835_PLLC_CORE0] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data);
- clks[BCM2835_PLLC_CORE1] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data);
- clks[BCM2835_PLLC_CORE2] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data);
- clks[BCM2835_PLLC_PER] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data);
- clks[BCM2835_PLLD_CORE] =
- bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data);
- clks[BCM2835_PLLD_PER] =
- bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data);
- clks[BCM2835_PLLH_RCAL] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data);
- clks[BCM2835_PLLH_AUX] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data);
- clks[BCM2835_PLLH_PIX] =
- bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data);
-
- clks[BCM2835_CLOCK_TIMER] =
- bcm2835_register_clock(cprman, &bcm2835_clock_timer_data);
- clks[BCM2835_CLOCK_OTP] =
- bcm2835_register_clock(cprman, &bcm2835_clock_otp_data);
- clks[BCM2835_CLOCK_TSENS] =
- bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data);
- clks[BCM2835_CLOCK_VPU] =
- bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data);
- clks[BCM2835_CLOCK_V3D] =
- bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
- clks[BCM2835_CLOCK_ISP] =
- bcm2835_register_clock(cprman, &bcm2835_clock_isp_data);
- clks[BCM2835_CLOCK_H264] =
- bcm2835_register_clock(cprman, &bcm2835_clock_h264_data);
- clks[BCM2835_CLOCK_V3D] =
- bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data);
- clks[BCM2835_CLOCK_SDRAM] =
- bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data);
- clks[BCM2835_CLOCK_UART] =
- bcm2835_register_clock(cprman, &bcm2835_clock_uart_data);
- clks[BCM2835_CLOCK_VEC] =
- bcm2835_register_clock(cprman, &bcm2835_clock_vec_data);
- clks[BCM2835_CLOCK_HSM] =
- bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data);
- clks[BCM2835_CLOCK_EMMC] =
- bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data);
-
- /*
- * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if
- * you have the debug bit set in the power manager, which we
- * don't bother exposing) are individual gates off of the
- * non-stop vpu clock.
- */
- clks[BCM2835_CLOCK_PERI_IMAGE] =
- clk_register_gate(dev, "peri_image", "vpu",
- CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE,
- cprman->regs + CM_PERIICTL, CM_GATE_BIT,
- 0, &cprman->regs_lock);
-
- clks[BCM2835_CLOCK_PWM] =
- bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data);
+ for (i = 0; i < asize; i++) {
+ desc = &clk_desc_array[i];
+ if (desc->clk_register && desc->data)
+ clks[i] = desc->clk_register(cprman, desc->data);
+ }
return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
&cprman->onecell);
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h
index 61f1d20..87235ac 100644
--- a/include/dt-bindings/clock/bcm2835.h
+++ b/include/dt-bindings/clock/bcm2835.h
@@ -44,5 +44,3 @@
#define BCM2835_CLOCK_EMMC 28
#define BCM2835_CLOCK_PERI_IMAGE 29
#define BCM2835_CLOCK_PWM 30
-
-#define BCM2835_CLOCK_COUNT 31
--
1.7.10.4
next prev parent reply other threads:[~2016-02-28 15:36 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-28 15:36 [PATCH v5 00/20] add additional clocks and frac/mash support kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 01/20] clk: bcm2835: pll_off should only set CM_PLL_ANARST kernel at martin.sperl.org
2016-02-28 17:58 ` Stefan Wahren
2016-02-28 15:36 ` [PATCH v5 02/20] clk: bcm2835: clean up coding style issues kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 03/20] clk: bcm2835: add locking to pll*_on/off methods kernel at martin.sperl.org
2016-02-28 18:04 ` Stefan Wahren
2016-02-28 15:36 ` [PATCH v5 04/20] clk: bcm2835: remove uart0/1_pclk fixed clocks kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 05/20] clk: bcm2835: enable clocks that have been enabled by firmware kernel at martin.sperl.org
2016-02-28 15:36 ` kernel at martin.sperl.org [this message]
2016-02-28 15:36 ` [PATCH v5 07/20] clk: bcm2835: reorganize bcm2835_clock_array assignment kernel at martin.sperl.org
2016-02-28 15:36 ` [PATCH v5 08/20] clk: bcm2835: add fractional support kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 09/20] clk: bcm2835: enable management of PCM clock kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 10/20] clk: bcm2835: implement correct clamping for mash clocks kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 11/20] clk: bcm2835: divider value has to be 1 or more kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 12/20] clk: bcm2835: expose raw clock-registers via debugfs kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 13/20] clk: bcm2835: expose current divider, parent and mash " kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 14/20] clk: bcm2835: added missing PLL clock divider kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 15/20] clk: bcm2835: add additional clocks kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 16/20] clk: bcm2835: add the camera related clocks cam0, cam1 and ccp2 kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 17/20] clk: bcm2835: add the dsi clocks kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 18/20] clk: bcm2835: add arm clock kernel at martin.sperl.org
2016-02-28 15:37 ` [PATCH v5 19/20] clk: bcm2835: add gates that require PM_DEBUG to be set kernel at martin.sperl.org
2016-02-28 17:48 ` [PATCH v5 00/20] add additional clocks and frac/mash support Stefan Wahren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1456673831-2408-7-git-send-email-kernel@martin.sperl.org \
--to=kernel@martin.sperl.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).