Skip to content

Commit 740b5b3

Browse files
paulkocialkowskimchehab
authored andcommitted
media: sun6i-csi: Always set exclusive module clock rate
In some situations the default rate of the module clock is not the required one for operation (for example when reconfiguring the clock tree to use a different parent). As a result, always set the correct rate for the clock (and take care of cleanup). Signed-off-by: Paul Kocialkowski <[email protected]> Reviewed-by: Jernej Skrabec <[email protected]> Signed-off-by: Hans Verkuil <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 43e8019 commit 740b5b3

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable)
154154
regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0);
155155

156156
clk_disable_unprepare(csi_dev->clock_ram);
157-
if (of_device_is_compatible(dev->of_node,
158-
"allwinner,sun50i-a64-csi"))
159-
clk_rate_exclusive_put(csi_dev->clock_mod);
160157
clk_disable_unprepare(csi_dev->clock_mod);
161158
reset_control_assert(csi_dev->reset);
162159
return 0;
@@ -168,9 +165,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable)
168165
return ret;
169166
}
170167

171-
if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi"))
172-
clk_set_rate_exclusive(csi_dev->clock_mod, 300000000);
173-
174168
ret = clk_prepare_enable(csi_dev->clock_ram);
175169
if (ret) {
176170
dev_err(csi_dev->dev, "Enable clk_dram_csi clk err %d\n", ret);
@@ -190,8 +184,6 @@ int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable)
190184
clk_ram_disable:
191185
clk_disable_unprepare(csi_dev->clock_ram);
192186
clk_mod_disable:
193-
if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi"))
194-
clk_rate_exclusive_put(csi_dev->clock_mod);
195187
clk_disable_unprepare(csi_dev->clock_mod);
196188
return ret;
197189
}
@@ -816,6 +808,7 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev,
816808
struct platform_device *platform_dev)
817809
{
818810
struct device *dev = csi_dev->dev;
811+
unsigned long clock_mod_rate;
819812
void __iomem *io_base;
820813
int ret;
821814
int irq;
@@ -847,28 +840,53 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev,
847840
return PTR_ERR(csi_dev->clock_ram);
848841
}
849842

843+
if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi"))
844+
clock_mod_rate = 300000000;
845+
else
846+
clock_mod_rate = 297000000;
847+
848+
ret = clk_set_rate_exclusive(csi_dev->clock_mod, clock_mod_rate);
849+
if (ret) {
850+
dev_err(dev, "failed to set mod clock rate\n");
851+
return ret;
852+
}
853+
850854
/* Reset */
851855

852856
csi_dev->reset = devm_reset_control_get_shared(dev, NULL);
853857
if (IS_ERR(csi_dev->reset)) {
854858
dev_err(dev, "failed to acquire reset\n");
855-
return PTR_ERR(csi_dev->reset);
859+
ret = PTR_ERR(csi_dev->reset);
860+
goto error_clock_rate_exclusive;
856861
}
857862

858863
/* Interrupt */
859864

860865
irq = platform_get_irq(platform_dev, 0);
861-
if (irq < 0)
862-
return -ENXIO;
866+
if (irq < 0) {
867+
dev_err(dev, "failed to get interrupt\n");
868+
ret = -ENXIO;
869+
goto error_clock_rate_exclusive;
870+
}
863871

864872
ret = devm_request_irq(dev, irq, sun6i_csi_interrupt, 0, SUN6I_CSI_NAME,
865873
csi_dev);
866874
if (ret) {
867875
dev_err(dev, "failed to request interrupt\n");
868-
return ret;
876+
goto error_clock_rate_exclusive;
869877
}
870878

871879
return 0;
880+
881+
error_clock_rate_exclusive:
882+
clk_rate_exclusive_put(csi_dev->clock_mod);
883+
884+
return ret;
885+
}
886+
887+
static void sun6i_csi_resources_cleanup(struct sun6i_csi_device *csi_dev)
888+
{
889+
clk_rate_exclusive_put(csi_dev->clock_mod);
872890
}
873891

874892
static int sun6i_csi_probe(struct platform_device *platform_dev)
@@ -888,14 +906,24 @@ static int sun6i_csi_probe(struct platform_device *platform_dev)
888906
if (ret)
889907
return ret;
890908

891-
return sun6i_csi_v4l2_init(csi_dev);
909+
ret = sun6i_csi_v4l2_init(csi_dev);
910+
if (ret)
911+
goto error_resources;
912+
913+
return 0;
914+
915+
error_resources:
916+
sun6i_csi_resources_cleanup(csi_dev);
917+
918+
return ret;
892919
}
893920

894921
static int sun6i_csi_remove(struct platform_device *pdev)
895922
{
896923
struct sun6i_csi_device *csi_dev = platform_get_drvdata(pdev);
897924

898925
sun6i_csi_v4l2_cleanup(csi_dev);
926+
sun6i_csi_resources_cleanup(csi_dev);
899927

900928
return 0;
901929
}

0 commit comments

Comments
 (0)