diff mbox

[v2,2/2] dmaengine: vdma: Add clock support

Message ID 1461152599-28858-2-git-send-email-appanad@xilinx.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Appana Durga Kedareswara rao April 20, 2016, 11:43 a.m. UTC
Added basic clock support. The clocks are requested at probe
and released at remove.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v2:
--> None.

 drivers/dma/xilinx/xilinx_vdma.c | 56 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

Comments

Shubhrajyoti Datta April 20, 2016, 11:54 a.m. UTC | #1
On Wed, Apr 20, 2016 at 5:13 PM, Kedareswara rao Appana
<appana.durga.rao@xilinx.com> wrote:
> Added basic clock support. The clocks are requested at probe
> and released at remove.
>
> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>


Reviewed-by: Shubhrajyoti Datta  <shubhraj@xilinx.com>
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Soren Brinkmann April 20, 2016, 2:36 p.m. UTC | #2
On Wed, 2016-04-20 at 17:13:19 +0530, Kedareswara rao Appana wrote:
> Added basic clock support. The clocks are requested at probe
> and released at remove.
> 
> Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
> ---
> Changes for v2:
> --> None.
> 
>  drivers/dma/xilinx/xilinx_vdma.c | 56 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 56 insertions(+)
> 
> diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
> index 70caea6..d526029 100644
> --- a/drivers/dma/xilinx/xilinx_vdma.c
> +++ b/drivers/dma/xilinx/xilinx_vdma.c
> @@ -44,6 +44,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/of_irq.h>
>  #include <linux/slab.h>
> +#include <linux/clk.h>
>  
>  #include "../dmaengine.h"
>  
> @@ -352,6 +353,8 @@ struct xilinx_dma_chan {
>   * @flush_on_fsync: Flush on frame sync
>   * @ext_addr: Indicates 64 bit addressing is supported by dma device
>   * @dmatype: DMA ip type
> + * @clks:	pointer to array of clocks
> + * @numclks:	number of clocks available
>   */
>  struct xilinx_dma_device {
>  	void __iomem *regs;
> @@ -362,6 +365,8 @@ struct xilinx_dma_device {
>  	u32 flush_on_fsync;
>  	bool ext_addr;
>  	enum xdma_ip_type dmatype;
> +	struct clk **clks;
> +	int numclks;
>  };
>  
>  /* Macros */
> @@ -1731,6 +1736,26 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
>  }
>  EXPORT_SYMBOL(xilinx_vdma_channel_set_config);
>  
> +static int xdma_clk_init(struct xilinx_dma_device *xdev, bool enable)
> +{
> +	int i = 0, ret;
> +
> +	for (i = 0; i < xdev->numclks; i++) {
> +		if (enable) {
> +			ret = clk_prepare_enable(xdev->clks[i]);
> +			if (ret) {
> +				dev_err(xdev->dev,
> +					"failed to enable the axidma clock\n");
> +				return ret;
> +			}
> +		} else {
> +			clk_disable_unprepare(xdev->clks[i]);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  /* -----------------------------------------------------------------------------
>   * Probe and remove
>   */
> @@ -1919,6 +1944,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
>  	struct resource *io;
>  	u32 num_frames, addr_width;
>  	int i, err;
> +	const char *str;
>  
>  	/* Allocate and initialize the DMA engine structure */
>  	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> @@ -1965,6 +1991,32 @@ static int xilinx_dma_probe(struct platform_device *pdev)
>  	/* Set the dma mask bits */
>  	dma_set_mask(xdev->dev, DMA_BIT_MASK(addr_width));
>  
> +	xdev->numclks = of_property_count_strings(pdev->dev.of_node,
> +						  "clock-names");
> +	if (xdev->numclks > 0) {
> +		xdev->clks = devm_kmalloc_array(&pdev->dev, xdev->numclks,
> +						sizeof(struct clk *),
> +						GFP_KERNEL);
> +		if (!xdev->clks)
> +			return -ENOMEM;
> +
> +		for (i = 0; i < xdev->numclks; i++) {
> +			of_property_read_string_index(pdev->dev.of_node,
> +						      "clock-names", i, &str);
> +			xdev->clks[i] = devm_clk_get(xdev->dev, str);
> +			if (IS_ERR(xdev->clks[i])) {
> +				if (PTR_ERR(xdev->clks[i]) == -ENOENT)
> +					xdev->clks[i] = NULL;
> +				else
> +					return PTR_ERR(xdev->clks[i]);
> +			}
> +		}
> +
> +		err = xdma_clk_init(xdev, true);
> +		if (err)
> +			return err;
> +	}

I guess this works, but the relation to the binding is a little loose,
IMHO. Instead of using the clock names from the binding this is just
using whatever is provided in DT and enabling it. Also, all the clocks
here are handled as optional feature, while binding - and I guess
reality too - have them as mandatory.
It would be nicer if the driver specifically asks for the clocks it
needs and return an error if a mandatory clock is missing.

	Sören
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Appana Durga Kedareswara rao April 20, 2016, 2:55 p.m. UTC | #3
SGkgU29yZW4sDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogU8O2cmVu
IEJyaW5rbWFubiBbbWFpbHRvOnNvcmVuLmJyaW5rbWFubkB4aWxpbnguY29tXQ0KPiBTZW50OiBX
ZWRuZXNkYXksIEFwcmlsIDIwLCAyMDE2IDg6MDYgUE0NCj4gVG86IEFwcGFuYSBEdXJnYSBLZWRh
cmVzd2FyYSBSYW8gPGFwcGFuYWRAeGlsaW54LmNvbT4NCj4gQ2M6IHJvYmgrZHRAa2VybmVsLm9y
ZzsgcGF3ZWwubW9sbEBhcm0uY29tOyBtYXJrLnJ1dGxhbmRAYXJtLmNvbTsNCj4gaWpjK2Rldmlj
ZXRyZWVAaGVsbGlvbi5vcmcudWs7IGdhbGFrQGNvZGVhdXJvcmEub3JnOyBNaWNoYWwgU2ltZWsN
Cj4gPG1pY2hhbHNAeGlsaW54LmNvbT47IHZpbm9kLmtvdWxAaW50ZWwuY29tOyBkYW4uai53aWxs
aWFtc0BpbnRlbC5jb207DQo+IEFwcGFuYSBEdXJnYSBLZWRhcmVzd2FyYSBSYW8gPGFwcGFuYWRA
eGlsaW54LmNvbT47DQo+IG1vcml0ei5maXNjaGVyQGV0dHVzLmNvbTsgbGF1cmVudC5waW5jaGFy
dEBpZGVhc29uYm9hcmQuY29tOw0KPiBsdWlzQGRlYmV0aGVuY291cnQuY29tOyBBbmlydWRoYSBT
YXJhbmdpIDxhbmlydWRoQHhpbGlueC5jb20+OyBQdW5uYWlhaA0KPiBDaG91ZGFyeSBLYWxsdXJp
IDxwdW5uYWlhQHhpbGlueC5jb20+OyBTaHViaHJhanlvdGkgRGF0dGENCj4gPHNodWJocmFqQHhp
bGlueC5jb20+OyBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZzsgbGludXgtYXJtLQ0KPiBrZXJu
ZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsgbGludXgta2VybmVsQHZnZXIua2VybmVsLm9yZzsNCj4g
ZG1hZW5naW5lQHZnZXIua2VybmVsLm9yZw0KPiBTdWJqZWN0OiBSZTogW1BBVENIIHYyIDIvMl0g
ZG1hZW5naW5lOiB2ZG1hOiBBZGQgY2xvY2sgc3VwcG9ydA0KPiANCj4gT24gV2VkLCAyMDE2LTA0
LTIwIGF0IDE3OjEzOjE5ICswNTMwLCBLZWRhcmVzd2FyYSByYW8gQXBwYW5hIHdyb3RlOg0KPiA+
IEFkZGVkIGJhc2ljIGNsb2NrIHN1cHBvcnQuIFRoZSBjbG9ja3MgYXJlIHJlcXVlc3RlZCBhdCBw
cm9iZSBhbmQNCj4gPiByZWxlYXNlZCBhdCByZW1vdmUuDQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5
OiBLZWRhcmVzd2FyYSByYW8gQXBwYW5hIDxhcHBhbmFkQHhpbGlueC5jb20+DQo+ID4gLS0tDQo+
ID4gQ2hhbmdlcyBmb3IgdjI6DQo+ID4gLS0+IE5vbmUuDQo+ID4NCj4gPiAgZHJpdmVycy9kbWEv
eGlsaW54L3hpbGlueF92ZG1hLmMgfCA1Ng0KPiA+ICsrKysrKysrKysrKysrKysrKysrKysrKysr
KysrKysrKysrKysrKysNCj4gPiAgMSBmaWxlIGNoYW5nZWQsIDU2IGluc2VydGlvbnMoKykNCj4g
Pg0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS94aWxpbngveGlsaW54X3ZkbWEuYw0KPiA+
IGIvZHJpdmVycy9kbWEveGlsaW54L3hpbGlueF92ZG1hLmMNCj4gPiBpbmRleCA3MGNhZWE2Li5k
NTI2MDI5IDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvZG1hL3hpbGlueC94aWxpbnhfdmRtYS5j
DQo+ID4gKysrIGIvZHJpdmVycy9kbWEveGlsaW54L3hpbGlueF92ZG1hLmMNCj4gPiBAQCAtNDQs
NiArNDQsNyBAQA0KPiA+ICAjaW5jbHVkZSA8bGludXgvb2ZfcGxhdGZvcm0uaD4NCj4gPiAgI2lu
Y2x1ZGUgPGxpbnV4L29mX2lycS5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvc2xhYi5oPg0KPiA+
ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+DQo+ID4NCj4gPiAgI2luY2x1ZGUgIi4uL2RtYWVuZ2lu
ZS5oIg0KPiA+DQo+ID4gQEAgLTM1Miw2ICszNTMsOCBAQCBzdHJ1Y3QgeGlsaW54X2RtYV9jaGFu
IHsNCj4gPiAgICogQGZsdXNoX29uX2ZzeW5jOiBGbHVzaCBvbiBmcmFtZSBzeW5jDQo+ID4gICAq
IEBleHRfYWRkcjogSW5kaWNhdGVzIDY0IGJpdCBhZGRyZXNzaW5nIGlzIHN1cHBvcnRlZCBieSBk
bWEgZGV2aWNlDQo+ID4gICAqIEBkbWF0eXBlOiBETUEgaXAgdHlwZQ0KPiA+ICsgKiBAY2xrczoJ
cG9pbnRlciB0byBhcnJheSBvZiBjbG9ja3MNCj4gPiArICogQG51bWNsa3M6CW51bWJlciBvZiBj
bG9ja3MgYXZhaWxhYmxlDQo+ID4gICAqLw0KPiA+ICBzdHJ1Y3QgeGlsaW54X2RtYV9kZXZpY2Ug
ew0KPiA+ICAJdm9pZCBfX2lvbWVtICpyZWdzOw0KPiA+IEBAIC0zNjIsNiArMzY1LDggQEAgc3Ry
dWN0IHhpbGlueF9kbWFfZGV2aWNlIHsNCj4gPiAgCXUzMiBmbHVzaF9vbl9mc3luYzsNCj4gPiAg
CWJvb2wgZXh0X2FkZHI7DQo+ID4gIAllbnVtIHhkbWFfaXBfdHlwZSBkbWF0eXBlOw0KPiA+ICsJ
c3RydWN0IGNsayAqKmNsa3M7DQo+ID4gKwlpbnQgbnVtY2xrczsNCj4gPiAgfTsNCj4gPg0KPiA+
ICAvKiBNYWNyb3MgKi8NCj4gPiBAQCAtMTczMSw2ICsxNzM2LDI2IEBAIGludCB4aWxpbnhfdmRt
YV9jaGFubmVsX3NldF9jb25maWcoc3RydWN0DQo+ID4gZG1hX2NoYW4gKmRjaGFuLCAgfSAgRVhQ
T1JUX1NZTUJPTCh4aWxpbnhfdmRtYV9jaGFubmVsX3NldF9jb25maWcpOw0KPiA+DQo+ID4gK3N0
YXRpYyBpbnQgeGRtYV9jbGtfaW5pdChzdHJ1Y3QgeGlsaW54X2RtYV9kZXZpY2UgKnhkZXYsIGJv
b2wgZW5hYmxlKQ0KPiA+ICt7DQo+ID4gKwlpbnQgaSA9IDAsIHJldDsNCj4gPiArDQo+ID4gKwlm
b3IgKGkgPSAwOyBpIDwgeGRldi0+bnVtY2xrczsgaSsrKSB7DQo+ID4gKwkJaWYgKGVuYWJsZSkg
ew0KPiA+ICsJCQlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoeGRldi0+Y2xrc1tpXSk7DQo+ID4g
KwkJCWlmIChyZXQpIHsNCj4gPiArCQkJCWRldl9lcnIoeGRldi0+ZGV2LA0KPiA+ICsJCQkJCSJm
YWlsZWQgdG8gZW5hYmxlIHRoZSBheGlkbWEgY2xvY2tcbiIpOw0KPiA+ICsJCQkJcmV0dXJuIHJl
dDsNCj4gPiArCQkJfQ0KPiA+ICsJCX0gZWxzZSB7DQo+ID4gKwkJCWNsa19kaXNhYmxlX3VucHJl
cGFyZSh4ZGV2LT5jbGtzW2ldKTsNCj4gPiArCQl9DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0
dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQo+ID4g
ICAqIFByb2JlIGFuZCByZW1vdmUNCj4gPiAgICovDQo+ID4gQEAgLTE5MTksNiArMTk0NCw3IEBA
IHN0YXRpYyBpbnQgeGlsaW54X2RtYV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlDQo+ICpw
ZGV2KQ0KPiA+ICAJc3RydWN0IHJlc291cmNlICppbzsNCj4gPiAgCXUzMiBudW1fZnJhbWVzLCBh
ZGRyX3dpZHRoOw0KPiA+ICAJaW50IGksIGVycjsNCj4gPiArCWNvbnN0IGNoYXIgKnN0cjsNCj4g
Pg0KPiA+ICAJLyogQWxsb2NhdGUgYW5kIGluaXRpYWxpemUgdGhlIERNQSBlbmdpbmUgc3RydWN0
dXJlICovDQo+ID4gIAl4ZGV2ID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNpemVvZigqeGRl
diksIEdGUF9LRVJORUwpOyBAQA0KPiA+IC0xOTY1LDYgKzE5OTEsMzIgQEAgc3RhdGljIGludCB4
aWxpbnhfZG1hX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UNCj4gKnBkZXYpDQo+ID4gIAkv
KiBTZXQgdGhlIGRtYSBtYXNrIGJpdHMgKi8NCj4gPiAgCWRtYV9zZXRfbWFzayh4ZGV2LT5kZXYs
IERNQV9CSVRfTUFTSyhhZGRyX3dpZHRoKSk7DQo+ID4NCj4gPiArCXhkZXYtPm51bWNsa3MgPSBv
Zl9wcm9wZXJ0eV9jb3VudF9zdHJpbmdzKHBkZXYtPmRldi5vZl9ub2RlLA0KPiA+ICsJCQkJCQkg
ICJjbG9jay1uYW1lcyIpOw0KPiA+ICsJaWYgKHhkZXYtPm51bWNsa3MgPiAwKSB7DQo+ID4gKwkJ
eGRldi0+Y2xrcyA9IGRldm1fa21hbGxvY19hcnJheSgmcGRldi0+ZGV2LCB4ZGV2LT5udW1jbGtz
LA0KPiA+ICsJCQkJCQlzaXplb2Yoc3RydWN0IGNsayAqKSwNCj4gPiArCQkJCQkJR0ZQX0tFUk5F
TCk7DQo+ID4gKwkJaWYgKCF4ZGV2LT5jbGtzKQ0KPiA+ICsJCQlyZXR1cm4gLUVOT01FTTsNCj4g
PiArDQo+ID4gKwkJZm9yIChpID0gMDsgaSA8IHhkZXYtPm51bWNsa3M7IGkrKykgew0KPiA+ICsJ
CQlvZl9wcm9wZXJ0eV9yZWFkX3N0cmluZ19pbmRleChwZGV2LT5kZXYub2Zfbm9kZSwNCj4gPiAr
CQkJCQkJICAgICAgImNsb2NrLW5hbWVzIiwgaSwgJnN0cik7DQo+ID4gKwkJCXhkZXYtPmNsa3Nb
aV0gPSBkZXZtX2Nsa19nZXQoeGRldi0+ZGV2LCBzdHIpOw0KPiA+ICsJCQlpZiAoSVNfRVJSKHhk
ZXYtPmNsa3NbaV0pKSB7DQo+ID4gKwkJCQlpZiAoUFRSX0VSUih4ZGV2LT5jbGtzW2ldKSA9PSAt
RU5PRU5UKQ0KPiA+ICsJCQkJCXhkZXYtPmNsa3NbaV0gPSBOVUxMOw0KPiA+ICsJCQkJZWxzZQ0K
PiA+ICsJCQkJCXJldHVybiBQVFJfRVJSKHhkZXYtPmNsa3NbaV0pOw0KPiA+ICsJCQl9DQo+ID4g
KwkJfQ0KPiA+ICsNCj4gPiArCQllcnIgPSB4ZG1hX2Nsa19pbml0KHhkZXYsIHRydWUpOw0KPiA+
ICsJCWlmIChlcnIpDQo+ID4gKwkJCXJldHVybiBlcnI7DQo+ID4gKwl9DQo+IA0KPiBJIGd1ZXNz
IHRoaXMgd29ya3MsIGJ1dCB0aGUgcmVsYXRpb24gdG8gdGhlIGJpbmRpbmcgaXMgYSBsaXR0bGUg
bG9vc2UsIElNSE8uIEluc3RlYWQNCj4gb2YgdXNpbmcgdGhlIGNsb2NrIG5hbWVzIGZyb20gdGhl
IGJpbmRpbmcgdGhpcyBpcyBqdXN0IHVzaW5nIHdoYXRldmVyIGlzIHByb3ZpZGVkDQo+IGluIERU
IGFuZCBlbmFibGluZyBpdC4gQWxzbywgYWxsIHRoZSBjbG9ja3MgaGVyZSBhcmUgaGFuZGxlZCBh
cyBvcHRpb25hbCBmZWF0dXJlLA0KPiB3aGlsZSBiaW5kaW5nIC0gYW5kIEkgZ3Vlc3MgcmVhbGl0
eSB0b28gLSBoYXZlIHRoZW0gYXMgbWFuZGF0b3J5Lg0KPiBJdCB3b3VsZCBiZSBuaWNlciBpZiB0
aGUgZHJpdmVyIHNwZWNpZmljYWxseSBhc2tzIGZvciB0aGUgY2xvY2tzIGl0IG5lZWRzIGFuZCBy
ZXR1cm4NCj4gYW4gZXJyb3IgaWYgYSBtYW5kYXRvcnkgY2xvY2sgaXMgbWlzc2luZy4NCg0KSGVy
ZSBETUEgY2hhbm5lbHMgYXJlIGNvbmZpZ3VyYWJsZSBJIG1lYW4gaWYgdXNlciBzZWxlY3Qgb25s
eSBtbTJzIGNoYW5uZWwgdGhlbiB3ZSB3aWxsIGhhdmUNCk9ubHkgMyBjbG9ja3MuIElmIHVzZXIg
c2VsZWN0cyBib3RoIG1tMnMgYW5kIHMybW0gY2hhbm5lbHMgd2Ugd2lsbCBoYXZlIDUgY2xvY2tz
Lg0KVGhhdOKAmXMgd2h5IHJlYWRpbmcgdGhlIG51bWJlciBvZiBjbG9ja3MgZnJvbSB0aGUgY2xv
Y2stbmFtZXMgcHJvcGVydHkuDQoNCkFuZCBhbHNvIHRoZSBBWEkgRE1BL0NETUEgSXAgc3VwcG9y
dCBhbHNvIGdldHRpbmcgYWRkZWQgdG8gdGhpcyBkcml2ZXIgZm9yIHRob3NlIElQJ3MgYWxzbyB0
aGUgY2xvY2tzIGFyZSBjb25maWd1cmFibGUNCkZvciBBWEkgRE1BIGl0IGlzIGVpdGhlciAzIG9y
IDQgY2xvY2tzIGFuZCBmb3IgQVhJIENETUEgaXQgaXMgMiBjbG9ja3MuDQoNClRoYXQncyB3aHkg
SSB0aG91Z2h0IGl0IGlzIHRoZSBwcm9wZXIgc29sdXRpb24uDQoNCklmIHlvdSBoYXZlIGFueSBi
ZXR0ZXIgaWRlYSBwbGVhc2UgbGV0IG1lIGtub3cgd2lsbCB0cnkgaW4gdGhhdCB3YXkuLi4NCg0K
UmVnYXJkcywNCktlZGFyLg0KPiANCj4gCVPDtnJlbg0K
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Soren Brinkmann April 20, 2016, 4:12 p.m. UTC | #4
On Wed, 2016-04-20 at 07:55:27 -0700, Appana Durga Kedareswara Rao wrote:
> Hi Soren,
> 
> > -----Original Message-----
> > From: Sören Brinkmann [mailto:soren.brinkmann@xilinx.com]
> > Sent: Wednesday, April 20, 2016 8:06 PM
> > To: Appana Durga Kedareswara Rao <appanad@xilinx.com>
> > Cc: robh+dt@kernel.org; pawel.moll@arm.com; mark.rutland@arm.com;
> > ijc+devicetree@hellion.org.uk; galak@codeaurora.org; Michal Simek
> > <michals@xilinx.com>; vinod.koul@intel.com; dan.j.williams@intel.com;
> > Appana Durga Kedareswara Rao <appanad@xilinx.com>;
> > moritz.fischer@ettus.com; laurent.pinchart@ideasonboard.com;
> > luis@debethencourt.com; Anirudha Sarangi <anirudh@xilinx.com>; Punnaiah
> > Choudary Kalluri <punnaia@xilinx.com>; Shubhrajyoti Datta
> > <shubhraj@xilinx.com>; devicetree@vger.kernel.org; linux-arm-
> > kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> > dmaengine@vger.kernel.org
> > Subject: Re: [PATCH v2 2/2] dmaengine: vdma: Add clock support
> > 
> > On Wed, 2016-04-20 at 17:13:19 +0530, Kedareswara rao Appana wrote:
> > > Added basic clock support. The clocks are requested at probe and
> > > released at remove.
> > >
> > > Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
> > > ---
> > > Changes for v2:
> > > --> None.
> > >
> > >  drivers/dma/xilinx/xilinx_vdma.c | 56
> > > ++++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 56 insertions(+)
> > >
> > > diff --git a/drivers/dma/xilinx/xilinx_vdma.c
> > > b/drivers/dma/xilinx/xilinx_vdma.c
> > > index 70caea6..d526029 100644
> > > --- a/drivers/dma/xilinx/xilinx_vdma.c
> > > +++ b/drivers/dma/xilinx/xilinx_vdma.c
> > > @@ -44,6 +44,7 @@
> > >  #include <linux/of_platform.h>
> > >  #include <linux/of_irq.h>
> > >  #include <linux/slab.h>
> > > +#include <linux/clk.h>
> > >
> > >  #include "../dmaengine.h"
> > >
> > > @@ -352,6 +353,8 @@ struct xilinx_dma_chan {
> > >   * @flush_on_fsync: Flush on frame sync
> > >   * @ext_addr: Indicates 64 bit addressing is supported by dma device
> > >   * @dmatype: DMA ip type
> > > + * @clks:	pointer to array of clocks
> > > + * @numclks:	number of clocks available
> > >   */
> > >  struct xilinx_dma_device {
> > >  	void __iomem *regs;
> > > @@ -362,6 +365,8 @@ struct xilinx_dma_device {
> > >  	u32 flush_on_fsync;
> > >  	bool ext_addr;
> > >  	enum xdma_ip_type dmatype;
> > > +	struct clk **clks;
> > > +	int numclks;
> > >  };
> > >
> > >  /* Macros */
> > > @@ -1731,6 +1736,26 @@ int xilinx_vdma_channel_set_config(struct
> > > dma_chan *dchan,  }  EXPORT_SYMBOL(xilinx_vdma_channel_set_config);
> > >
> > > +static int xdma_clk_init(struct xilinx_dma_device *xdev, bool enable)
> > > +{
> > > +	int i = 0, ret;
> > > +
> > > +	for (i = 0; i < xdev->numclks; i++) {
> > > +		if (enable) {
> > > +			ret = clk_prepare_enable(xdev->clks[i]);
> > > +			if (ret) {
> > > +				dev_err(xdev->dev,
> > > +					"failed to enable the axidma clock\n");
> > > +				return ret;
> > > +			}
> > > +		} else {
> > > +			clk_disable_unprepare(xdev->clks[i]);
> > > +		}
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  /* -----------------------------------------------------------------------------
> > >   * Probe and remove
> > >   */
> > > @@ -1919,6 +1944,7 @@ static int xilinx_dma_probe(struct platform_device
> > *pdev)
> > >  	struct resource *io;
> > >  	u32 num_frames, addr_width;
> > >  	int i, err;
> > > +	const char *str;
> > >
> > >  	/* Allocate and initialize the DMA engine structure */
> > >  	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); @@
> > > -1965,6 +1991,32 @@ static int xilinx_dma_probe(struct platform_device
> > *pdev)
> > >  	/* Set the dma mask bits */
> > >  	dma_set_mask(xdev->dev, DMA_BIT_MASK(addr_width));
> > >
> > > +	xdev->numclks = of_property_count_strings(pdev->dev.of_node,
> > > +						  "clock-names");
> > > +	if (xdev->numclks > 0) {
> > > +		xdev->clks = devm_kmalloc_array(&pdev->dev, xdev->numclks,
> > > +						sizeof(struct clk *),
> > > +						GFP_KERNEL);
> > > +		if (!xdev->clks)
> > > +			return -ENOMEM;
> > > +
> > > +		for (i = 0; i < xdev->numclks; i++) {
> > > +			of_property_read_string_index(pdev->dev.of_node,
> > > +						      "clock-names", i, &str);
> > > +			xdev->clks[i] = devm_clk_get(xdev->dev, str);
> > > +			if (IS_ERR(xdev->clks[i])) {
> > > +				if (PTR_ERR(xdev->clks[i]) == -ENOENT)
> > > +					xdev->clks[i] = NULL;
> > > +				else
> > > +					return PTR_ERR(xdev->clks[i]);
> > > +			}
> > > +		}
> > > +
> > > +		err = xdma_clk_init(xdev, true);
> > > +		if (err)
> > > +			return err;
> > > +	}
> > 
> > I guess this works, but the relation to the binding is a little loose, IMHO. Instead
> > of using the clock names from the binding this is just using whatever is provided
> > in DT and enabling it. Also, all the clocks here are handled as optional feature,
> > while binding - and I guess reality too - have them as mandatory.
> > It would be nicer if the driver specifically asks for the clocks it needs and return
> > an error if a mandatory clock is missing.
> 
> Here DMA channels are configurable I mean if user select only mm2s channel then we will have
> Only 3 clocks. If user selects both mm2s and s2mm channels we will have 5 clocks.
> That’s why reading the number of clocks from the clock-names property.
> 
> And also the AXI DMA/CDMA Ip support also getting added to this driver for those IP's also the clocks are configurable
> For AXI DMA it is either 3 or 4 clocks and for AXI CDMA it is 2 clocks.
> 
> That's why I thought it is the proper solution.
> 
> If you have any better idea please let me know will try in that way...

I guess the driver know all these things: whether it controls vdma or
cdma, what interfaces it has and how many channels? Based on that, I
guess it should be possible to derive what clocks are required for
correct operation.

	Sören
--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index 70caea6..d526029 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -44,6 +44,7 @@ 
 #include <linux/of_platform.h>
 #include <linux/of_irq.h>
 #include <linux/slab.h>
+#include <linux/clk.h>
 
 #include "../dmaengine.h"
 
@@ -352,6 +353,8 @@  struct xilinx_dma_chan {
  * @flush_on_fsync: Flush on frame sync
  * @ext_addr: Indicates 64 bit addressing is supported by dma device
  * @dmatype: DMA ip type
+ * @clks:	pointer to array of clocks
+ * @numclks:	number of clocks available
  */
 struct xilinx_dma_device {
 	void __iomem *regs;
@@ -362,6 +365,8 @@  struct xilinx_dma_device {
 	u32 flush_on_fsync;
 	bool ext_addr;
 	enum xdma_ip_type dmatype;
+	struct clk **clks;
+	int numclks;
 };
 
 /* Macros */
@@ -1731,6 +1736,26 @@  int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
 }
 EXPORT_SYMBOL(xilinx_vdma_channel_set_config);
 
+static int xdma_clk_init(struct xilinx_dma_device *xdev, bool enable)
+{
+	int i = 0, ret;
+
+	for (i = 0; i < xdev->numclks; i++) {
+		if (enable) {
+			ret = clk_prepare_enable(xdev->clks[i]);
+			if (ret) {
+				dev_err(xdev->dev,
+					"failed to enable the axidma clock\n");
+				return ret;
+			}
+		} else {
+			clk_disable_unprepare(xdev->clks[i]);
+		}
+	}
+
+	return 0;
+}
+
 /* -----------------------------------------------------------------------------
  * Probe and remove
  */
@@ -1919,6 +1944,7 @@  static int xilinx_dma_probe(struct platform_device *pdev)
 	struct resource *io;
 	u32 num_frames, addr_width;
 	int i, err;
+	const char *str;
 
 	/* Allocate and initialize the DMA engine structure */
 	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
@@ -1965,6 +1991,32 @@  static int xilinx_dma_probe(struct platform_device *pdev)
 	/* Set the dma mask bits */
 	dma_set_mask(xdev->dev, DMA_BIT_MASK(addr_width));
 
+	xdev->numclks = of_property_count_strings(pdev->dev.of_node,
+						  "clock-names");
+	if (xdev->numclks > 0) {
+		xdev->clks = devm_kmalloc_array(&pdev->dev, xdev->numclks,
+						sizeof(struct clk *),
+						GFP_KERNEL);
+		if (!xdev->clks)
+			return -ENOMEM;
+
+		for (i = 0; i < xdev->numclks; i++) {
+			of_property_read_string_index(pdev->dev.of_node,
+						      "clock-names", i, &str);
+			xdev->clks[i] = devm_clk_get(xdev->dev, str);
+			if (IS_ERR(xdev->clks[i])) {
+				if (PTR_ERR(xdev->clks[i]) == -ENOENT)
+					xdev->clks[i] = NULL;
+				else
+					return PTR_ERR(xdev->clks[i]);
+			}
+		}
+
+		err = xdma_clk_init(xdev, true);
+		if (err)
+			return err;
+	}
+
 	/* Initialize the DMA engine */
 	xdev->common.dev = &pdev->dev;
 
@@ -2025,6 +2077,8 @@  static int xilinx_dma_probe(struct platform_device *pdev)
 	return 0;
 
 error:
+	if (xdev->numclks > 0)
+		xdma_clk_init(xdev, false);
 	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
 		if (xdev->chan[i])
 			xilinx_dma_chan_remove(xdev->chan[i]);
@@ -2050,6 +2104,8 @@  static int xilinx_dma_remove(struct platform_device *pdev)
 	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
 		if (xdev->chan[i])
 			xilinx_dma_chan_remove(xdev->chan[i]);
+	if (xdev->numclks > 0)
+		xdma_clk_init(xdev, false);
 
 	return 0;
 }