Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.4-rc4 150 lines 3.8 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2014 Free Electrons 4 * Copyright (C) 2014 Atmel 5 * 6 * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> 7 */ 8 9#include <linux/clk.h> 10#include <linux/iopoll.h> 11#include <linux/mfd/atmel-hlcdc.h> 12#include <linux/mfd/core.h> 13#include <linux/module.h> 14#include <linux/mod_devicetable.h> 15#include <linux/platform_device.h> 16#include <linux/regmap.h> 17 18#define ATMEL_HLCDC_REG_MAX (0x4000 - 0x4) 19 20struct atmel_hlcdc_regmap { 21 void __iomem *regs; 22}; 23 24static const struct mfd_cell atmel_hlcdc_cells[] = { 25 { 26 .name = "atmel-hlcdc-pwm", 27 .of_compatible = "atmel,hlcdc-pwm", 28 }, 29 { 30 .name = "atmel-hlcdc-dc", 31 .of_compatible = "atmel,hlcdc-display-controller", 32 }, 33}; 34 35static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg, 36 unsigned int val) 37{ 38 struct atmel_hlcdc_regmap *hregmap = context; 39 40 if (reg <= ATMEL_HLCDC_DIS) { 41 u32 status; 42 43 readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR, 44 status, !(status & ATMEL_HLCDC_SIP), 45 1, 100); 46 } 47 48 writel(val, hregmap->regs + reg); 49 50 return 0; 51} 52 53static int regmap_atmel_hlcdc_reg_read(void *context, unsigned int reg, 54 unsigned int *val) 55{ 56 struct atmel_hlcdc_regmap *hregmap = context; 57 58 *val = readl(hregmap->regs + reg); 59 60 return 0; 61} 62 63static const struct regmap_config atmel_hlcdc_regmap_config = { 64 .reg_bits = 32, 65 .val_bits = 32, 66 .reg_stride = 4, 67 .max_register = ATMEL_HLCDC_REG_MAX, 68 .reg_write = regmap_atmel_hlcdc_reg_write, 69 .reg_read = regmap_atmel_hlcdc_reg_read, 70 .fast_io = true, 71}; 72 73static int atmel_hlcdc_probe(struct platform_device *pdev) 74{ 75 struct atmel_hlcdc_regmap *hregmap; 76 struct device *dev = &pdev->dev; 77 struct atmel_hlcdc *hlcdc; 78 struct resource *res; 79 80 hregmap = devm_kzalloc(dev, sizeof(*hregmap), GFP_KERNEL); 81 if (!hregmap) 82 return -ENOMEM; 83 84 hlcdc = devm_kzalloc(dev, sizeof(*hlcdc), GFP_KERNEL); 85 if (!hlcdc) 86 return -ENOMEM; 87 88 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 89 hregmap->regs = devm_ioremap_resource(dev, res); 90 if (IS_ERR(hregmap->regs)) 91 return PTR_ERR(hregmap->regs); 92 93 hlcdc->irq = platform_get_irq(pdev, 0); 94 if (hlcdc->irq < 0) 95 return hlcdc->irq; 96 97 hlcdc->periph_clk = devm_clk_get(dev, "periph_clk"); 98 if (IS_ERR(hlcdc->periph_clk)) { 99 dev_err(dev, "failed to get peripheral clock\n"); 100 return PTR_ERR(hlcdc->periph_clk); 101 } 102 103 hlcdc->sys_clk = devm_clk_get(dev, "sys_clk"); 104 if (IS_ERR(hlcdc->sys_clk)) { 105 dev_err(dev, "failed to get system clock\n"); 106 return PTR_ERR(hlcdc->sys_clk); 107 } 108 109 hlcdc->slow_clk = devm_clk_get(dev, "slow_clk"); 110 if (IS_ERR(hlcdc->slow_clk)) { 111 dev_err(dev, "failed to get slow clock\n"); 112 return PTR_ERR(hlcdc->slow_clk); 113 } 114 115 hlcdc->regmap = devm_regmap_init(dev, NULL, hregmap, 116 &atmel_hlcdc_regmap_config); 117 if (IS_ERR(hlcdc->regmap)) 118 return PTR_ERR(hlcdc->regmap); 119 120 dev_set_drvdata(dev, hlcdc); 121 122 return devm_mfd_add_devices(dev, -1, atmel_hlcdc_cells, 123 ARRAY_SIZE(atmel_hlcdc_cells), 124 NULL, 0, NULL); 125} 126 127static const struct of_device_id atmel_hlcdc_match[] = { 128 { .compatible = "atmel,at91sam9n12-hlcdc" }, 129 { .compatible = "atmel,at91sam9x5-hlcdc" }, 130 { .compatible = "atmel,sama5d2-hlcdc" }, 131 { .compatible = "atmel,sama5d3-hlcdc" }, 132 { .compatible = "atmel,sama5d4-hlcdc" }, 133 { .compatible = "microchip,sam9x60-hlcdc" }, 134 { /* sentinel */ }, 135}; 136MODULE_DEVICE_TABLE(of, atmel_hlcdc_match); 137 138static struct platform_driver atmel_hlcdc_driver = { 139 .probe = atmel_hlcdc_probe, 140 .driver = { 141 .name = "atmel-hlcdc", 142 .of_match_table = atmel_hlcdc_match, 143 }, 144}; 145module_platform_driver(atmel_hlcdc_driver); 146 147MODULE_ALIAS("platform:atmel-hlcdc"); 148MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>"); 149MODULE_DESCRIPTION("Atmel HLCDC driver"); 150MODULE_LICENSE("GPL v2");