brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · ee03db0 Raw
165 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2014 Free Electrons4 *5 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com>6 *7 * Allwinner PRCM (Power/Reset/Clock Management) driver8 */9 10#include <linux/mfd/core.h>11#include <linux/init.h>12#include <linux/of.h>13 14#define SUN8I_CODEC_ANALOG_BASE	0x1c015#define SUN8I_CODEC_ANALOG_SIZE	0x416 17struct prcm_data {18	int nsubdevs;19	const struct mfd_cell *subdevs;20};21 22static const struct resource sun6i_a31_ar100_clk_res[] = {23	DEFINE_RES_MEM(0x0, 4)24};25 26static const struct resource sun6i_a31_apb0_clk_res[] = {27	DEFINE_RES_MEM(0xc, 4)28};29 30static const struct resource sun6i_a31_apb0_gates_clk_res[] = {31	DEFINE_RES_MEM(0x28, 4)32};33 34static const struct resource sun6i_a31_ir_clk_res[] = {35	DEFINE_RES_MEM(0x54, 4)36};37 38static const struct resource sun6i_a31_apb0_rstc_res[] = {39	DEFINE_RES_MEM(0xb0, 4)40};41 42static const struct resource sun8i_codec_analog_res[] = {43	DEFINE_RES_MEM(SUN8I_CODEC_ANALOG_BASE, SUN8I_CODEC_ANALOG_SIZE),44};45 46static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {47	{48		.name = "sun6i-a31-ar100-clk",49		.of_compatible = "allwinner,sun6i-a31-ar100-clk",50		.num_resources = ARRAY_SIZE(sun6i_a31_ar100_clk_res),51		.resources = sun6i_a31_ar100_clk_res,52	},53	{54		.name = "sun6i-a31-apb0-clk",55		.of_compatible = "allwinner,sun6i-a31-apb0-clk",56		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_clk_res),57		.resources = sun6i_a31_apb0_clk_res,58	},59	{60		.name = "sun6i-a31-apb0-gates-clk",61		.of_compatible = "allwinner,sun6i-a31-apb0-gates-clk",62		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_gates_clk_res),63		.resources = sun6i_a31_apb0_gates_clk_res,64	},65	{66		.name = "sun6i-a31-ir-clk",67		.of_compatible = "allwinner,sun4i-a10-mod0-clk",68		.num_resources = ARRAY_SIZE(sun6i_a31_ir_clk_res),69		.resources = sun6i_a31_ir_clk_res,70	},71	{72		.name = "sun6i-a31-apb0-clock-reset",73		.of_compatible = "allwinner,sun6i-a31-clock-reset",74		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),75		.resources = sun6i_a31_apb0_rstc_res,76	},77};78 79static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {80	{81		.name = "sun8i-a23-apb0-clk",82		.of_compatible = "allwinner,sun8i-a23-apb0-clk",83		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_clk_res),84		.resources = sun6i_a31_apb0_clk_res,85	},86	{87		.name = "sun6i-a31-apb0-gates-clk",88		.of_compatible = "allwinner,sun8i-a23-apb0-gates-clk",89		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_gates_clk_res),90		.resources = sun6i_a31_apb0_gates_clk_res,91	},92	{93		.name = "sun6i-a31-apb0-clock-reset",94		.of_compatible = "allwinner,sun6i-a31-clock-reset",95		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),96		.resources = sun6i_a31_apb0_rstc_res,97	},98	{99		.name		= "sun8i-codec-analog",100		.of_compatible	= "allwinner,sun8i-a23-codec-analog",101		.num_resources	= ARRAY_SIZE(sun8i_codec_analog_res),102		.resources	= sun8i_codec_analog_res,103	},104};105 106static const struct prcm_data sun6i_a31_prcm_data = {107	.nsubdevs = ARRAY_SIZE(sun6i_a31_prcm_subdevs),108	.subdevs = sun6i_a31_prcm_subdevs,109};110 111static const struct prcm_data sun8i_a23_prcm_data = {112	.nsubdevs = ARRAY_SIZE(sun8i_a23_prcm_subdevs),113	.subdevs = sun8i_a23_prcm_subdevs,114};115 116static const struct of_device_id sun6i_prcm_dt_ids[] = {117	{118		.compatible = "allwinner,sun6i-a31-prcm",119		.data = &sun6i_a31_prcm_data,120	},121	{122		.compatible = "allwinner,sun8i-a23-prcm",123		.data = &sun8i_a23_prcm_data,124	},125	{ /* sentinel */ },126};127 128static int sun6i_prcm_probe(struct platform_device *pdev)129{130	const struct of_device_id *match;131	const struct prcm_data *data;132	struct resource *res;133	int ret;134 135	match = of_match_node(sun6i_prcm_dt_ids, pdev->dev.of_node);136	if (!match)137		return -EINVAL;138 139	data = match->data;140 141	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);142	if (!res) {143		dev_err(&pdev->dev, "no prcm memory region provided\n");144		return -ENOENT;145	}146 147	ret = mfd_add_devices(&pdev->dev, 0, data->subdevs, data->nsubdevs,148			      res, -1, NULL);149	if (ret) {150		dev_err(&pdev->dev, "failed to add subdevices\n");151		return ret;152	}153 154	return 0;155}156 157static struct platform_driver sun6i_prcm_driver = {158	.driver = {159		.name = "sun6i-prcm",160		.of_match_table = sun6i_prcm_dt_ids,161	},162	.probe = sun6i_prcm_probe,163};164builtin_platform_driver(sun6i_prcm_driver);165