Пример #1
0
static int xhci_histb_config(struct xhci_hcd_histb *histb)
{
	struct device_node *np = histb->dev->of_node;
	u32 regval;

	if (of_property_match_string(np, "phys-names", "inno") >= 0) {
		/* USB2 PHY chose ulpi 8bit interface */
		regval = readl(histb->ctrl + REG_GUSB2PHYCFG0);
		regval &= ~BIT_UTMI_ULPI;
		regval &= ~(BIT_UTMI_8_16);
		regval &= ~BIT_FREECLK_EXIST;
		writel(regval, histb->ctrl + REG_GUSB2PHYCFG0);
	}

	if (of_property_match_string(np, "phys-names", "combo") >= 0) {
		/*
		 * write 0x010c0012 to GUSB3PIPECTL0
		 * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV ,
		 * decrease TX voltage
		 * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB,
		 * refer to xHCI spec
		 */
		regval = readl(histb->ctrl + REG_GUSB3PIPECTL0);
		regval &= ~USB3_DEEMPHASIS_MASK;
		regval |= USB3_DEEMPHASIS0;
		regval |= USB3_TX_MARGIN1;
		writel(regval, histb->ctrl + REG_GUSB3PIPECTL0);
	}

	writel(0x23100000, histb->ctrl + GTXTHRCFG);
	writel(0x23100000, histb->ctrl + GRXTHRCFG);

	return 0;
}
Пример #2
0
static int kick_l2spm(struct device_node *l2ccc_node,
				struct device_node *vctl_node)
{
	struct resource res, acinactm_res;
	int val;
	int timeout = 10, ret = 0;
	void __iomem *l2spm_base = of_iomap(vctl_node, 0);
	bool use_acinactm = false;
	int index;
	if (!l2spm_base)
		return -ENOMEM;

	if (!(__raw_readl(l2spm_base + L2_SPM_STS) & 0xFFFF0000))
		goto bail_l2_pwr_bit;

	index = of_property_match_string(l2ccc_node, "reg-names", "l2-common");
	if (index < 0)
		goto bail_l2_pwr_bit;
	ret = of_address_to_resource(l2ccc_node, index, &res);
	if (ret)
		goto bail_l2_pwr_bit;

	/* L2 is executing sleep state machine,
	 * let's softly kick it awake
	 */
	val = scm_io_read((u32)res.start);
	val |= BIT(0);
	scm_io_write((u32)res.start, val);

	use_acinactm = of_property_read_bool(l2ccc_node, "qcom,use-acinactm");
	if (use_acinactm) {
		index = of_property_match_string(l2ccc_node, "reg-names",
								"l2-acinactm");
		if (index < 0)
			goto bail_l2_pwr_bit;
		ret = of_address_to_resource(l2ccc_node, index, &acinactm_res);
		if (ret)
			goto bail_l2_pwr_bit;
		val = scm_io_read((u32)acinactm_res.start);
		val &= ~BIT(4);
		scm_io_write((u32)acinactm_res.start, val);
	}

	/* Wait until the SPM status indicates that the PWR_CTL
	 * bits are clear.
	 */
	while (readl_relaxed(l2spm_base + L2_SPM_STS) & 0xFFFF0000) {
		BUG_ON(!timeout--);
		cpu_relax();
		usleep(100);
	}

bail_l2_pwr_bit:
	iounmap(l2spm_base);
	return ret;
}
Пример #3
0
void __init clk_sp810_of_setup(struct device_node *node)
{
	struct clk_sp810 *sp810 = kzalloc(sizeof(*sp810), GFP_KERNEL);
	const char *parent_names[2];
	char name[12];
	struct clk_init_data init;
	static int instance;
	int i;

	if (!sp810) {
		pr_err("Failed to allocate memory for SP810!\n");
		return;
	}

	sp810->refclk_index = of_property_match_string(node, "clock-names",
			"refclk");
	parent_names[0] = of_clk_get_parent_name(node, sp810->refclk_index);

	sp810->timclk_index = of_property_match_string(node, "clock-names",
			"timclk");
	parent_names[1] = of_clk_get_parent_name(node, sp810->timclk_index);

	if (parent_names[0] <= 0 || parent_names[1] <= 0) {
		pr_warn("Failed to obtain parent clocks for SP810!\n");
		return;
	}

	sp810->node = node;
	sp810->base = of_iomap(node, 0);
	spin_lock_init(&sp810->lock);

	init.name = name;
	init.ops = &clk_sp810_timerclken_ops;
	init.flags = CLK_IS_BASIC;
	init.parent_names = parent_names;
	init.num_parents = ARRAY_SIZE(parent_names);

	for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) {
		snprintf(name, sizeof(name), "sp810_%d_%d", instance, i);

		sp810->timerclken[i].sp810 = sp810;
		sp810->timerclken[i].channel = i;
		sp810->timerclken[i].hw.init = &init;

		sp810->timerclken[i].clk = clk_register(NULL,
				&sp810->timerclken[i].hw);
		WARN_ON(IS_ERR(sp810->timerclken[i].clk));
	}

	of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810);
	instance++;
}
static int is_property_public(struct device_node *np, const char *prop_name)
{
    int ret;
    int len;
    struct property *pp;

    pp = of_find_property(np, HW_PUBLIC, NULL);
    if(!pp) {
        hwlog_err("of_find_property failed\n");
        return 0;
    }

    len = pp->length;
    if(len == 0) {
        return 1;
    }

    ret = of_property_match_string(np, HW_PUBLIC, prop_name);
    if(ret < 0) {
        hwlog_err("of_property_match_string error, ret = %d\n", ret);
        return 0;
    }

    return 1;
}
Пример #5
0
static struct clk_hw *sun8i_tcon_top_register_gate(struct device *dev,
						   const char *parent,
						   void __iomem *regs,
						   spinlock_t *lock,
						   u8 bit, int name_index)
{
	const char *clk_name, *parent_name;
	int ret, index;

	index = of_property_match_string(dev->of_node, "clock-names", parent);
	if (index < 0)
		return ERR_PTR(index);

	parent_name = of_clk_get_parent_name(dev->of_node, index);

	ret = of_property_read_string_index(dev->of_node,
					    "clock-output-names", name_index,
					    &clk_name);
	if (ret)
		return ERR_PTR(ret);

	return clk_hw_register_gate(dev, clk_name, parent_name,
				    CLK_SET_RATE_PARENT,
				    regs + TCON_TOP_GATE_SRC_REG,
				    bit, 0, lock);
};
static int tegra_uart_parse_dt(struct platform_device *pdev,
	struct tegra_uart_port *tup)
{
	struct device_node *np = pdev->dev.of_node;
	int port;
	int index;

	port = of_alias_get_id(np, "serial");
	if (port < 0) {
		dev_err(&pdev->dev, "failed to get alias id, errno %d\n", port);
		return port;
	}
	tup->uport.line = port;

	tup->enable_modem_interrupt = of_property_read_bool(np,
					"nvidia,enable-modem-interrupt");

	index = of_property_match_string(np, "dma-names", "rx");
	if (index < 0) {
		tup->use_rx_pio = true;
		dev_info(&pdev->dev, "RX in PIO mode\n");
	}
	tup->enable_rx_buffer_throttle = of_property_read_bool(np,
			"nvidia,enable-rx-buffer-throttling");
	if (tup->enable_rx_buffer_throttle)
		dev_info(&pdev->dev, "Rx buffer throttling enabled\n");

	return 0;
}
Пример #7
0
static void __init of_selftest_property_match_string(void)
{
	struct device_node *np;
	int rc;

	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
	if (!np) {
		pr_err("No testcase data in device tree\n");
		return;
	}

	rc = of_property_match_string(np, "phandle-list-names", "first");
	selftest(rc == 0, "first expected:0 got:%i\n", rc);
	rc = of_property_match_string(np, "phandle-list-names", "second");
	selftest(rc == 1, "second expected:0 got:%i\n", rc);
	rc = of_property_match_string(np, "phandle-list-names", "third");
	selftest(rc == 2, "third expected:0 got:%i\n", rc);
	rc = of_property_match_string(np, "phandle-list-names", "fourth");
	selftest(rc == -ENODATA, "unmatched string; rc=%i", rc);
	rc = of_property_match_string(np, "missing-property", "blah");
	selftest(rc == -EINVAL, "missing property; rc=%i", rc);
	rc = of_property_match_string(np, "empty-property", "blah");
	selftest(rc == -ENODATA, "empty property; rc=%i", rc);
	rc = of_property_match_string(np, "unterminated-string", "blah");
	selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
}
Пример #8
0
static int dummy_codec_audio_probe(struct platform_device *pdev)
{
    int ret = 0;

    //printk(KERN_DEBUG "enter %s\n", __func__);
    printk("enter %s\n", __func__);
#ifdef CONFIG_USE_OF		
		dummy_codec_pdata = kzalloc(sizeof(struct dummy_codec_platform_data), GFP_KERNEL);
		if(!dummy_codec_pdata){
           // kfree(dummy_codec_pdata);
			return -1;
		}

		if (pdev->dev.of_node) {
            np = pdev->dev.of_node;
            ret = of_property_match_string(np,"status","okay");
            if(ret){
                printk("the platform not register this codec\n");
				goto err1;
            }
		}
		dummy_codec_dev=&pdev->dev;		
    dummy_codec_pdata->device_init = &dummy_codec_device_init;
    dummy_codec_pdata->device_uninit = &dummy_codec_device_deinit;
         
		pdev->dev.platform_data = dummy_codec_pdata;
#endif

    dummy_codec_snd_pdata = pdev->dev.platform_data;
    snd_BUG_ON(!dummy_codec_snd_pdata);
    dummy_codec_snd_device = platform_device_alloc("soc-audio", -1);
    if (!dummy_codec_snd_device) {
        printk(KERN_ERR "ASoC: Platform device allocation failed\n");
        ret = -ENOMEM;
        goto err;
    }

    platform_set_drvdata(dummy_codec_snd_device, &snd_soc_dummy_codec);

    ret = platform_device_add(dummy_codec_snd_device);
    if (ret) {
        printk(KERN_ERR "ASoC: Platform device allocation failed\n");
        goto err_device_add;
    }


    dummy_codec_dev_init();

    return ret;

err_device_add:
    platform_device_put(dummy_codec_snd_device);
err:
err1:
    kfree(dummy_codec_pdata);
    return ret;
}
Пример #9
0
static int stm32_sai_sub_parse_of(struct platform_device *pdev,
				  struct stm32_sai_sub_data *sai)
{
	struct device_node *np = pdev->dev.of_node;
	struct resource *res;
	void __iomem *base;

	if (!np)
		return -ENODEV;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	dev_err(&pdev->dev, "res %pr\n", res);

	base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	sai->phys_addr = res->start;
	sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
					    &stm32_sai_sub_regmap_config);

	/* Get direction property */
	if (of_property_match_string(np, "dma-names", "tx") >= 0) {
		sai->dir = SNDRV_PCM_STREAM_PLAYBACK;
	} else if (of_property_match_string(np, "dma-names", "rx") >= 0) {
		sai->dir = SNDRV_PCM_STREAM_CAPTURE;
	} else {
		dev_err(&pdev->dev, "Unsupported direction\n");
		return -EINVAL;
	}

	sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck");
	if (IS_ERR(sai->sai_ck)) {
		dev_err(&pdev->dev, "missing kernel clock sai_ck\n");
		return PTR_ERR(sai->sai_ck);
	}

	return 0;
}
Пример #10
0
/**
 * of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number
 * @dev: pointer to device tree node
 * @name: irq name
 *
 * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
 * is not yet created, or error code in case of any other failure.
 */
int of_irq_get_byname(struct device_node *dev, const char *name)
{
	int index;

	if (unlikely(!name))
		return -EINVAL;

	index = of_property_match_string(dev, "interrupt-names", name);
	if (index < 0)
		return index;

	return of_irq_get(dev, index);
}
Пример #11
0
static int of_get_dml_pipe_index(struct device_node *np, const char *name)
{
	int index;
	struct of_phandle_args	dma_spec;

	index = of_property_match_string(np, "dma-names", name);

	if (index < 0)
		return -ENODEV;

	if (of_parse_phandle_with_args(np, "dmas", "#dma-cells", index,
				       &dma_spec))
		return -ENODEV;

	if (dma_spec.args_count)
		return dma_spec.args[0];

	return -ENODEV;
}
Пример #12
0
static struct regmap *meson_map_resource(struct meson_pinctrl *pc,
					 struct device_node *node, char *name)
{
	struct resource res;
	void __iomem *base;
	int i;

	i = of_property_match_string(node, "reg-names", name);
	if (of_address_to_resource(node, i, &res))
		return ERR_PTR(-ENOENT);

	base = devm_ioremap_resource(pc->dev, &res);
	if (IS_ERR(base))
		return ERR_CAST(base);

	meson_regmap_config.max_register = resource_size(&res) - 4;
	meson_regmap_config.name = devm_kasprintf(pc->dev, GFP_KERNEL,
						  "%s-%s", node->name,
						  name);
	if (!meson_regmap_config.name)
		return ERR_PTR(-ENOMEM);

	return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config);
}
Пример #13
0
static int pil_mss_loadable_init(struct modem_data *drv,
					struct platform_device *pdev)
{
	struct q6v5_data *q6;
	struct pil_desc *q6_desc;
	struct resource *res;
	struct property *prop;
	int ret;

	q6 = pil_q6v5_init(pdev);
	if (IS_ERR(q6))
		return PTR_ERR(q6);
	drv->q6 = q6;
	drv->xo = q6->xo;

	q6_desc = &q6->desc;
	q6_desc->owner = THIS_MODULE;
	q6_desc->proxy_timeout = PROXY_TIMEOUT_MS;

	q6_desc->ops = &pil_msa_mss_ops;

	q6->self_auth = of_property_read_bool(pdev->dev.of_node,
							"qcom,pil-self-auth");
	if (q6->self_auth) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						    "rmb_base");
		q6->rmb_base = devm_request_and_ioremap(&pdev->dev, res);
		if (!q6->rmb_base)
			return -ENOMEM;
		drv->rmb_base = q6->rmb_base;
		q6_desc->ops = &pil_msa_mss_ops_selfauth;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "restart_reg");
	if (!res) {
		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
							"restart_reg_sec");
		q6->restart_reg_sec = true;
	}

	q6->restart_reg = devm_request_and_ioremap(&pdev->dev, res);
	if (!q6->restart_reg)
		return -ENOMEM;

	q6->vreg = NULL;

	prop = of_find_property(pdev->dev.of_node, "vdd_mss-supply", NULL);
	if (prop) {
		q6->vreg = devm_regulator_get(&pdev->dev, "vdd_mss");
		if (IS_ERR(q6->vreg))
			return PTR_ERR(q6->vreg);

		ret = regulator_set_voltage(q6->vreg, VDD_MSS_UV,
						MAX_VDD_MSS_UV);
		if (ret)
			dev_err(&pdev->dev, "Failed to set vreg voltage.\n");

		ret = regulator_set_optimum_mode(q6->vreg, 100000);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to set vreg mode.\n");
			return ret;
		}
	}

	q6->vreg_mx = devm_regulator_get(&pdev->dev, "vdd_mx");
	if (IS_ERR(q6->vreg_mx))
		return PTR_ERR(q6->vreg_mx);
	prop = of_find_property(pdev->dev.of_node, "vdd_mx-uV", NULL);
	if (!prop) {
		dev_err(&pdev->dev, "Missing vdd_mx-uV property\n");
		return -EINVAL;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
		"cxrail_bhs_reg");
	if (res)
		q6->cxrail_bhs = devm_ioremap(&pdev->dev, res->start,
					  resource_size(res));

	q6->ahb_clk = devm_clk_get(&pdev->dev, "iface_clk");
	if (IS_ERR(q6->ahb_clk))
		return PTR_ERR(q6->ahb_clk);

	q6->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
	if (IS_ERR(q6->axi_clk))
		return PTR_ERR(q6->axi_clk);

	q6->rom_clk = devm_clk_get(&pdev->dev, "mem_clk");
	if (IS_ERR(q6->rom_clk))
		return PTR_ERR(q6->rom_clk);

	/* Optional. */
	if (of_property_match_string(pdev->dev.of_node,
			"qcom,active-clock-names", "gpll0_mss_clk") >= 0)
		q6->gpll0_mss_clk = devm_clk_get(&pdev->dev, "gpll0_mss_clk");

	ret = pil_desc_init(q6_desc);

	return ret;
}
Пример #14
0
/**
 * zynqmp_clk_setup -  Setup the clock framework and register clocks
 * @np:		Device node
 *
 * Return:	Error code on failure
 */
static void __init zynqmp_clk_setup(struct device_node *np)
{
	int i;
	u32 tmp;
	struct clk *clk;
	char *clk_name;
	int idx;

	idx = of_property_match_string(np, "clock-names", "pss_ref_clk");
	if (idx < 0) {
		pr_err("pss_ref_clk not provided\n");
		return;
	}
	input_clks[0] =	of_clk_get_parent_name(np, idx);

	idx = of_property_match_string(np, "clock-names", "video_clk");
	if (idx < 0) {
		pr_err("video_clk not provided\n");
		return;
	}
	input_clks[1] =	of_clk_get_parent_name(np, idx);

	idx = of_property_match_string(np, "clock-names", "pss_alt_ref_clk");
	if (idx < 0) {
		pr_err("pss_alt_ref_clk not provided\n");
		return;
	}
	input_clks[2] =	of_clk_get_parent_name(np, idx);

	idx = of_property_match_string(np, "clock-names", "aux_ref_clk");
	if (idx < 0) {
		pr_err("aux_ref_clk not provided\n");
		return;
	}
	input_clks[3] =	of_clk_get_parent_name(np, idx);

	idx = of_property_match_string(np, "clock-names", "gt_crx_ref_clk");
	if (idx < 0) {
		pr_err("aux_ref_clk not provided\n");
		return;
	}
	input_clks[4] =	of_clk_get_parent_name(np, idx);

	/* get clock output names from DT */
	for (i = 0; i < clk_max; i++) {
		if (of_property_read_string_index(np, "clock-output-names",
				  i, &clk_output_name[i])) {
			pr_err("%s: clock output name not in DT\n", __func__);
			BUG();
		}
	}
	/* APU clocks */
	acpu_parents[0] = clk_output_name[apll];
	acpu_parents[1] = dummy_nm;
	acpu_parents[2] = clk_output_name[dpll];
	acpu_parents[3] = clk_output_name[vpll];

	/* PLL clocks */
	zynqmp_clk_register_pll_clk(apll, clk_output_name[apll],
			CLK_IGNORE_UNUSED,
			(resource_size_t *)CRF_APB_APLL_CTRL,
			(resource_size_t *)CRF_APB_PLL_STATUS, 0);

	zynqmp_clk_register_pll_clk(dpll, clk_output_name[dpll], 0,
			(resource_size_t *)CRF_APB_DPLL_CTRL,
			(resource_size_t *)CRF_APB_PLL_STATUS, 1);

	zynqmp_clk_register_pll_clk(vpll, clk_output_name[vpll],
			CLK_IGNORE_UNUSED,
			(resource_size_t *)CRF_APB_VPLL_CTRL,
			(resource_size_t *)CRF_APB_PLL_STATUS, 2);

	zynqmp_clk_register_pll_clk(iopll, clk_output_name[iopll], 0,
			(resource_size_t *)CRL_APB_IOPLL_CTRL,
			(resource_size_t *)CRL_APB_PLL_STATUS, 0);

	zynqmp_clk_register_pll_clk(rpll, clk_output_name[rpll], 0,
			(resource_size_t *)CRL_APB_RPLL_CTRL,
			(resource_size_t *)CRL_APB_PLL_STATUS, 1);

	/* Domain crossing PLL clock dividers */
	clks[apll_to_lpd] = zynqmp_clk_register_divider(NULL, "apll_to_lpd",
			clk_output_name[apll], 0,
			(resource_size_t *)CRF_APB_APLL_TO_LPD_CTRL, 8,
			6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clks[dpll_to_lpd] = zynqmp_clk_register_divider(NULL, "dpll_to_lpd",
			clk_output_name[dpll], 0,
			(resource_size_t *)CRF_APB_DPLL_TO_LPD_CTRL, 8,
			6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clks[vpll_to_lpd] = zynqmp_clk_register_divider(NULL, "vpll_to_lpd",
			clk_output_name[vpll], 0,
			(resource_size_t *)CRF_APB_VPLL_TO_LPD_CTRL, 8,
			6,  CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clks[iopll_to_fpd] = zynqmp_clk_register_divider(NULL, "iopll_to_fpd",
			clk_output_name[iopll], 0,
			(resource_size_t *)CRL_APB_IOPLL_TO_FPD_CTRL,
			8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clks[rpll_to_fpd] = zynqmp_clk_register_divider(NULL, "rpll_to_fpd",
			clk_output_name[rpll], 0,
			(resource_size_t *)CRL_APB_RPLL_TO_FPD_CTRL, 8,
			6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clk = zynqmp_clk_register_mux(NULL, "acpu_mux", acpu_parents, 4,
			CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRF_APB_ACPU_CTRL, 0, 3, 0);

	clk = zynqmp_clk_register_divider(NULL, "acpu_div0", "acpu_mux", 0,
			(resource_size_t *)CRF_APB_ACPU_CTRL, 8, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clks[acpu] = zynqmp_clk_register_gate(NULL, clk_output_name[acpu],
			"acpu_div0", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
			(resource_size_t *)CRF_APB_ACPU_CTRL, 24, 0);

	clk_prepare_enable(clks[acpu]);

	clk = clk_register_fixed_factor(NULL, "acpu_half_div", "acpu_div0", 0,
			1, 2);

	clks[acpu_half] = zynqmp_clk_register_gate(NULL,
			clk_output_name[acpu_half], "acpu_half_div",
			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
			(resource_size_t *)CRF_APB_ACPU_CTRL, 25, 0);

	/* Timers */
	/* The first parent clock source will be changed in the future.
	 * Currently, using the acpu clock as the parent based on the
	 * assumption that it comes from APB.
	 */
	wdt_ext_clk_mux_parents[0] = clk_output_name[acpu];
	for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				swdt_ext_clk_input_names[i]);
		if (idx >= 0)
			wdt_ext_clk_mux_parents[i + 1] =
				of_clk_get_parent_name(np, idx);
		else
			wdt_ext_clk_mux_parents[i + 1] = dummy_nm;
	}
	clks[wdt] = zynqmp_clk_register_mux(NULL, clk_output_name[wdt],
			wdt_ext_clk_mux_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_WDT_CLK_SEL, 0, 1, 0);

	/* DDR clocks */
	ddr_parents[0] = clk_output_name[dpll];
	ddr_parents[1] = clk_output_name[vpll];

	clk = zynqmp_clk_register_mux(NULL, "ddr_mux", ddr_parents, 2,
			CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRF_APB_DDR_CTRL, 0, 3, 0);

	clks[ddr_ref] = zynqmp_clk_register_divider(NULL,
			clk_output_name[ddr_ref],
			"ddr_mux", 0, (resource_size_t *)CRF_APB_DDR_CTRL, 8, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clk_prepare_enable(clks[ddr_ref]);

	/* Peripheral clock parents */
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_trace],
					iopll_to_fpd, dpll, apll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_fpd],
					iopll_to_fpd, dpll, apll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_lpd],
					rpll, iopll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_tstmp],
					iopll_to_fpd, dpll, apll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_video_ref],
					vpll, dpll, rpll_to_fpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_audio_ref],
					vpll, dpll, rpll_to_fpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dp_stc_ref],
					vpll, dpll, rpll_to_fpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gpu_ref],
					iopll_to_fpd, vpll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[sata_ref],
					iopll_to_fpd, apll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[pcie_ref],
					iopll_to_fpd, rpll_to_fpd, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gdma_ref],
					apll, vpll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[dpdma_ref],
					apll, vpll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[topsw_main],
					apll, vpll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[topsw_lsbus],
					apll, iopll_to_fpd, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gtgref0_ref],
					iopll_to_fpd, apll, dpll);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[usb3_dual_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[usb0_bus_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[usb1_bus_ref],
					iopll, apll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gem0_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gem1_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gem2_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gem3_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[qspi_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[sdio0_ref],
					iopll, rpll, vpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[sdio1_ref],
					iopll, rpll, vpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[uart0_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[uart1_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[spi0_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[spi1_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[can0_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[can1_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[cpu_r5],
					rpll, iopll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[iou_switch],
					rpll, iopll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[csu_pll],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[pcap],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[lpd_switch],
					rpll, iopll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[lpd_lsbus],
					rpll, iopll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[nand_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[adma_ref],
					rpll, iopll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[gem_tsu_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[ams_ref],
					rpll, iopll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[i2c0_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[i2c1_ref],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[pl0],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[pl1],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[pl2],
					iopll, rpll, dpll_to_lpd);
	zynqmp_clk_get_parents(clk_output_name, periph_parents[pl3],
					iopll, rpll, dpll_to_lpd);

	/* PL clocks */
	zynqmp_clk_register_pl_clk(pl0, clk_output_name[pl0],
			(resource_size_t *)CRL_APB_PL0_REF_CTRL,
			periph_parents[pl0]);
	zynqmp_clk_register_pl_clk(pl1, clk_output_name[pl1],
			(resource_size_t *)CRL_APB_PL1_REF_CTRL,
			periph_parents[pl1]);
	zynqmp_clk_register_pl_clk(pl2, clk_output_name[pl2],
			(resource_size_t *)CRL_APB_PL2_REF_CTRL,
			periph_parents[pl2]);
	zynqmp_clk_register_pl_clk(pl3, clk_output_name[pl3],
			(resource_size_t *)CRL_APB_PL3_REF_CTRL,
			periph_parents[pl3]);

	/* Peripheral clock */
	zynqmp_clk_register_periph_clk(dbg_trace, clk_output_name[dbg_trace],
			CRF_APB_DBG_TRACE_CTRL, periph_parents[dbg_trace], 1,
			0, 24);

	zynqmp_clk_get_parents(clk_output_name, periph_parents[dbg_fpd],
					iopll_to_fpd, dpll, apll);
	zynqmp_clk_register_periph_clk(dbg_fpd, clk_output_name[dbg_fpd],
			CRF_APB_DBG_FPD_CTRL, periph_parents[dbg_fpd], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(dbg_lpd, clk_output_name[dbg_lpd],
			CRL_APB_DBG_LPD_CTRL, periph_parents[dbg_lpd], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(dbg_tstmp, clk_output_name[dbg_tstmp],
			CRF_APB_DBG_TSTMP_CTRL, periph_parents[dbg_tstmp], 0,
			0, 0);

	zynqmp_clk_register_periph_clk(dp_video_ref,
			clk_output_name[dp_video_ref],
			CRF_APB_DP_VIDEO_REF_CTRL,
			periph_parents[dp_video_ref], 1, 1, 24);

	zynqmp_clk_register_periph_clk(dp_audio_ref,
			clk_output_name[dp_audio_ref],
			CRF_APB_DP_AUDIO_REF_CTRL,
			periph_parents[dp_audio_ref], 1, 1, 24);

	zynqmp_clk_register_periph_clk(dp_stc_ref,
			clk_output_name[dp_stc_ref], CRF_APB_DP_STC_REF_CTRL,
			periph_parents[dp_stc_ref], 1, 1, 24);

	zynqmp_clk_register_periph_clk(gpu_ref, clk_output_name[gpu_ref],
			CRF_APB_GPU_REF_CTRL, periph_parents[gpu_ref], 1, 0,
			24);
	clks[gpu_pp0_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[gpu_pp0_ref], "gpu_ref_div0",
			CLK_SET_RATE_PARENT,
			(resource_size_t *)CRF_APB_GPU_REF_CTRL, 25, 0);
	clks[gpu_pp1_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[gpu_pp1_ref], "gpu_ref_div0",
			CLK_SET_RATE_PARENT,
			(resource_size_t *)CRF_APB_GPU_REF_CTRL, 26, 0);

	zynqmp_clk_register_periph_clk(sata_ref, clk_output_name[sata_ref],
			CRF_APB_SATA_REF_CTRL, periph_parents[sata_ref], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(pcie_ref, clk_output_name[pcie_ref],
			CRF_APB_PCIE_REF_CTRL, periph_parents[pcie_ref], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(gdma_ref, clk_output_name[gdma_ref],
			CRF_APB_GDMA_REF_CTRL, periph_parents[gdma_ref], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(dpdma_ref, clk_output_name[dpdma_ref],
			CRF_APB_DPDMA_REF_CTRL, periph_parents[dpdma_ref], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(topsw_main, clk_output_name[topsw_main],
			CRF_APB_TOPSW_MAIN_CTRL, periph_parents[topsw_main],
			CLK_IGNORE_UNUSED, 0, 24);

	zynqmp_clk_register_periph_clk(topsw_lsbus,
			clk_output_name[topsw_lsbus], CRF_APB_TOPSW_LSBUS_CTRL,
			periph_parents[topsw_lsbus], CLK_IGNORE_UNUSED, 0, 24);

	zynqmp_clk_register_periph_clk(gtgref0_ref,
			clk_output_name[gtgref0_ref], CRF_APB_GTGREF0_REF_CTRL,
			periph_parents[gtgref0_ref], 1, 0, 24);

	zynqmp_clk_register_periph_clk(usb3_dual_ref,
			clk_output_name[usb3_dual_ref],
			CRL_APB_USB3_DUAL_REF_CTRL,
			periph_parents[usb3_dual_ref], 1, 1, 25);

	zynqmp_clk_register_periph_clk(usb0_bus_ref,
			clk_output_name[usb0_bus_ref],
			CRL_APB_USB0_BUS_REF_CTRL,
			periph_parents[usb0_bus_ref], 1, 1, 25);

	clks[usb0] = zynqmp_clk_register_mux(NULL, clk_output_name[usb0],
			usb0_mio_mux_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_USB0_BUS_REF_CTRL, 2, 1, 0);

	zynqmp_clk_register_periph_clk(usb1_bus_ref,
			clk_output_name[usb1_bus_ref],
			CRL_APB_USB1_BUS_REF_CTRL,
			periph_parents[usb1_bus_ref], 1, 1, 25);
	clks[usb1] = zynqmp_clk_register_mux(NULL, clk_output_name[usb1],
			usb1_mio_mux_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_USB1_BUS_REF_CTRL, 2, 1, 0);

	/* Ethernet clocks */
	for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				gem0_emio_input_names[i]);
		if (idx >= 0)
			gem0_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}
	clk = zynqmp_clk_register_mux(NULL, "gem0_ref_mux",
			periph_parents[gem0_ref], 4, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_GEM0_REF_CTRL, 0, 3, 0);
	clk = zynqmp_clk_register_divider(NULL, "gem0_ref_div0", "gem0_ref_mux",
			0, (resource_size_t *)CRL_APB_GEM0_REF_CTRL, 8, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_divider(NULL, "gem0_ref_div1",
			"gem0_ref_div0", 0,
			(resource_size_t *)CRL_APB_GEM0_REF_CTRL, 16, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);

	clk = zynqmp_clk_register_mux(NULL, "gem0_tx_mux", gem0_tx_mux_parents,
			2, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 1, 1, 0);
	clks[gem0_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem0_rx],
			"gem0_tx_mux",
			CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM0_REF_CTRL, 26, 0);
	clks[gem0_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[gem0_ref],
			"gem0_ref_div1", CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM0_REF_CTRL, 25, 0);


	for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				gem1_emio_input_names[i]);
		if (idx >= 0)
			gem1_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}

	clk = zynqmp_clk_register_mux(NULL, "gem1_ref_mux",
			periph_parents[gem1_ref],
			4, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_GEM1_REF_CTRL, 0, 3, 0);
	clk = zynqmp_clk_register_divider(NULL, "gem1_ref_div0", "gem1_ref_mux",
			0, (resource_size_t *)CRL_APB_GEM1_REF_CTRL, 8, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_divider(NULL, "gem1_ref_div1",
			"gem1_ref_div0", 0,
			(resource_size_t *)CRL_APB_GEM1_REF_CTRL, 16, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_mux(NULL, "gem1_tx_mux", gem1_tx_mux_parents,
			2, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 6, 1,	0);
	clks[gem1_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem1_rx],
			"gem1_tx_mux", CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM1_REF_CTRL, 26, 0);
	clks[gem1_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[gem1_ref], "gem1_ref_div1",
			CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM1_REF_CTRL, 25, 0);


	for (i = 0; i < ARRAY_SIZE(gem2_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				gem2_emio_input_names[i]);
		if (idx >= 0)
			gem2_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}
	clk = zynqmp_clk_register_mux(NULL, "gem2_ref_mux",
			periph_parents[gem2_ref], 4, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_GEM2_REF_CTRL, 0, 3, 0);
	clk = zynqmp_clk_register_divider(NULL, "gem2_ref_div0",
			"gem2_ref_mux", 0,
			(resource_size_t *)CRL_APB_GEM2_REF_CTRL, 8, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_divider(NULL, "gem2_ref_div1",
			"gem2_ref_div0", 0,
			(resource_size_t *)CRL_APB_GEM2_REF_CTRL, 16, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_mux(NULL, "gem2_tx_mux", gem2_tx_mux_parents,
			2, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 11, 1, 0);
	clks[gem2_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem2_rx],
			"gem2_tx_mux", CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM2_REF_CTRL, 26, 0);
	clks[gem2_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[gem2_ref], "gem2_ref_div1",
			CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM2_REF_CTRL, 25, 0);


	for (i = 0; i < ARRAY_SIZE(gem3_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				gem3_emio_input_names[i]);
		if (idx >= 0)
			gem3_tx_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}

	clk = zynqmp_clk_register_mux(NULL, "gem3_ref_mux",
			periph_parents[gem3_ref], 4, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_GEM3_REF_CTRL, 0,
			3, 0);
	clk = zynqmp_clk_register_divider(NULL, "gem3_ref_div0",
			"gem3_ref_mux", 0,
			(resource_size_t *)CRL_APB_GEM3_REF_CTRL, 8, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_divider(NULL, "gem3_ref_div1",
			"gem3_ref_div0", CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM3_REF_CTRL, 16, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clk = zynqmp_clk_register_mux(NULL, "gem3_tx_mux", gem3_tx_mux_parents,
			2, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 16, 1, 0);
	clks[gem3_rx] = zynqmp_clk_register_gate(NULL, clk_output_name[gem3_rx],
			"gem3_tx_mux", CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM3_REF_CTRL, 26, 0);
	clks[gem3_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[gem3_ref], "gem3_ref_div1",
			CLK_SET_RATE_PARENT,
			(resource_size_t *)CRL_APB_GEM3_REF_CTRL, 25, 0);

	gem_tsu_mux_parents[0] = clk_output_name[gem_tsu_ref];
	gem_tsu_mux_parents[1] = clk_output_name[gem_tsu_ref];
	gem_tsu_mux_parents[2] = "mio_clk_26";
	gem_tsu_mux_parents[3] = "mio_clk_50_or_51";

	zynqmp_clk_register_periph_clk(gem_tsu_ref,
			clk_output_name[gem_tsu_ref], CRL_APB_GEM_TSU_REF_CTRL,
			periph_parents[gem_tsu_ref], 1, 1, 24);

	clks[gem_tsu] = zynqmp_clk_register_mux(NULL, clk_output_name[gem_tsu],
			gem_tsu_mux_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_GEM_CLK_CTRL, 20, 2, 0);

	zynqmp_clk_register_periph_clk(qspi_ref, clk_output_name[qspi_ref],
			CRL_APB_QSPI_REF_CTRL, periph_parents[qspi_ref], 1, 1,
			24);

	zynqmp_clk_register_periph_clk(sdio0_ref, clk_output_name[sdio0_ref],
			CRL_APB_SDIO0_REF_CTRL, periph_parents[sdio0_ref], 1,
			1, 24);

	zynqmp_clk_register_periph_clk(sdio1_ref, clk_output_name[sdio1_ref],
			CRL_APB_SDIO1_REF_CTRL, periph_parents[sdio1_ref], 1,
			1, 24);

	zynqmp_clk_register_periph_clk(uart0_ref, clk_output_name[uart0_ref],
			CRL_APB_UART0_REF_CTRL, periph_parents[uart0_ref], 1,
			1, 24);

	zynqmp_clk_register_periph_clk(uart1_ref, clk_output_name[uart1_ref],
			CRL_APB_UART1_REF_CTRL, periph_parents[uart1_ref], 1,
			1, 24);

	zynqmp_clk_register_periph_clk(spi0_ref, clk_output_name[spi0_ref],
			CRL_APB_SPI0_REF_CTRL, periph_parents[spi0_ref], 1, 1,
			24);

	zynqmp_clk_register_periph_clk(spi1_ref, clk_output_name[spi1_ref],
			CRL_APB_SPI1_REF_CTRL, periph_parents[spi1_ref], 1, 1,
			24);

	tmp = strlen("mio_clk_00x");
	clk_name = kmalloc(tmp, GFP_KERNEL);
	for (i = 0; i < NUM_MIO_PINS; i++) {
		int idx;

		snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
		idx = of_property_match_string(np, "clock-names", clk_name);
		if (idx >= 0)
			can_mio_mux_parents[i] = of_clk_get_parent_name(np,
						idx);
		else
			can_mio_mux_parents[i] = dummy_nm;
	}
	kfree(clk_name);
	zynqmp_clk_register_periph_clk(can0_ref, clk_output_name[can0_ref],
			CRL_APB_CAN0_REF_CTRL, periph_parents[can0_ref], 1, 1,
			24);
	clk = zynqmp_clk_register_mux(NULL, "can0_mio_mux",
			can_mio_mux_parents, NUM_MIO_PINS,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 0, 7, 0);
	clks[can0] = zynqmp_clk_register_mux(NULL, clk_output_name[can0],
			can0_mio_mux2_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 7, 1, 0);

	zynqmp_clk_register_periph_clk(can1_ref, clk_output_name[can1_ref],
			CRL_APB_CAN1_REF_CTRL, periph_parents[can1_ref], 1, 1,
			24);
	clk = zynqmp_clk_register_mux(NULL, "can1_mio_mux",
			can_mio_mux_parents, NUM_MIO_PINS,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 15, 7, 0);
	clks[can1] = zynqmp_clk_register_mux(NULL, clk_output_name[can1],
			can1_mio_mux2_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)IOU_SLCR_CAN_MIO_CTRL, 22, 1, 0);

	zynqmp_clk_register_periph_clk(cpu_r5, clk_output_name[cpu_r5],
			CRL_APB_CPU_R5_CTRL, periph_parents[cpu_r5],
			CLK_IGNORE_UNUSED, 0, 24);
	clk = zynqmp_clk_register_gate(NULL, "cpu_r5_core_gate", "cpu_r5_div0",
			CLK_IGNORE_UNUSED,
			(resource_size_t *)CRL_APB_CPU_R5_CTRL, 25, 0);

	zynqmp_clk_register_periph_clk(iou_switch, clk_output_name[iou_switch],
			CRL_APB_IOU_SWITCH_CTRL, periph_parents[iou_switch],
			CLK_IGNORE_UNUSED, 0, 24);

	zynqmp_clk_register_periph_clk(csu_pll, clk_output_name[csu_pll],
			CRL_APB_CSU_PLL_CTRL, periph_parents[csu_pll], 1, 0,
			24);

	zynqmp_clk_register_periph_clk(pcap, clk_output_name[pcap],
			CRL_APB_PCAP_CTRL, periph_parents[pcap], 1, 0, 24);

	zynqmp_clk_register_periph_clk(lpd_switch, clk_output_name[lpd_switch],
			CRL_APB_LPD_SWITCH_CTRL, periph_parents[lpd_switch],
			CLK_IGNORE_UNUSED, 0, 24);

	zynqmp_clk_register_periph_clk(lpd_lsbus, clk_output_name[lpd_lsbus],
			CRL_APB_LPD_LSBUS_CTRL, periph_parents[lpd_lsbus],
			CLK_IGNORE_UNUSED, 0, 24);

	zynqmp_clk_register_periph_clk(nand_ref, clk_output_name[nand_ref],
			CRL_APB_NAND_REF_CTRL, periph_parents[nand_ref], 1, 1,
			24);

	zynqmp_clk_register_periph_clk(adma_ref, clk_output_name[adma_ref],
			CRL_APB_ADMA_REF_CTRL, periph_parents[adma_ref], 1, 0,
			24);

	dll_ref_parents[0] = clk_output_name[iopll];
	dll_ref_parents[1] = clk_output_name[rpll];
	clks[dll_ref] = zynqmp_clk_register_mux(NULL, clk_output_name[dll_ref],
				dll_ref_parents, 2,
				CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
				(resource_size_t *)CRL_APB_DLL_REF_CTRL,
				0, 3, 0);

	zynqmp_clk_register_periph_clk(ams_ref, clk_output_name[ams_ref],
			CRL_APB_AMS_REF_CTRL, periph_parents[ams_ref], 1, 1,
			24);

	zynqmp_clk_register_periph_clk(i2c0_ref, clk_output_name[i2c0_ref],
			CRL_APB_I2C0_REF_CTRL, periph_parents[i2c0_ref], 1,
			1, 24);

	zynqmp_clk_register_periph_clk(i2c1_ref, clk_output_name[i2c1_ref],
			CRL_APB_I2C1_REF_CTRL, periph_parents[i2c1_ref], 1,
			1, 24);

	timestamp_ref_parents[0] = clk_output_name[rpll];
	timestamp_ref_parents[1] = dummy_nm;
	timestamp_ref_parents[2] = clk_output_name[iopll];
	timestamp_ref_parents[3] = clk_output_name[dpll_to_lpd];
	timestamp_ref_parents[4] = input_clks[0];
	timestamp_ref_parents[5] = input_clks[0];
	timestamp_ref_parents[6] = input_clks[0];
	timestamp_ref_parents[7] = input_clks[0];
	clk = zynqmp_clk_register_mux(NULL, "timestamp_ref_mux",
			timestamp_ref_parents, 8, CLK_SET_RATE_NO_REPARENT,
			(resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL, 0, 3, 0);
	clk = zynqmp_clk_register_divider(NULL, "timestamp_ref_div0",
			"timestamp_ref_mux", 0,
			(resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL,
			8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO);
	clks[timestamp_ref] = zynqmp_clk_register_gate(NULL,
			clk_output_name[timestamp_ref], "timestamp_ref_div0",
			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
			(resource_size_t *)CRL_APB_TIMESTAMP_REF_CTRL, 24, 0);

	for (i = 0; i < ARRAY_SIZE(clks); i++) {
		if (IS_ERR(clks[i])) {
			pr_err("Zynq Ultrascale+ MPSoC clk %d: register failed with %ld\n",
			       i, PTR_ERR(clks[i]));
			BUG();
		}
	}

	clk_data.clks = clks;
	clk_data.clk_num = ARRAY_SIZE(clks);
	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
Пример #15
0
static void __init zynq_clk_setup(struct device_node *np)
{
	int i;
	u32 tmp;
	int ret;
	struct clk *clk;
	char *clk_name;
	unsigned int fclk_enable = 0;
	const char *clk_output_name[clk_max];
	const char *cpu_parents[4];
	const char *periph_parents[4];
	const char *swdt_ext_clk_mux_parents[2];
	const char *can_mio_mux_parents[NUM_MIO_PINS];

	pr_info("Zynq clock init\n");

	/* get clock output names from DT */
	for (i = 0; i < clk_max; i++) {
		if (of_property_read_string_index(np, "clock-output-names",
				  i, &clk_output_name[i])) {
			pr_err("%s: clock output name not in DT\n", __func__);
			BUG();
		}
	}
	cpu_parents[0] = clk_output_name[armpll];
	cpu_parents[1] = clk_output_name[armpll];
	cpu_parents[2] = clk_output_name[ddrpll];
	cpu_parents[3] = clk_output_name[iopll];
	periph_parents[0] = clk_output_name[iopll];
	periph_parents[1] = clk_output_name[iopll];
	periph_parents[2] = clk_output_name[armpll];
	periph_parents[3] = clk_output_name[ddrpll];

	of_property_read_u32(np, "fclk-enable", &fclk_enable);

	/* ps_clk */
	ret = of_property_read_u32(np, "ps-clk-frequency", &tmp);
	if (ret) {
		pr_warn("ps_clk frequency not specified, using 33 MHz.\n");
		tmp = 33333333;
	}
	ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT,
			tmp);

	ret = of_property_read_u32(np, "fclk-enable", &fclk_enable);
	if (ret)
		fclk_enable = 0xf;

	/* PLLs */
	clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL,
			SLCR_PLL_STATUS, 0, &armpll_lock);
	clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll],
			armpll_parents, 2, CLK_SET_RATE_NO_REPARENT,
			SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock);

	clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL,
			SLCR_PLL_STATUS, 1, &ddrpll_lock);
	clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll],
			ddrpll_parents, 2, CLK_SET_RATE_NO_REPARENT,
			SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock);

	clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL,
			SLCR_PLL_STATUS, 2, &iopll_lock);
	clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll],
			iopll_parents, 2, CLK_SET_RATE_NO_REPARENT,
			SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock);

	/* CPU clocks */
	tmp = readl(SLCR_621_TRUE) & 1;
	clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4,
			CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0,
			&armclk_lock);
	clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0,
			SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &armclk_lock);

	clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x],
			"cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
			SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock);

	clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0,
			1, 2);
	clks[cpu_3or2x] = clk_register_gate(NULL, clk_output_name[cpu_3or2x],
			"cpu_3or2x_div", CLK_IGNORE_UNUSED,
			SLCR_ARM_CLK_CTRL, 25, 0, &armclk_lock);

	clk = clk_register_fixed_factor(NULL, "cpu_2x_div", "cpu_div", 0, 1,
			2 + tmp);
	clks[cpu_2x] = clk_register_gate(NULL, clk_output_name[cpu_2x],
			"cpu_2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL,
			26, 0, &armclk_lock);

	clk = clk_register_fixed_factor(NULL, "cpu_1x_div", "cpu_div", 0, 1,
			4 + 2 * tmp);
	clks[cpu_1x] = clk_register_gate(NULL, clk_output_name[cpu_1x],
			"cpu_1x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 27,
			0, &armclk_lock);

	/* Timers */
	swdt_ext_clk_mux_parents[0] = clk_output_name[cpu_1x];
	for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				swdt_ext_clk_input_names[i]);
		if (idx >= 0)
			swdt_ext_clk_mux_parents[i + 1] =
				of_clk_get_parent_name(np, idx);
		else
			swdt_ext_clk_mux_parents[i + 1] = dummy_nm;
	}
	clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt],
			swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT |
			CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0,
			&swdtclk_lock);

	/* DDR clocks */
	clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0,
			SLCR_DDR_CLK_CTRL, 26, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
	clks[ddr2x] = clk_register_gate(NULL, clk_output_name[ddr2x],
			"ddr2x_div", 0, SLCR_DDR_CLK_CTRL, 1, 0, &ddrclk_lock);
	clk_prepare_enable(clks[ddr2x]);
	clk = clk_register_divider(NULL, "ddr3x_div", "ddrpll", 0,
			SLCR_DDR_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
	clks[ddr3x] = clk_register_gate(NULL, clk_output_name[ddr3x],
			"ddr3x_div", 0, SLCR_DDR_CLK_CTRL, 0, 0, &ddrclk_lock);
	clk_prepare_enable(clks[ddr3x]);

	clk = clk_register_divider(NULL, "dci_div0", "ddrpll", 0,
			SLCR_DCI_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock);
	clk = clk_register_divider(NULL, "dci_div1", "dci_div0",
			CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 20, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
			&dciclk_lock);
	clks[dci] = clk_register_gate(NULL, clk_output_name[dci], "dci_div1",
			CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 0, 0,
			&dciclk_lock);
	clk_prepare_enable(clks[dci]);

	/* Peripheral clocks */
	for (i = fclk0; i <= fclk3; i++) {
		int enable = !!(fclk_enable & BIT(i - fclk0));
		zynq_clk_register_fclk(i, clk_output_name[i],
				SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0),
				periph_parents, enable);
	}

	zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL,
			SLCR_LQSPI_CLK_CTRL, periph_parents, 0);

	zynq_clk_register_periph_clk(smc, 0, clk_output_name[smc], NULL,
			SLCR_SMC_CLK_CTRL, periph_parents, 0);

	zynq_clk_register_periph_clk(pcap, 0, clk_output_name[pcap], NULL,
			SLCR_PCAP_CLK_CTRL, periph_parents, 0);

	zynq_clk_register_periph_clk(sdio0, sdio1, clk_output_name[sdio0],
			clk_output_name[sdio1], SLCR_SDIO_CLK_CTRL,
			periph_parents, 1);

	zynq_clk_register_periph_clk(uart0, uart1, clk_output_name[uart0],
			clk_output_name[uart1], SLCR_UART_CLK_CTRL,
			periph_parents, 1);

	zynq_clk_register_periph_clk(spi0, spi1, clk_output_name[spi0],
			clk_output_name[spi1], SLCR_SPI_CLK_CTRL,
			periph_parents, 1);

	for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				gem0_emio_input_names[i]);
		if (idx >= 0)
			gem0_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}
	clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4,
			CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 4, 2, 0,
			&gem0clk_lock);
	clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0,
			SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock);
	clk = clk_register_divider(NULL, "gem0_div1", "gem0_div0",
			CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
			&gem0clk_lock);
	clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			SLCR_GEM0_CLK_CTRL, 6, 1, 0,
			&gem0clk_lock);
	clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0],
			"gem0_emio_mux", CLK_SET_RATE_PARENT,
			SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock);

	for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				gem1_emio_input_names[i]);
		if (idx >= 0)
			gem1_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}
	clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4,
			CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 4, 2, 0,
			&gem1clk_lock);
	clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0,
			SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock);
	clk = clk_register_divider(NULL, "gem1_div1", "gem1_div0",
			CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
			&gem1clk_lock);
	clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2,
			CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
			SLCR_GEM1_CLK_CTRL, 6, 1, 0,
			&gem1clk_lock);
	clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1],
			"gem1_emio_mux", CLK_SET_RATE_PARENT,
			SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);

	tmp = strlen("mio_clk_00x");
	clk_name = kmalloc(tmp, GFP_KERNEL);
	for (i = 0; i < NUM_MIO_PINS; i++) {
		int idx;

		snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
		idx = of_property_match_string(np, "clock-names", clk_name);
		if (idx >= 0)
			can_mio_mux_parents[i] = of_clk_get_parent_name(np,
						idx);
		else
			can_mio_mux_parents[i] = dummy_nm;
	}
	kfree(clk_name);
	clk = clk_register_mux(NULL, "can_mux", periph_parents, 4,
			CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0,
			&canclk_lock);
	clk = clk_register_divider(NULL, "can_div0", "can_mux", 0,
			SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &canclk_lock);
	clk = clk_register_divider(NULL, "can_div1", "can_div0",
			CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 20, 6,
			CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
			&canclk_lock);
	clk = clk_register_gate(NULL, "can0_gate", "can_div1",
			CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 0, 0,
			&canclk_lock);
	clk = clk_register_gate(NULL, "can1_gate", "can_div1",
			CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0,
			&canclk_lock);
	clk = clk_register_mux(NULL, "can0_mio_mux",
			can_mio_mux_parents, 54, CLK_SET_RATE_PARENT |
			CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0,
			&canmioclk_lock);
	clk = clk_register_mux(NULL, "can1_mio_mux",
			can_mio_mux_parents, 54, CLK_SET_RATE_PARENT |
			CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6,
			0, &canmioclk_lock);
	clks[can0] = clk_register_mux(NULL, clk_output_name[can0],
			can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT |
			CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0,
			&canmioclk_lock);
	clks[can1] = clk_register_mux(NULL, clk_output_name[can1],
			can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT |
			CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1,
			0, &canmioclk_lock);

	for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) {
		int idx = of_property_match_string(np, "clock-names",
				dbgtrc_emio_input_names[i]);
		if (idx >= 0)
			dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np,
					idx);
	}
	clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4,
			CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 4, 2, 0,
			&dbgclk_lock);
	clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0,
			SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
			CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock);
	clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2,
			CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 6, 1, 0,
			&dbgclk_lock);
	clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc],
			"dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL,
			0, 0, &dbgclk_lock);
	clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb],
			clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0,
			&dbgclk_lock);

	/* leave debug clocks in the state the bootloader set them up to */
	tmp = clk_readl(SLCR_DBG_CLK_CTRL);
	if (tmp & DBG_CLK_CTRL_CLKACT_TRC)
		if (clk_prepare_enable(clks[dbg_trc]))
			pr_warn("%s: trace clk enable failed\n", __func__);
	if (tmp & DBG_CLK_CTRL_CPU_1XCLKACT)
		if (clk_prepare_enable(clks[dbg_apb]))
			pr_warn("%s: debug APB clk enable failed\n", __func__);

	/* One gated clock for all APER clocks. */
	clks[dma] = clk_register_gate(NULL, clk_output_name[dma],
			clk_output_name[cpu_2x], 0, SLCR_APER_CLK_CTRL, 0, 0,
			&aperclk_lock);
	clks[usb0_aper] = clk_register_gate(NULL, clk_output_name[usb0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 2, 0,
			&aperclk_lock);
	clks[usb1_aper] = clk_register_gate(NULL, clk_output_name[usb1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 3, 0,
			&aperclk_lock);
	clks[gem0_aper] = clk_register_gate(NULL, clk_output_name[gem0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 6, 0,
			&aperclk_lock);
	clks[gem1_aper] = clk_register_gate(NULL, clk_output_name[gem1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 7, 0,
			&aperclk_lock);
	clks[sdio0_aper] = clk_register_gate(NULL, clk_output_name[sdio0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 10, 0,
			&aperclk_lock);
	clks[sdio1_aper] = clk_register_gate(NULL, clk_output_name[sdio1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 11, 0,
			&aperclk_lock);
	clks[spi0_aper] = clk_register_gate(NULL, clk_output_name[spi0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 14, 0,
			&aperclk_lock);
	clks[spi1_aper] = clk_register_gate(NULL, clk_output_name[spi1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 15, 0,
			&aperclk_lock);
	clks[can0_aper] = clk_register_gate(NULL, clk_output_name[can0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 16, 0,
			&aperclk_lock);
	clks[can1_aper] = clk_register_gate(NULL, clk_output_name[can1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 17, 0,
			&aperclk_lock);
	clks[i2c0_aper] = clk_register_gate(NULL, clk_output_name[i2c0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 18, 0,
			&aperclk_lock);
	clks[i2c1_aper] = clk_register_gate(NULL, clk_output_name[i2c1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 19, 0,
			&aperclk_lock);
	clks[uart0_aper] = clk_register_gate(NULL, clk_output_name[uart0_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 20, 0,
			&aperclk_lock);
	clks[uart1_aper] = clk_register_gate(NULL, clk_output_name[uart1_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 21, 0,
			&aperclk_lock);
	clks[gpio_aper] = clk_register_gate(NULL, clk_output_name[gpio_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 22, 0,
			&aperclk_lock);
	clks[lqspi_aper] = clk_register_gate(NULL, clk_output_name[lqspi_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 23, 0,
			&aperclk_lock);
	clks[smc_aper] = clk_register_gate(NULL, clk_output_name[smc_aper],
			clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 24, 0,
			&aperclk_lock);

	for (i = 0; i < ARRAY_SIZE(clks); i++) {
		if (IS_ERR(clks[i])) {
			pr_err("Zynq clk %d: register failed with %ld\n",
			       i, PTR_ERR(clks[i]));
			BUG();
		}
	}

	clk_data.clks = clks;
	clk_data.clk_num = ARRAY_SIZE(clks);
	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
static int dummy_codec_audio_probe(struct platform_device *pdev)
{
    int ret = 0;
		struct snd_soc_card *card = &snd_soc_dummy_codec;

    //printk(KERN_DEBUG "enter %s\n", __func__);
    printk("enter %s\n", __func__);
#ifdef CONFIG_USE_OF
		dummy_codec_pdata = kzalloc(sizeof(struct dummy_codec_platform_data), GFP_KERNEL);
		if(!dummy_codec_pdata){
           // kfree(dummy_codec_pdata);
			return -1;
		}

		if (pdev->dev.of_node) {
            np = pdev->dev.of_node;
            ret = of_property_match_string(np,"status","okay");
            if(ret){
                printk("the platform not register this codec\n");
				goto err1;
            }
		}
		dummy_codec_dev=&pdev->dev;
    dummy_codec_pdata->device_init = &dummy_codec_device_init;
    dummy_codec_pdata->device_uninit = &dummy_codec_device_deinit;

		pdev->dev.platform_data = dummy_codec_pdata;
		dummy_codec_snd_pdata = pdev->dev.platform_data;
#endif

#if 1
    card->dev = &pdev->dev;
		platform_set_drvdata(pdev, card);
		snd_soc_card_set_drvdata(card, dummy_codec_pdata);
		if (!(pdev->dev.of_node)) {
			dev_err(&pdev->dev, "Must be instantiated using device tree\n");
			ret = -EINVAL;
			goto err;
		}

    ret = snd_soc_register_card(card);
		if (ret) {
			dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
			ret);
		goto err;
	}

#endif
#if 0
    dummy_codec_snd_pdata = pdev->dev.platform_data;
    snd_BUG_ON(!dummy_codec_snd_pdata);
    dummy_codec_snd_device = platform_device_alloc("soc-audio", -1);
    if (!dummy_codec_snd_device) {
        printk(KERN_ERR "ASoC: Platform device allocation failed\n");
        ret = -ENOMEM;
        goto err;
    }

    platform_set_drvdata(dummy_codec_snd_device, &snd_soc_dummy_codec);

    ret = platform_device_add(dummy_codec_snd_device);
    if (ret) {
        printk(KERN_ERR "ASoC: Platform device allocation failed\n");
        goto err_device_add;
    }
#endif

    dummy_codec_dev_init();

    return ret;

#if 0
err_device_add:
    platform_device_put(dummy_codec_snd_device);
#endif
err:
err1:
    kfree(dummy_codec_pdata);
    return ret;
}
Пример #17
0
static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct regmap *sys_mgr_base_addr;
	u32 reg_offset, reg_shift;
	int ret, index;
	struct device_node *np_splitter = NULL;
	struct device_node *np_sgmii_adapter = NULL;
	struct resource res_splitter;
	struct resource res_tse_pcs;
	struct resource res_sgmii_adapter;

	dwmac->interface = of_get_phy_mode(np);

	sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
	if (IS_ERR(sys_mgr_base_addr)) {
		dev_info(dev, "No sysmgr-syscon node found\n");
		return PTR_ERR(sys_mgr_base_addr);
	}

	ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);
	if (ret) {
		dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n");
		return -EINVAL;
	}

	ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, &reg_shift);
	if (ret) {
		dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n");
		return -EINVAL;
	}

	dwmac->f2h_ptp_ref_clk = of_property_read_bool(np, "altr,f2h_ptp_ref_clk");

	np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0);
	if (np_splitter) {
		ret = of_address_to_resource(np_splitter, 0, &res_splitter);
		of_node_put(np_splitter);
		if (ret) {
			dev_info(dev, "Missing emac splitter address\n");
			return -EINVAL;
		}

		dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter);
		if (IS_ERR(dwmac->splitter_base)) {
			dev_info(dev, "Failed to mapping emac splitter\n");
			return PTR_ERR(dwmac->splitter_base);
		}
	}

	np_sgmii_adapter = of_parse_phandle(np,
					    "altr,gmii-to-sgmii-converter", 0);
	if (np_sgmii_adapter) {
		index = of_property_match_string(np_sgmii_adapter, "reg-names",
						 "hps_emac_interface_splitter_avalon_slave");

		if (index >= 0) {
			if (of_address_to_resource(np_sgmii_adapter, index,
						   &res_splitter)) {
				dev_err(dev,
					"%s: ERROR: missing emac splitter address\n",
					__func__);
				ret = -EINVAL;
				goto err_node_put;
			}

			dwmac->splitter_base =
			    devm_ioremap_resource(dev, &res_splitter);

			if (IS_ERR(dwmac->splitter_base)) {
				ret = PTR_ERR(dwmac->splitter_base);
				goto err_node_put;
			}
		}

		index = of_property_match_string(np_sgmii_adapter, "reg-names",
						 "gmii_to_sgmii_adapter_avalon_slave");

		if (index >= 0) {
			if (of_address_to_resource(np_sgmii_adapter, index,
						   &res_sgmii_adapter)) {
				dev_err(dev,
					"%s: ERROR: failed mapping adapter\n",
					__func__);
				ret = -EINVAL;
				goto err_node_put;
			}

			dwmac->pcs.sgmii_adapter_base =
			    devm_ioremap_resource(dev, &res_sgmii_adapter);

			if (IS_ERR(dwmac->pcs.sgmii_adapter_base)) {
				ret = PTR_ERR(dwmac->pcs.sgmii_adapter_base);
				goto err_node_put;
			}
		}

		index = of_property_match_string(np_sgmii_adapter, "reg-names",
						 "eth_tse_control_port");

		if (index >= 0) {
			if (of_address_to_resource(np_sgmii_adapter, index,
						   &res_tse_pcs)) {
				dev_err(dev,
					"%s: ERROR: failed mapping tse control port\n",
					__func__);
				ret = -EINVAL;
				goto err_node_put;
			}

			dwmac->pcs.tse_pcs_base =
			    devm_ioremap_resource(dev, &res_tse_pcs);

			if (IS_ERR(dwmac->pcs.tse_pcs_base)) {
				ret = PTR_ERR(dwmac->pcs.tse_pcs_base);
				goto err_node_put;
			}
		}
	}
	dwmac->reg_offset = reg_offset;
	dwmac->reg_shift = reg_shift;
	dwmac->sys_mgr_base_addr = sys_mgr_base_addr;
	dwmac->dev = dev;
	of_node_put(np_sgmii_adapter);

	return 0;

err_node_put:
	of_node_put(np_sgmii_adapter);
	return ret;
}
Пример #18
0
void __init of_dra7_apll_setup(struct device_node *node)
{
	const struct clk_ops *ops;
	struct clk *clk;
	const char *clk_name = node->name;
	int num_parents;
	const char **parent_names = NULL;
	u8 apll_flags = 0;
	struct dpll_data *ad;
	u32 idlest_mask = 0x1;
	u32 autoidle_mask = 0x3;
	int i;

	ops = &apll_ck_ops;
	ad = kzalloc(sizeof(*ad), GFP_KERNEL);
	if (!ad) {
		pr_err("%s: could not allocate dpll_data\n", __func__);
		return;
	}

	of_property_read_string(node, "clock-output-names", &clk_name);

	num_parents = of_clk_get_parent_count(node);
	if (num_parents < 1) {
		pr_err("%s: omap dpll %s must have parent(s)\n",
		       __func__, node->name);
		goto cleanup;
	}

	parent_names = kzalloc(sizeof(char *) * num_parents, GFP_KERNEL);

	for (i = 0; i < num_parents; i++)
		parent_names[i] = of_clk_get_parent_name(node, i);

	ad->clk_ref = of_clk_get(node, 0);
	ad->clk_bypass = of_clk_get(node, 1);

	if (IS_ERR(ad->clk_ref)) {
		pr_err("%s: ti,clk-ref for %s not found\n", __func__,
		       clk_name);
		goto cleanup;
	}

	if (IS_ERR(ad->clk_bypass)) {
		pr_err("%s: ti,clk-bypass for %s not found\n", __func__,
		       clk_name);
		goto cleanup;
	}

	i = of_property_match_string(node, "reg-names", "control");
	if (i >= 0)
		ad->control_reg = of_iomap(node, i);

	i = of_property_match_string(node, "reg-names", "idlest");
	if (i >= 0)
		ad->idlest_reg = of_iomap(node, i);

	ad->idlest_mask = idlest_mask;
	ad->enable_mask = autoidle_mask;

	clk = omap_clk_register_apll(NULL, clk_name, parent_names,
				num_parents, apll_flags, ad,
				NULL, ops);

	if (!IS_ERR(clk))
		of_clk_add_provider(node, of_clk_src_simple_get, clk);
	return;

cleanup:
	kfree(parent_names);
	kfree(ad);
	return;
}
Пример #19
0
static void __init at91sam9rl_pmc_setup(struct device_node *np)
{
	const char *slck_name, *mainxtal_name;
	struct pmc_data *at91sam9rl_pmc;
	const char *parent_names[6];
	struct regmap *regmap;
	struct clk_hw *hw;
	int i;

	i = of_property_match_string(np, "clock-names", "slow_clk");
	if (i < 0)
		return;

	slck_name = of_clk_get_parent_name(np, i);

	i = of_property_match_string(np, "clock-names", "main_xtal");
	if (i < 0)
		return;
	mainxtal_name = of_clk_get_parent_name(np, i);

	regmap = syscon_node_to_regmap(np);
	if (IS_ERR(regmap))
		return;

	at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
					   nck(at91sam9rl_systemck),
					   nck(at91sam9rl_periphck), 0);
	if (!at91sam9rl_pmc)
		return;

	hw = at91_clk_register_rm9200_main(regmap, "mainck", mainxtal_name);
	if (IS_ERR(hw))
		goto err_free;

	at91sam9rl_pmc->chws[PMC_MAIN] = hw;

	hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
				   &at91rm9200_pll_layout,
				   &sam9rl_plla_characteristics);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
	if (IS_ERR(hw))
		goto err_free;

	at91sam9rl_pmc->chws[PMC_UTMI] = hw;

	parent_names[0] = slck_name;
	parent_names[1] = "mainck";
	parent_names[2] = "pllack";
	parent_names[3] = "utmick";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
				      &at91rm9200_master_layout,
				      &sam9rl_mck_characteristics);
	if (IS_ERR(hw))
		goto err_free;

	at91sam9rl_pmc->chws[PMC_MCK] = hw;

	parent_names[0] = slck_name;
	parent_names[1] = "mainck";
	parent_names[2] = "pllack";
	parent_names[3] = "utmick";
	parent_names[4] = "masterck";
	for (i = 0; i < 2; i++) {
		char name[6];

		snprintf(name, sizeof(name), "prog%d", i);

		hw = at91_clk_register_programmable(regmap, name,
						    parent_names, 5, i,
						    &at91rm9200_programmable_layout);
		if (IS_ERR(hw))
			goto err_free;
	}

	for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
		hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n,
					      at91sam9rl_systemck[i].p,
					      at91sam9rl_systemck[i].id);
		if (IS_ERR(hw))
			goto err_free;

		at91sam9rl_pmc->shws[at91sam9rl_systemck[i].id] = hw;
	}

	for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) {
		hw = at91_clk_register_peripheral(regmap,
						  at91sam9rl_periphck[i].n,
						  "masterck",
						  at91sam9rl_periphck[i].id);
		if (IS_ERR(hw))
			goto err_free;

		at91sam9rl_pmc->phws[at91sam9rl_periphck[i].id] = hw;
	}

	of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9rl_pmc);

	return;

err_free:
	pmc_data_free(at91sam9rl_pmc);
}
Пример #20
0
static void __init sama5d4_pmc_setup(struct device_node *np)
{
	struct clk_range range = CLK_RANGE(0, 0);
	const char *slck_name, *mainxtal_name;
	struct pmc_data *sama5d4_pmc;
	const char *parent_names[5];
	struct regmap *regmap;
	struct clk *hw;
	int i;
	bool bypass;

	i = of_property_match_string(np, "clock-names", "slow_clk");
	if (i < 0)
		return;

	slck_name = of_clk_get_parent_name(np, i);

	i = of_property_match_string(np, "clock-names", "main_xtal");
	if (i < 0)
		return;
	mainxtal_name = of_clk_get_parent_name(np, i);

	regmap = syscon_node_to_regmap(np);
	if (IS_ERR(regmap))
		return;

	sama5d4_pmc = pmc_data_allocate(PMC_MCK2 + 1,
					nck(sama5d4_systemck),
					nck(sama5d4_periph32ck), 0);
	if (!sama5d4_pmc)
		return;

	hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
					   100000000);
	if (IS_ERR(hw))
		goto err_free;

	bypass = of_property_read_bool(np, "atmel,osc-bypass");

	hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
					bypass);
	if (IS_ERR(hw))
		goto err_free;

	parent_names[0] = "main_rc_osc";
	parent_names[1] = "main_osc";
	hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
				   &sama5d3_pll_layout, &plla_characteristics);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
	if (IS_ERR(hw))
		goto err_free;

	sama5d4_pmc->chws[PMC_UTMI] = hw;

	parent_names[0] = slck_name;
	parent_names[1] = "mainck";
	parent_names[2] = "plladivck";
	parent_names[3] = "utmick";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
				      &at91sam9x5_master_layout,
				      &mck_characteristics);
	if (IS_ERR(hw))
		goto err_free;

	sama5d4_pmc->chws[PMC_MCK] = hw;

	hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck");
	if (IS_ERR(hw))
		goto err_free;

	sama5d4_pmc->chws[PMC_MCK2] = hw;

	parent_names[0] = "plladivck";
	parent_names[1] = "utmick";
	hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
	if (IS_ERR(hw))
		goto err_free;

	parent_names[0] = "plladivck";
	parent_names[1] = "utmick";
	hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2);
	if (IS_ERR(hw))
		goto err_free;

	parent_names[0] = slck_name;
	parent_names[1] = "mainck";
	parent_names[2] = "plladivck";
	parent_names[3] = "utmick";
	parent_names[4] = "mck";
	for (i = 0; i < 3; i++) {
		char *name;

		name = xasprintf("prog%d", i);

		hw = at91_clk_register_programmable(regmap, name,
						    parent_names, 5, i,
						    &at91sam9x5_programmable_layout);
		if (IS_ERR(hw))
			goto err_free;
	}

	for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
		hw = at91_clk_register_system(regmap, sama5d4_systemck[i].n,
					      sama5d4_systemck[i].p,
					      sama5d4_systemck[i].id);
		if (IS_ERR(hw))
			goto err_free;

		sama5d4_pmc->shws[sama5d4_systemck[i].id] = hw;
	}

	for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) {
		hw = at91_clk_register_sam9x5_peripheral(regmap,
							 sama5d4_periphck[i].n,
							 "masterck",
							 sama5d4_periphck[i].id,
							 &range);
		if (IS_ERR(hw))
			goto err_free;

		sama5d4_pmc->phws[sama5d4_periphck[i].id] = hw;
	}

	for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) {
		hw = at91_clk_register_sam9x5_peripheral(regmap,
							 sama5d4_periph32ck[i].n,
							 "h32mxck",
							 sama5d4_periph32ck[i].id,
							 &range);
		if (IS_ERR(hw))
			goto err_free;

		sama5d4_pmc->phws[sama5d4_periph32ck[i].id] = hw;
	}

	of_clk_add_provider(np, of_clk_hw_pmc_get, sama5d4_pmc);

	return;

err_free:
	pmc_data_free(sama5d4_pmc);
}
static void __init of_selftest_property_string(void)
{
	const char *strings[4];
	struct device_node *np;
	int rc;

	pr_info("start\n");
	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
	if (!np) {
		pr_err("No testcase data in device tree\n");
		return;
	}

	rc = of_property_match_string(np, "phandle-list-names", "first");
	selftest(rc == 0, "first expected:0 got:%i\n", rc);
	rc = of_property_match_string(np, "phandle-list-names", "second");
	selftest(rc == 1, "second expected:0 got:%i\n", rc);
	rc = of_property_match_string(np, "phandle-list-names", "third");
	selftest(rc == 2, "third expected:0 got:%i\n", rc);
	rc = of_property_match_string(np, "phandle-list-names", "fourth");
	selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc);
	rc = of_property_match_string(np, "missing-property", "blah");
	selftest(rc == -EINVAL, "missing property; rc=%i\n", rc);
	rc = of_property_match_string(np, "empty-property", "blah");
	selftest(rc == -ENODATA, "empty property; rc=%i\n", rc);
	rc = of_property_match_string(np, "unterminated-string", "blah");
	selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);

	/* of_property_count_strings() tests */
	rc = of_property_count_strings(np, "string-property");
	selftest(rc == 1, "Incorrect string count; rc=%i\n", rc);
	rc = of_property_count_strings(np, "phandle-list-names");
	selftest(rc == 3, "Incorrect string count; rc=%i\n", rc);
	rc = of_property_count_strings(np, "unterminated-string");
	selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
	rc = of_property_count_strings(np, "unterminated-string-list");
	selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);

	/* of_property_read_string_index() tests */
	rc = of_property_read_string_index(np, "string-property", 0, strings);
	selftest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc);
	strings[0] = NULL;
	rc = of_property_read_string_index(np, "string-property", 1, strings);
	selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
	rc = of_property_read_string_index(np, "phandle-list-names", 0, strings);
	selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
	rc = of_property_read_string_index(np, "phandle-list-names", 1, strings);
	selftest(rc == 0 && !strcmp(strings[0], "second"), "of_property_read_string_index() failure; rc=%i\n", rc);
	rc = of_property_read_string_index(np, "phandle-list-names", 2, strings);
	selftest(rc == 0 && !strcmp(strings[0], "third"), "of_property_read_string_index() failure; rc=%i\n", rc);
	strings[0] = NULL;
	rc = of_property_read_string_index(np, "phandle-list-names", 3, strings);
	selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
	strings[0] = NULL;
	rc = of_property_read_string_index(np, "unterminated-string", 0, strings);
	selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
	rc = of_property_read_string_index(np, "unterminated-string-list", 0, strings);
	selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc);
	strings[0] = NULL;
	rc = of_property_read_string_index(np, "unterminated-string-list", 2, strings); /* should fail */
	selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc);
	strings[1] = NULL;

	/* of_property_read_string_array() tests */
	rc = of_property_read_string_array(np, "string-property", strings, 4);
	selftest(rc == 1, "Incorrect string count; rc=%i\n", rc);
	rc = of_property_read_string_array(np, "phandle-list-names", strings, 4);
	selftest(rc == 3, "Incorrect string count; rc=%i\n", rc);
	rc = of_property_read_string_array(np, "unterminated-string", strings, 4);
	selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc);
	/* -- An incorrectly formed string should cause a failure */
	rc = of_property_read_string_array(np, "unterminated-string-list", strings, 4);
	selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc);
	/* -- parsing the correctly formed strings should still work: */
	strings[2] = NULL;
	rc = of_property_read_string_array(np, "unterminated-string-list", strings, 2);
	selftest(rc == 2 && strings[2] == NULL, "of_property_read_string_array() failure; rc=%i\n", rc);
	strings[1] = NULL;
	rc = of_property_read_string_array(np, "phandle-list-names", strings, 1);
	selftest(rc == 1 && strings[1] == NULL, "Overwrote end of string array; rc=%i, str='%s'\n", rc, strings[1]);
}
Пример #22
0
static int unifykey_item_parse_dt(struct device_node *node, int id)
{
	int count;
	int ret =  -1;
	const char *propname;
	struct key_item_t *temp_item = NULL;

	temp_item = kzalloc(sizeof(struct key_item_t), GFP_KERNEL);
	if (!temp_item) {
		pr_err("%s:%d,no memory for key_item\n", __func__, __LINE__);
		ret = -ENOMEM;
		return ret;
	}
	propname = NULL;
	ret = of_property_read_string(node, "key-name", &propname);
	if (ret < 0) {
		pr_err("%s:%d,get key-name fail\n", __func__, __LINE__);
		ret = -EINVAL;
		goto exit;
	}
	if (propname) {
		count = strlen(propname);
		memset(temp_item->name, 0, KEY_UNIFY_NAME_LEN);
		if (count >= KEY_UNIFY_NAME_LEN)
			count = KEY_UNIFY_NAME_LEN-1;
		strncpy(temp_item->name, propname, count);
	}

	propname = NULL;
	ret = of_property_read_string(node, "key-device", &propname);
	if (ret < 0) {
		pr_err("%s:%d,get key-device fail\n", __func__, __LINE__);
		ret = -EINVAL;
		goto exit;
	}
	if (propname) {
		if (strcmp(propname, KEY_DEV_EFUSE) == 0)
			temp_item->dev = KEY_M_EFUSE;
		else if (strcmp(propname, KEY_DEV_NORMAL) == 0)
			temp_item->dev = KEY_M_NORMAL;
		else if (strcmp(propname, KEY_DEV_SECURE) == 0)
			temp_item->dev = KEY_M_SECURE;
		else
			temp_item->dev = KEY_M_UNKNOW_DEV;
	}

	temp_item->permit = 0;
	if (of_property_match_string(node, "key-permit", KEY_PERMIT_READ) >= 0)
		temp_item->permit |= KEY_M_PERMIT_READ;
	if (of_property_match_string(node, "key-permit", KEY_PERMIT_WRITE) >= 0)
		temp_item->permit |= KEY_M_PERMIT_WRITE;
	if (of_property_match_string(node, "key-permit", KEY_PERMIT_DEL) >= 0)
		temp_item->permit |= KEY_M_PERMIT_DEL;
	temp_item->id = id;

	unifykey_add_to_list(temp_item);

	return 0;
exit:
	kfree(temp_item);
	return ret;
}
Пример #23
0
static int get_audio_codec_i2c_info(struct device_node* p_node, aml_audio_codec_info_t* audio_codec_dev)
{
    const char* str;
    int ret = 0;
    unsigned i2c_addr;
    struct i2c_adapter *adapter;

    ret = of_property_read_string(p_node, "codec_name", &audio_codec_dev->name);
    if (ret) {
        printk("get audio codec name failed!\n");
        goto err_out;
    }

    ret = of_property_match_string(p_node,"status","okay");
    if(ret){
        printk("%s:this audio codec is disabled!\n",audio_codec_dev->name);
        goto err_out;
    }
    printk("use audio codec %s\n",audio_codec_dev->name);

    ret = of_property_read_u32(p_node,"capless",&audio_codec_dev->capless);
    if(ret){
        printk("don't find audio codec capless mode!\n");
    }

    ret = of_property_read_string(p_node, "i2c_bus", &str);
    if (ret) {
        printk("%s: faild to get i2c_bus str,use default i2c bus!\n", audio_codec_dev->name);
        audio_codec_dev->i2c_bus_type = AML_I2C_BUS_D;
    } else {
        if (!strncmp(str, "i2c_bus_a", 9))
            audio_codec_dev->i2c_bus_type = AML_I2C_BUS_A;
        else if (!strncmp(str, "i2c_bus_b", 9))
            audio_codec_dev->i2c_bus_type = AML_I2C_BUS_B;
        else if (!strncmp(str, "i2c_bus_c", 9))
            audio_codec_dev->i2c_bus_type = AML_I2C_BUS_C;
        else if (!strncmp(str, "i2c_bus_d", 9))
            audio_codec_dev->i2c_bus_type = AML_I2C_BUS_D;
        else if (!strncmp(str, "i2c_bus_ao", 10))
            audio_codec_dev->i2c_bus_type = AML_I2C_BUS_AO;
        else
            audio_codec_dev->i2c_bus_type = AML_I2C_BUS_D;
    }

    ret = of_property_read_u32(p_node,"i2c_addr",&i2c_addr);
    if(ret){
        printk("don't find i2c adress capless,use default!\n");
        audio_codec_dev->i2c_addr = 0x1B;
    }else{
        audio_codec_dev->i2c_addr = i2c_addr;
    }
    printk("audio codec addr: 0x%x\n", audio_codec_dev->i2c_addr);
    printk("audio codec i2c bus: %d\n", audio_codec_dev->i2c_bus_type);

    /* test if the camera is exist */
    adapter = i2c_get_adapter(audio_codec_dev->i2c_bus_type);
    if (!adapter) {
        printk("can not do probe function\n");
        ret = -1;
        goto err_out;
    }
    ret = 0;

err_out:
    return ret;
}