brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 28a8cc5 Raw
135 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ARM PL353 SMC driver4 *5 * Copyright (C) 2012 - 2018 Xilinx, Inc6 * Author: Punnaiah Choudary Kalluri <punnaiah@xilinx.com>7 * Author: Naga Sureshkumar Relli <nagasure@xilinx.com>8 */9 10#include <linux/clk.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/of.h>14#include <linux/of_platform.h>15#include <linux/platform_device.h>16#include <linux/amba/bus.h>17 18/**19 * struct pl353_smc_data - Private smc driver structure20 * @memclk:		Pointer to the peripheral clock21 * @aclk:		Pointer to the AXI peripheral clock22 */23struct pl353_smc_data {24	struct clk		*memclk;25	struct clk		*aclk;26};27 28static int __maybe_unused pl353_smc_suspend(struct device *dev)29{30	struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);31 32	clk_disable(pl353_smc->memclk);33	clk_disable(pl353_smc->aclk);34 35	return 0;36}37 38static int __maybe_unused pl353_smc_resume(struct device *dev)39{40	struct pl353_smc_data *pl353_smc = dev_get_drvdata(dev);41	int ret;42 43	ret = clk_enable(pl353_smc->aclk);44	if (ret) {45		dev_err(dev, "Cannot enable axi domain clock.\n");46		return ret;47	}48 49	ret = clk_enable(pl353_smc->memclk);50	if (ret) {51		dev_err(dev, "Cannot enable memory clock.\n");52		clk_disable(pl353_smc->aclk);53		return ret;54	}55 56	return ret;57}58 59static SIMPLE_DEV_PM_OPS(pl353_smc_dev_pm_ops, pl353_smc_suspend,60			 pl353_smc_resume);61 62static const struct of_device_id pl353_smc_supported_children[] = {63	{64		.compatible = "cfi-flash"65	},66	{67		.compatible = "arm,pl353-nand-r2p1",68	},69	{}70};71 72static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)73{74	struct device_node *of_node = adev->dev.of_node;75	const struct of_device_id *match = NULL;76	struct pl353_smc_data *pl353_smc;77 78	pl353_smc = devm_kzalloc(&adev->dev, sizeof(*pl353_smc), GFP_KERNEL);79	if (!pl353_smc)80		return -ENOMEM;81 82	pl353_smc->aclk = devm_clk_get_enabled(&adev->dev, "apb_pclk");83	if (IS_ERR(pl353_smc->aclk))84		return dev_err_probe(&adev->dev, PTR_ERR(pl353_smc->aclk),85				     "aclk clock not found.\n");86 87	pl353_smc->memclk = devm_clk_get_enabled(&adev->dev, "memclk");88	if (IS_ERR(pl353_smc->memclk))89		return dev_err_probe(&adev->dev, PTR_ERR(pl353_smc->memclk),90				     "memclk clock not found.\n");91 92	amba_set_drvdata(adev, pl353_smc);93 94	/* Find compatible children. Only a single child is supported */95	for_each_available_child_of_node_scoped(of_node, child) {96		match = of_match_node(pl353_smc_supported_children, child);97		if (!match) {98			dev_warn(&adev->dev, "unsupported child node\n");99			continue;100		}101		of_platform_device_create(child, NULL, &adev->dev);102		break;103	}104	if (!match) {105		dev_err(&adev->dev, "no matching children\n");106		return -ENODEV;107	}108 109	return 0;110}111 112static const struct amba_id pl353_ids[] = {113	{114		.id = 0x00041353,115		.mask = 0x000fffff,116	},117	{ 0, 0 },118};119MODULE_DEVICE_TABLE(amba, pl353_ids);120 121static struct amba_driver pl353_smc_driver = {122	.drv = {123		.name = "pl353-smc",124		.pm = &pl353_smc_dev_pm_ops,125	},126	.id_table = pl353_ids,127	.probe = pl353_smc_probe,128};129 130module_amba_driver(pl353_smc_driver);131 132MODULE_AUTHOR("Xilinx, Inc.");133MODULE_DESCRIPTION("ARM PL353 SMC Driver");134MODULE_LICENSE("GPL");135