root/drivers/mfd/vexpress-sysreg.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vexpress_flags_set
  2. vexpress_sysreg_probe
  3. vexpress_sysreg_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  * Copyright (C) 2012 ARM Limited
   5  */
   6 
   7 #include <linux/gpio/driver.h>
   8 #include <linux/err.h>
   9 #include <linux/io.h>
  10 #include <linux/mfd/core.h>
  11 #include <linux/of_address.h>
  12 #include <linux/of_platform.h>
  13 #include <linux/platform_data/syscon.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/slab.h>
  16 #include <linux/stat.h>
  17 #include <linux/vexpress.h>
  18 
  19 #define SYS_ID                  0x000
  20 #define SYS_SW                  0x004
  21 #define SYS_LED                 0x008
  22 #define SYS_100HZ               0x024
  23 #define SYS_FLAGSSET            0x030
  24 #define SYS_FLAGSCLR            0x034
  25 #define SYS_NVFLAGS             0x038
  26 #define SYS_NVFLAGSSET          0x038
  27 #define SYS_NVFLAGSCLR          0x03c
  28 #define SYS_MCI                 0x048
  29 #define SYS_FLASH               0x04c
  30 #define SYS_CFGSW               0x058
  31 #define SYS_24MHZ               0x05c
  32 #define SYS_MISC                0x060
  33 #define SYS_DMA                 0x064
  34 #define SYS_PROCID0             0x084
  35 #define SYS_PROCID1             0x088
  36 #define SYS_CFGDATA             0x0a0
  37 #define SYS_CFGCTRL             0x0a4
  38 #define SYS_CFGSTAT             0x0a8
  39 
  40 #define SYS_HBI_MASK            0xfff
  41 #define SYS_PROCIDx_HBI_SHIFT   0
  42 
  43 #define SYS_MISC_MASTERSITE     (1 << 14)
  44 
  45 void vexpress_flags_set(u32 data)
  46 {
  47         static void __iomem *base;
  48 
  49         if (!base) {
  50                 struct device_node *node = of_find_compatible_node(NULL, NULL,
  51                                 "arm,vexpress-sysreg");
  52 
  53                 base = of_iomap(node, 0);
  54         }
  55 
  56         if (WARN_ON(!base))
  57                 return;
  58 
  59         writel(~0, base + SYS_FLAGSCLR);
  60         writel(data, base + SYS_FLAGSSET);
  61 }
  62 
  63 /* The sysreg block is just a random collection of various functions... */
  64 
  65 static struct syscon_platform_data vexpress_sysreg_sys_id_pdata = {
  66         .label = "sys_id",
  67 };
  68 
  69 static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = {
  70         .label = "sys_led",
  71         .base = -1,
  72         .ngpio = 8,
  73 };
  74 
  75 static struct bgpio_pdata vexpress_sysreg_sys_mci_pdata = {
  76         .label = "sys_mci",
  77         .base = -1,
  78         .ngpio = 2,
  79 };
  80 
  81 static struct bgpio_pdata vexpress_sysreg_sys_flash_pdata = {
  82         .label = "sys_flash",
  83         .base = -1,
  84         .ngpio = 1,
  85 };
  86 
  87 static struct syscon_platform_data vexpress_sysreg_sys_misc_pdata = {
  88         .label = "sys_misc",
  89 };
  90 
  91 static struct syscon_platform_data vexpress_sysreg_sys_procid_pdata = {
  92         .label = "sys_procid",
  93 };
  94 
  95 static struct mfd_cell vexpress_sysreg_cells[] = {
  96         {
  97                 .name = "syscon",
  98                 .num_resources = 1,
  99                 .resources = (struct resource []) {
 100                         DEFINE_RES_MEM(SYS_ID, 0x4),
 101                 },
 102                 .platform_data = &vexpress_sysreg_sys_id_pdata,
 103                 .pdata_size = sizeof(vexpress_sysreg_sys_id_pdata),
 104         }, {
 105                 .name = "basic-mmio-gpio",
 106                 .of_compatible = "arm,vexpress-sysreg,sys_led",
 107                 .num_resources = 1,
 108                 .resources = (struct resource []) {
 109                         DEFINE_RES_MEM_NAMED(SYS_LED, 0x4, "dat"),
 110                 },
 111                 .platform_data = &vexpress_sysreg_sys_led_pdata,
 112                 .pdata_size = sizeof(vexpress_sysreg_sys_led_pdata),
 113         }, {
 114                 .name = "basic-mmio-gpio",
 115                 .of_compatible = "arm,vexpress-sysreg,sys_mci",
 116                 .num_resources = 1,
 117                 .resources = (struct resource []) {
 118                         DEFINE_RES_MEM_NAMED(SYS_MCI, 0x4, "dat"),
 119                 },
 120                 .platform_data = &vexpress_sysreg_sys_mci_pdata,
 121                 .pdata_size = sizeof(vexpress_sysreg_sys_mci_pdata),
 122         }, {
 123                 .name = "basic-mmio-gpio",
 124                 .of_compatible = "arm,vexpress-sysreg,sys_flash",
 125                 .num_resources = 1,
 126                 .resources = (struct resource []) {
 127                         DEFINE_RES_MEM_NAMED(SYS_FLASH, 0x4, "dat"),
 128                 },
 129                 .platform_data = &vexpress_sysreg_sys_flash_pdata,
 130                 .pdata_size = sizeof(vexpress_sysreg_sys_flash_pdata),
 131         }, {
 132                 .name = "syscon",
 133                 .num_resources = 1,
 134                 .resources = (struct resource []) {
 135                         DEFINE_RES_MEM(SYS_MISC, 0x4),
 136                 },
 137                 .platform_data = &vexpress_sysreg_sys_misc_pdata,
 138                 .pdata_size = sizeof(vexpress_sysreg_sys_misc_pdata),
 139         }, {
 140                 .name = "syscon",
 141                 .num_resources = 1,
 142                 .resources = (struct resource []) {
 143                         DEFINE_RES_MEM(SYS_PROCID0, 0x8),
 144                 },
 145                 .platform_data = &vexpress_sysreg_sys_procid_pdata,
 146                 .pdata_size = sizeof(vexpress_sysreg_sys_procid_pdata),
 147         }, {
 148                 .name = "vexpress-syscfg",
 149                 .num_resources = 1,
 150                 .resources = (struct resource []) {
 151                         DEFINE_RES_MEM(SYS_CFGDATA, 0xc),
 152                 },
 153         }
 154 };
 155 
 156 static int vexpress_sysreg_probe(struct platform_device *pdev)
 157 {
 158         struct resource *mem;
 159         void __iomem *base;
 160         struct gpio_chip *mmc_gpio_chip;
 161         int master;
 162         u32 dt_hbi;
 163 
 164         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 165         if (!mem)
 166                 return -EINVAL;
 167 
 168         base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
 169         if (!base)
 170                 return -ENOMEM;
 171 
 172         master = readl(base + SYS_MISC) & SYS_MISC_MASTERSITE ?
 173                         VEXPRESS_SITE_DB2 : VEXPRESS_SITE_DB1;
 174         vexpress_config_set_master(master);
 175 
 176         /* Confirm board type against DT property, if available */
 177         if (of_property_read_u32(of_root, "arm,hbi", &dt_hbi) == 0) {
 178                 u32 id = readl(base + (master == VEXPRESS_SITE_DB1 ?
 179                                  SYS_PROCID0 : SYS_PROCID1));
 180                 u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
 181 
 182                 if (WARN_ON(dt_hbi != hbi))
 183                         dev_warn(&pdev->dev, "DT HBI (%x) is not matching hardware (%x)!\n",
 184                                         dt_hbi, hbi);
 185         }
 186 
 187         /*
 188          * Duplicated SYS_MCI pseudo-GPIO controller for compatibility with
 189          * older trees using sysreg node for MMC control lines.
 190          */
 191         mmc_gpio_chip = devm_kzalloc(&pdev->dev, sizeof(*mmc_gpio_chip),
 192                         GFP_KERNEL);
 193         if (!mmc_gpio_chip)
 194                 return -ENOMEM;
 195         bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI,
 196                         NULL, NULL, NULL, NULL, 0);
 197         mmc_gpio_chip->ngpio = 2;
 198         gpiochip_add_data(mmc_gpio_chip, NULL);
 199 
 200         return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
 201                         vexpress_sysreg_cells,
 202                         ARRAY_SIZE(vexpress_sysreg_cells), mem, 0, NULL);
 203 }
 204 
 205 static const struct of_device_id vexpress_sysreg_match[] = {
 206         { .compatible = "arm,vexpress-sysreg", },
 207         {},
 208 };
 209 
 210 static struct platform_driver vexpress_sysreg_driver = {
 211         .driver = {
 212                 .name = "vexpress-sysreg",
 213                 .of_match_table = vexpress_sysreg_match,
 214         },
 215         .probe = vexpress_sysreg_probe,
 216 };
 217 
 218 static int __init vexpress_sysreg_init(void)
 219 {
 220         struct device_node *node;
 221 
 222         /* Need the sysreg early, before any other device... */
 223         for_each_matching_node(node, vexpress_sysreg_match)
 224                 of_platform_device_create(node, NULL, NULL);
 225 
 226         return platform_driver_register(&vexpress_sysreg_driver);
 227 }
 228 core_initcall(vexpress_sysreg_init);

/* [<][>][^][v][top][bottom][index][help] */