From: Dragan Cvetic <dragan.cvetic@xilinx.com> To: <arnd@arndb.de>, <gregkh@linuxfoundation.org>, <michal.simek@xilinx.com>, <linux-arm-kernel@lists.infradead.org> Cc: <linux-kernel@vger.kernel.org>, Dragan Cvetic <dragan.cvetic@xilinx.com>, Derek Kiernan <derek.kiernan@xilinx.com> Subject: [PATCH V2 03/12] misc: xilinx_sdfec: Add CCF support Date: Tue, 9 Apr 2019 11:06:45 +0100 [thread overview] Message-ID: <1554804414-206099-4-git-send-email-dragan.cvetic@xilinx.com> (raw) In-Reply-To: <1554804414-206099-1-git-send-email-dragan.cvetic@xilinx.com> Add the support for Linux Clock Control Framework (CCF). Registers and enables clocks with the Clock Control Framework (CCF), to prevent shared clocks from been disabled. Tested-by: Dragan Cvetic <dragan.cvetic@xilinx.com> Signed-off-by: Derek Kiernan <derek.kiernan@xilinx.com> Signed-off-by: Dragan Cvetic <dragan.cvetic@xilinx.com> --- drivers/misc/xilinx_sdfec.c | 154 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c index 278754b..a52a5c6 100644 --- a/drivers/misc/xilinx_sdfec.c +++ b/drivers/misc/xilinx_sdfec.c @@ -37,6 +37,28 @@ static atomic_t xsdfec_ndevs = ATOMIC_INIT(0); static dev_t xsdfec_devt; /** + * struct xsdfec_clks - For managing SD-FEC clocks + * @core_clk: Main processing clock for core + * @axi_clk: AXI4-Lite memory-mapped clock + * @din_words_clk: DIN Words AXI4-Stream Slave clock + * @din_clk: DIN AXI4-Stream Slave clock + * @dout_clk: DOUT Words AXI4-Stream Slave clock + * @dout_words_clk: DOUT AXI4-Stream Slave clock + * @ctrl_clk: Control AXI4-Stream Slave clock + * @status_clk: Status AXI4-Stream Slave clock + */ +struct xsdfec_clks { + struct clk *core_clk; + struct clk *axi_clk; + struct clk *din_words_clk; + struct clk *din_clk; + struct clk *dout_clk; + struct clk *dout_words_clk; + struct clk *ctrl_clk; + struct clk *status_clk; +}; + +/** * struct xsdfec_dev - Driver data for SDFEC * @regs: device physical base address * @dev: pointer to device struct @@ -44,6 +66,7 @@ static dev_t xsdfec_devt; * @open_count: Count of char device being opened * @xsdfec_cdev: Character device handle * @irq_lock: Driver spinlock + * @clks: Clocks managed by the SDFEC driver * * This structure contains necessary state for SDFEC driver to operate */ @@ -55,12 +78,136 @@ struct xsdfec_dev { struct cdev xsdfec_cdev; /* Spinlock to protect state_updated and stats_updated */ spinlock_t irq_lock; + struct xsdfec_clks clks; }; static const struct file_operations xsdfec_fops = { .owner = THIS_MODULE, }; +static int xsdfec_clk_init(struct platform_device *pdev, + struct xsdfec_clks *clks) +{ + int err; + + clks->core_clk = devm_clk_get(&pdev->dev, "core_clk"); + if (IS_ERR(clks->core_clk)) { + dev_err(&pdev->dev, "failed to get core_clk"); + return PTR_ERR(clks->core_clk); + } + + clks->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clks->axi_clk)) { + dev_err(&pdev->dev, "failed to get axi_clk"); + return PTR_ERR(clks->axi_clk); + } + + clks->din_words_clk = devm_clk_get(&pdev->dev, "s_axis_din_words_aclk"); + if (IS_ERR(clks->din_words_clk)) + clks->din_words_clk = NULL; + + clks->din_clk = devm_clk_get(&pdev->dev, "s_axis_din_aclk"); + if (IS_ERR(clks->din_clk)) + clks->din_clk = NULL; + + clks->dout_clk = devm_clk_get(&pdev->dev, "m_axis_dout_aclk"); + if (IS_ERR(clks->dout_clk)) + clks->dout_clk = NULL; + + clks->dout_words_clk = + devm_clk_get(&pdev->dev, "s_axis_dout_words_aclk"); + if (IS_ERR(clks->dout_words_clk)) + clks->dout_words_clk = NULL; + + clks->ctrl_clk = devm_clk_get(&pdev->dev, "s_axis_ctrl_aclk"); + if (IS_ERR(clks->ctrl_clk)) + clks->ctrl_clk = NULL; + + clks->status_clk = devm_clk_get(&pdev->dev, "m_axis_status_aclk"); + if (IS_ERR(clks->status_clk)) + clks->status_clk = NULL; + + err = clk_prepare_enable(clks->core_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable core_clk (%d)", err); + return err; + } + + err = clk_prepare_enable(clks->axi_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable axi_clk (%d)", err); + goto err_disable_core_clk; + } + + err = clk_prepare_enable(clks->din_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable din_clk (%d)", err); + goto err_disable_axi_clk; + } + + err = clk_prepare_enable(clks->din_words_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable din_words_clk (%d)", err); + goto err_disable_din_clk; + } + + err = clk_prepare_enable(clks->dout_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable dout_clk (%d)", err); + goto err_disable_din_words_clk; + } + + err = clk_prepare_enable(clks->dout_words_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable dout_words_clk (%d)", + err); + goto err_disable_dout_clk; + } + + err = clk_prepare_enable(clks->ctrl_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable ctrl_clk (%d)", err); + goto err_disable_dout_words_clk; + } + + err = clk_prepare_enable(clks->status_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable status_clk (%d)\n", err); + goto err_disable_ctrl_clk; + } + + return err; + +err_disable_ctrl_clk: + clk_disable_unprepare(clks->ctrl_clk); +err_disable_dout_words_clk: + clk_disable_unprepare(clks->dout_words_clk); +err_disable_dout_clk: + clk_disable_unprepare(clks->dout_clk); +err_disable_din_words_clk: + clk_disable_unprepare(clks->din_words_clk); +err_disable_din_clk: + clk_disable_unprepare(clks->din_clk); +err_disable_axi_clk: + clk_disable_unprepare(clks->axi_clk); +err_disable_core_clk: + clk_disable_unprepare(clks->core_clk); + + return err; +} + +static void xsdfec_disable_all_clks(struct xsdfec_clks *clks) +{ + clk_disable_unprepare(clks->status_clk); + clk_disable_unprepare(clks->ctrl_clk); + clk_disable_unprepare(clks->dout_words_clk); + clk_disable_unprepare(clks->dout_clk); + clk_disable_unprepare(clks->din_words_clk); + clk_disable_unprepare(clks->din_clk); + clk_disable_unprepare(clks->core_clk); + clk_disable_unprepare(clks->axi_clk); +} + static int xsdfec_probe(struct platform_device *pdev) { struct xsdfec_dev *xsdfec; @@ -77,6 +224,10 @@ static int xsdfec_probe(struct platform_device *pdev) xsdfec->config.fec_id = atomic_read(&xsdfec_ndevs); spin_lock_init(&xsdfec->irq_lock); + err = xsdfec_clk_init(pdev, &xsdfec->clks); + if (err) + return err; + dev = xsdfec->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xsdfec->regs = devm_ioremap_resource(dev, res); @@ -124,6 +275,7 @@ static int xsdfec_probe(struct platform_device *pdev) err_xsdfec_cdev: cdev_del(&xsdfec->xsdfec_cdev); err_xsdfec_dev: + xsdfec_disable_all_clks(&xsdfec->clks); return err; } @@ -141,6 +293,8 @@ static int xsdfec_remove(struct platform_device *pdev) return -EIO; } + xsdfec_disable_all_clks(&xsdfec->clks); + device_destroy(xsdfec_class, MKDEV(MAJOR(xsdfec_devt), xsdfec->config.fec_id)); cdev_del(&xsdfec->xsdfec_cdev); -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Dragan Cvetic <dragan.cvetic@xilinx.com> To: <arnd@arndb.de>, <gregkh@linuxfoundation.org>, <michal.simek@xilinx.com>, <linux-arm-kernel@lists.infradead.org> Cc: Dragan Cvetic <dragan.cvetic@xilinx.com>, Derek Kiernan <derek.kiernan@xilinx.com>, linux-kernel@vger.kernel.org Subject: [PATCH V2 03/12] misc: xilinx_sdfec: Add CCF support Date: Tue, 9 Apr 2019 11:06:45 +0100 [thread overview] Message-ID: <1554804414-206099-4-git-send-email-dragan.cvetic@xilinx.com> (raw) In-Reply-To: <1554804414-206099-1-git-send-email-dragan.cvetic@xilinx.com> Add the support for Linux Clock Control Framework (CCF). Registers and enables clocks with the Clock Control Framework (CCF), to prevent shared clocks from been disabled. Tested-by: Dragan Cvetic <dragan.cvetic@xilinx.com> Signed-off-by: Derek Kiernan <derek.kiernan@xilinx.com> Signed-off-by: Dragan Cvetic <dragan.cvetic@xilinx.com> --- drivers/misc/xilinx_sdfec.c | 154 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c index 278754b..a52a5c6 100644 --- a/drivers/misc/xilinx_sdfec.c +++ b/drivers/misc/xilinx_sdfec.c @@ -37,6 +37,28 @@ static atomic_t xsdfec_ndevs = ATOMIC_INIT(0); static dev_t xsdfec_devt; /** + * struct xsdfec_clks - For managing SD-FEC clocks + * @core_clk: Main processing clock for core + * @axi_clk: AXI4-Lite memory-mapped clock + * @din_words_clk: DIN Words AXI4-Stream Slave clock + * @din_clk: DIN AXI4-Stream Slave clock + * @dout_clk: DOUT Words AXI4-Stream Slave clock + * @dout_words_clk: DOUT AXI4-Stream Slave clock + * @ctrl_clk: Control AXI4-Stream Slave clock + * @status_clk: Status AXI4-Stream Slave clock + */ +struct xsdfec_clks { + struct clk *core_clk; + struct clk *axi_clk; + struct clk *din_words_clk; + struct clk *din_clk; + struct clk *dout_clk; + struct clk *dout_words_clk; + struct clk *ctrl_clk; + struct clk *status_clk; +}; + +/** * struct xsdfec_dev - Driver data for SDFEC * @regs: device physical base address * @dev: pointer to device struct @@ -44,6 +66,7 @@ static dev_t xsdfec_devt; * @open_count: Count of char device being opened * @xsdfec_cdev: Character device handle * @irq_lock: Driver spinlock + * @clks: Clocks managed by the SDFEC driver * * This structure contains necessary state for SDFEC driver to operate */ @@ -55,12 +78,136 @@ struct xsdfec_dev { struct cdev xsdfec_cdev; /* Spinlock to protect state_updated and stats_updated */ spinlock_t irq_lock; + struct xsdfec_clks clks; }; static const struct file_operations xsdfec_fops = { .owner = THIS_MODULE, }; +static int xsdfec_clk_init(struct platform_device *pdev, + struct xsdfec_clks *clks) +{ + int err; + + clks->core_clk = devm_clk_get(&pdev->dev, "core_clk"); + if (IS_ERR(clks->core_clk)) { + dev_err(&pdev->dev, "failed to get core_clk"); + return PTR_ERR(clks->core_clk); + } + + clks->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clks->axi_clk)) { + dev_err(&pdev->dev, "failed to get axi_clk"); + return PTR_ERR(clks->axi_clk); + } + + clks->din_words_clk = devm_clk_get(&pdev->dev, "s_axis_din_words_aclk"); + if (IS_ERR(clks->din_words_clk)) + clks->din_words_clk = NULL; + + clks->din_clk = devm_clk_get(&pdev->dev, "s_axis_din_aclk"); + if (IS_ERR(clks->din_clk)) + clks->din_clk = NULL; + + clks->dout_clk = devm_clk_get(&pdev->dev, "m_axis_dout_aclk"); + if (IS_ERR(clks->dout_clk)) + clks->dout_clk = NULL; + + clks->dout_words_clk = + devm_clk_get(&pdev->dev, "s_axis_dout_words_aclk"); + if (IS_ERR(clks->dout_words_clk)) + clks->dout_words_clk = NULL; + + clks->ctrl_clk = devm_clk_get(&pdev->dev, "s_axis_ctrl_aclk"); + if (IS_ERR(clks->ctrl_clk)) + clks->ctrl_clk = NULL; + + clks->status_clk = devm_clk_get(&pdev->dev, "m_axis_status_aclk"); + if (IS_ERR(clks->status_clk)) + clks->status_clk = NULL; + + err = clk_prepare_enable(clks->core_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable core_clk (%d)", err); + return err; + } + + err = clk_prepare_enable(clks->axi_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable axi_clk (%d)", err); + goto err_disable_core_clk; + } + + err = clk_prepare_enable(clks->din_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable din_clk (%d)", err); + goto err_disable_axi_clk; + } + + err = clk_prepare_enable(clks->din_words_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable din_words_clk (%d)", err); + goto err_disable_din_clk; + } + + err = clk_prepare_enable(clks->dout_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable dout_clk (%d)", err); + goto err_disable_din_words_clk; + } + + err = clk_prepare_enable(clks->dout_words_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable dout_words_clk (%d)", + err); + goto err_disable_dout_clk; + } + + err = clk_prepare_enable(clks->ctrl_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable ctrl_clk (%d)", err); + goto err_disable_dout_words_clk; + } + + err = clk_prepare_enable(clks->status_clk); + if (err) { + dev_err(&pdev->dev, "failed to enable status_clk (%d)\n", err); + goto err_disable_ctrl_clk; + } + + return err; + +err_disable_ctrl_clk: + clk_disable_unprepare(clks->ctrl_clk); +err_disable_dout_words_clk: + clk_disable_unprepare(clks->dout_words_clk); +err_disable_dout_clk: + clk_disable_unprepare(clks->dout_clk); +err_disable_din_words_clk: + clk_disable_unprepare(clks->din_words_clk); +err_disable_din_clk: + clk_disable_unprepare(clks->din_clk); +err_disable_axi_clk: + clk_disable_unprepare(clks->axi_clk); +err_disable_core_clk: + clk_disable_unprepare(clks->core_clk); + + return err; +} + +static void xsdfec_disable_all_clks(struct xsdfec_clks *clks) +{ + clk_disable_unprepare(clks->status_clk); + clk_disable_unprepare(clks->ctrl_clk); + clk_disable_unprepare(clks->dout_words_clk); + clk_disable_unprepare(clks->dout_clk); + clk_disable_unprepare(clks->din_words_clk); + clk_disable_unprepare(clks->din_clk); + clk_disable_unprepare(clks->core_clk); + clk_disable_unprepare(clks->axi_clk); +} + static int xsdfec_probe(struct platform_device *pdev) { struct xsdfec_dev *xsdfec; @@ -77,6 +224,10 @@ static int xsdfec_probe(struct platform_device *pdev) xsdfec->config.fec_id = atomic_read(&xsdfec_ndevs); spin_lock_init(&xsdfec->irq_lock); + err = xsdfec_clk_init(pdev, &xsdfec->clks); + if (err) + return err; + dev = xsdfec->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xsdfec->regs = devm_ioremap_resource(dev, res); @@ -124,6 +275,7 @@ static int xsdfec_probe(struct platform_device *pdev) err_xsdfec_cdev: cdev_del(&xsdfec->xsdfec_cdev); err_xsdfec_dev: + xsdfec_disable_all_clks(&xsdfec->clks); return err; } @@ -141,6 +293,8 @@ static int xsdfec_remove(struct platform_device *pdev) return -EIO; } + xsdfec_disable_all_clks(&xsdfec->clks); + device_destroy(xsdfec_class, MKDEV(MAJOR(xsdfec_devt), xsdfec->config.fec_id)); cdev_del(&xsdfec->xsdfec_cdev); -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-04-09 10:08 UTC|newest] Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-04-09 10:06 [PATCH V2 00/12] misc: xilinx sd-fec drive Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 01/12] dt-bindings: xilinx-sdfec: Add SDFEC binding Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-25 20:24 ` Greg KH 2019-04-25 20:24 ` Greg KH 2019-04-26 12:27 ` Dragan Cvetic 2019-04-26 12:27 ` Dragan Cvetic 2019-04-26 12:27 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 02/12] misc: xilinx-sdfec: add core driver Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-25 20:25 ` Greg KH 2019-04-25 20:25 ` Greg KH 2019-04-26 12:24 ` Dragan Cvetic 2019-04-26 12:24 ` Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic [this message] 2019-04-09 10:06 ` [PATCH V2 03/12] misc: xilinx_sdfec: Add CCF support Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 04/12] misc: xilinx_sdfec: Add open, close and ioctl Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 05/12] misc: xilinx_sdfec: Store driver config and state Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 06/12] misc: xilinx_sdfec: Add ability to configure turbo Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 07/12] misc: xilinx_sdfec: Add ability to configure LDPC Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 08/12] misc: xilinx_sdfec: Add ability to get/set config Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 09/12] misc: xilinx_sdfec: Support poll file operation Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 10/12] misc: xilinx_sdfec: Add stats & status ioctls Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 11/12] Docs: misc: xilinx_sdfec: Add documentation Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic 2019-04-09 10:06 ` [PATCH V2 12/12] MAINTAINERS: add maintainer for SD-FEC Dragan Cvetic 2019-04-09 10:06 ` Dragan Cvetic
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=1554804414-206099-4-git-send-email-dragan.cvetic@xilinx.com \ --to=dragan.cvetic@xilinx.com \ --cc=arnd@arndb.de \ --cc=derek.kiernan@xilinx.com \ --cc=gregkh@linuxfoundation.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=michal.simek@xilinx.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.