in qcom-ebi2.c [292:388]
static int qcom_ebi2_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
struct device *dev = &pdev->dev;
struct resource *res;
void __iomem *ebi2_base;
void __iomem *ebi2_xmem;
struct clk *ebi2xclk;
struct clk *ebi2clk;
bool have_children = false;
u32 val;
int ret;
ebi2xclk = devm_clk_get(dev, "ebi2x");
if (IS_ERR(ebi2xclk))
return PTR_ERR(ebi2xclk);
ret = clk_prepare_enable(ebi2xclk);
if (ret) {
dev_err(dev, "could not enable EBI2X clk (%d)\n", ret);
return ret;
}
ebi2clk = devm_clk_get(dev, "ebi2");
if (IS_ERR(ebi2clk)) {
ret = PTR_ERR(ebi2clk);
goto err_disable_2x_clk;
}
ret = clk_prepare_enable(ebi2clk);
if (ret) {
dev_err(dev, "could not enable EBI2 clk\n");
goto err_disable_2x_clk;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ebi2_base = devm_ioremap_resource(dev, res);
if (IS_ERR(ebi2_base)) {
ret = PTR_ERR(ebi2_base);
goto err_disable_clk;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
ebi2_xmem = devm_ioremap_resource(dev, res);
if (IS_ERR(ebi2_xmem)) {
ret = PTR_ERR(ebi2_xmem);
goto err_disable_clk;
}
/* Allegedly this turns the power save mode off */
writel(0UL, ebi2_xmem + EBI2_XMEM_CFG);
/* Disable all chipselects */
val = readl(ebi2_base);
val &= ~EBI2_CSN_MASK;
writel(val, ebi2_base);
/* Walk over the child nodes and see what chipselects we use */
for_each_available_child_of_node(np, child) {
u32 csindex;
/* Figure out the chipselect */
ret = of_property_read_u32(child, "reg", &csindex);
if (ret) {
of_node_put(child);
return ret;
}
if (csindex > 5) {
dev_err(dev,
"invalid chipselect %u, we only support 0-5\n",
csindex);
continue;
}
qcom_ebi2_setup_chipselect(child,
dev,
ebi2_base,
ebi2_xmem,
csindex);
/* We have at least one child */
have_children = true;
}
if (have_children)
return of_platform_default_populate(np, NULL, dev);
return 0;
err_disable_clk:
clk_disable_unprepare(ebi2clk);
err_disable_2x_clk:
clk_disable_unprepare(ebi2xclk);
return ret;
}