Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  * Copyright (C) 2012 ARM Limited
0005  */
0006 
0007 #include <linux/gpio/driver.h>
0008 #include <linux/err.h>
0009 #include <linux/io.h>
0010 #include <linux/mfd/core.h>
0011 #include <linux/module.h>
0012 #include <linux/of_platform.h>
0013 #include <linux/platform_data/syscon.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016 #include <linux/stat.h>
0017 
0018 #define SYS_ID          0x000
0019 #define SYS_SW          0x004
0020 #define SYS_LED         0x008
0021 #define SYS_100HZ       0x024
0022 #define SYS_FLAGSSET        0x030
0023 #define SYS_FLAGSCLR        0x034
0024 #define SYS_NVFLAGS     0x038
0025 #define SYS_NVFLAGSSET      0x038
0026 #define SYS_NVFLAGSCLR      0x03c
0027 #define SYS_MCI         0x048
0028 #define SYS_FLASH       0x04c
0029 #define SYS_CFGSW       0x058
0030 #define SYS_24MHZ       0x05c
0031 #define SYS_MISC        0x060
0032 #define SYS_DMA         0x064
0033 #define SYS_PROCID0     0x084
0034 #define SYS_PROCID1     0x088
0035 #define SYS_CFGDATA     0x0a0
0036 #define SYS_CFGCTRL     0x0a4
0037 #define SYS_CFGSTAT     0x0a8
0038 
0039 /* The sysreg block is just a random collection of various functions... */
0040 
0041 static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = {
0042     .label = "sys_led",
0043     .base = -1,
0044     .ngpio = 8,
0045 };
0046 
0047 static struct bgpio_pdata vexpress_sysreg_sys_mci_pdata = {
0048     .label = "sys_mci",
0049     .base = -1,
0050     .ngpio = 2,
0051 };
0052 
0053 static struct bgpio_pdata vexpress_sysreg_sys_flash_pdata = {
0054     .label = "sys_flash",
0055     .base = -1,
0056     .ngpio = 1,
0057 };
0058 
0059 static struct mfd_cell vexpress_sysreg_cells[] = {
0060     {
0061         .name = "basic-mmio-gpio",
0062         .of_compatible = "arm,vexpress-sysreg,sys_led",
0063         .num_resources = 1,
0064         .resources = (struct resource []) {
0065             DEFINE_RES_MEM_NAMED(SYS_LED, 0x4, "dat"),
0066         },
0067         .platform_data = &vexpress_sysreg_sys_led_pdata,
0068         .pdata_size = sizeof(vexpress_sysreg_sys_led_pdata),
0069     }, {
0070         .name = "basic-mmio-gpio",
0071         .of_compatible = "arm,vexpress-sysreg,sys_mci",
0072         .num_resources = 1,
0073         .resources = (struct resource []) {
0074             DEFINE_RES_MEM_NAMED(SYS_MCI, 0x4, "dat"),
0075         },
0076         .platform_data = &vexpress_sysreg_sys_mci_pdata,
0077         .pdata_size = sizeof(vexpress_sysreg_sys_mci_pdata),
0078     }, {
0079         .name = "basic-mmio-gpio",
0080         .of_compatible = "arm,vexpress-sysreg,sys_flash",
0081         .num_resources = 1,
0082         .resources = (struct resource []) {
0083             DEFINE_RES_MEM_NAMED(SYS_FLASH, 0x4, "dat"),
0084         },
0085         .platform_data = &vexpress_sysreg_sys_flash_pdata,
0086         .pdata_size = sizeof(vexpress_sysreg_sys_flash_pdata),
0087     }, {
0088         .name = "vexpress-syscfg",
0089         .num_resources = 1,
0090         .resources = (struct resource []) {
0091             DEFINE_RES_MEM(SYS_MISC, 0x4c),
0092         },
0093     }
0094 };
0095 
0096 static int vexpress_sysreg_probe(struct platform_device *pdev)
0097 {
0098     struct resource *mem;
0099     void __iomem *base;
0100     struct gpio_chip *mmc_gpio_chip;
0101 
0102     mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0103     if (!mem)
0104         return -EINVAL;
0105 
0106     base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
0107     if (!base)
0108         return -ENOMEM;
0109 
0110     /*
0111      * Duplicated SYS_MCI pseudo-GPIO controller for compatibility with
0112      * older trees using sysreg node for MMC control lines.
0113      */
0114     mmc_gpio_chip = devm_kzalloc(&pdev->dev, sizeof(*mmc_gpio_chip),
0115             GFP_KERNEL);
0116     if (!mmc_gpio_chip)
0117         return -ENOMEM;
0118     bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI,
0119             NULL, NULL, NULL, NULL, 0);
0120     mmc_gpio_chip->ngpio = 2;
0121     devm_gpiochip_add_data(&pdev->dev, mmc_gpio_chip, NULL);
0122 
0123     return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
0124             vexpress_sysreg_cells,
0125             ARRAY_SIZE(vexpress_sysreg_cells), mem, 0, NULL);
0126 }
0127 
0128 static const struct of_device_id vexpress_sysreg_match[] = {
0129     { .compatible = "arm,vexpress-sysreg", },
0130     {},
0131 };
0132 MODULE_DEVICE_TABLE(of, vexpress_sysreg_match);
0133 
0134 static struct platform_driver vexpress_sysreg_driver = {
0135     .driver = {
0136         .name = "vexpress-sysreg",
0137         .of_match_table = vexpress_sysreg_match,
0138     },
0139     .probe = vexpress_sysreg_probe,
0140 };
0141 
0142 module_platform_driver(vexpress_sysreg_driver);
0143 MODULE_LICENSE("GPL v2");