Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright 2008 Simtec Electronics
0004  *  http://armlinux.simtec.co.uk/
0005  *  Ben Dooks <ben@simtec.co.uk>
0006  *
0007  * S3C Platform - GPIO core
0008  */
0009 
0010 #ifndef __PLAT_SAMSUNG_GPIO_CORE_H
0011 #define __PLAT_SAMSUNG_GPIO_CORE_H
0012 
0013 /* Bring in machine-local definitions, especially S3C_GPIO_END */
0014 #include "gpio-samsung.h"
0015 #include <linux/gpio/driver.h>
0016 
0017 #define GPIOCON_OFF (0x00)
0018 #define GPIODAT_OFF (0x04)
0019 
0020 #define con_4bit_shift(__off) ((__off) * 4)
0021 
0022 /* Define the core gpiolib support functions that the s3c platforms may
0023  * need to extend or change depending on the hardware and the s3c chip
0024  * selected at build or found at run time.
0025  *
0026  * These definitions are not intended for driver inclusion, there is
0027  * nothing here that should not live outside the platform and core
0028  * specific code.
0029 */
0030 
0031 struct samsung_gpio_chip;
0032 
0033 /**
0034  * struct samsung_gpio_pm - power management (suspend/resume) information
0035  * @save: Routine to save the state of the GPIO block
0036  * @resume: Routine to resume the GPIO block.
0037  */
0038 struct samsung_gpio_pm {
0039     void (*save)(struct samsung_gpio_chip *chip);
0040     void (*resume)(struct samsung_gpio_chip *chip);
0041 };
0042 
0043 struct samsung_gpio_cfg;
0044 
0045 /**
0046  * struct samsung_gpio_chip - wrapper for specific implementation of gpio
0047  * @chip: The chip structure to be exported via gpiolib.
0048  * @base: The base pointer to the gpio configuration registers.
0049  * @group: The group register number for gpio interrupt support.
0050  * @irq_base: The base irq number.
0051  * @config: special function and pull-resistor control information.
0052  * @lock: Lock for exclusive access to this gpio bank.
0053  * @pm_save: Save information for suspend/resume support.
0054  * @bitmap_gpio_int: Bitmap for representing GPIO interrupt or not.
0055  *
0056  * This wrapper provides the necessary information for the Samsung
0057  * specific gpios being registered with gpiolib.
0058  *
0059  * The lock protects each gpio bank from multiple access of the shared
0060  * configuration registers, or from reading of data whilst another thread
0061  * is writing to the register set.
0062  *
0063  * Each chip has its own lock to avoid any  contention between different
0064  * CPU cores trying to get one lock for different GPIO banks, where each
0065  * bank of GPIO has its own register space and configuration registers.
0066  */
0067 struct samsung_gpio_chip {
0068     struct gpio_chip    chip;
0069     struct samsung_gpio_cfg *config;
0070     struct samsung_gpio_pm  *pm;
0071     void __iomem        *base;
0072     int         irq_base;
0073     int         group;
0074     spinlock_t       lock;
0075 #ifdef CONFIG_PM
0076     u32         pm_save[4];
0077 #endif
0078     u32         bitmap_gpio_int;
0079 };
0080 
0081 static inline struct samsung_gpio_chip *to_samsung_gpio(struct gpio_chip *gpc)
0082 {
0083     return container_of(gpc, struct samsung_gpio_chip, chip);
0084 }
0085 
0086 /**
0087  * samsung_gpiolib_to_irq - convert gpio pin to irq number
0088  * @chip: The gpio chip that the pin belongs to.
0089  * @offset: The offset of the pin in the chip.
0090  *
0091  * This helper returns the irq number calculated from the chip->irq_base and
0092  * the provided offset.
0093  */
0094 extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
0095 
0096 /* exported for core SoC support to change */
0097 extern struct samsung_gpio_cfg s3c24xx_gpiocfg_default;
0098 
0099 #ifdef CONFIG_S3C_GPIO_TRACK
0100 extern struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
0101 
0102 static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int chip)
0103 {
0104     return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
0105 }
0106 #else
0107 /* machine specific code should provide samsung_gpiolib_getchip */
0108 
0109 extern struct samsung_gpio_chip s3c24xx_gpios[];
0110 
0111 static inline struct samsung_gpio_chip *samsung_gpiolib_getchip(unsigned int pin)
0112 {
0113     struct samsung_gpio_chip *chip;
0114 
0115     if (pin > S3C_GPIO_END)
0116         return NULL;
0117 
0118     chip = &s3c24xx_gpios[pin/32];
0119     return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
0120 }
0121 
0122 static inline void s3c_gpiolib_track(struct samsung_gpio_chip *chip) { }
0123 #endif
0124 
0125 #ifdef CONFIG_PM
0126 extern struct samsung_gpio_pm samsung_gpio_pm_1bit;
0127 extern struct samsung_gpio_pm samsung_gpio_pm_2bit;
0128 extern struct samsung_gpio_pm samsung_gpio_pm_4bit;
0129 #define __gpio_pm(x) x
0130 #else
0131 #define samsung_gpio_pm_1bit NULL
0132 #define samsung_gpio_pm_2bit NULL
0133 #define samsung_gpio_pm_4bit NULL
0134 #define __gpio_pm(x) NULL
0135 
0136 #endif /* CONFIG_PM */
0137 
0138 /* locking wrappers to deal with multiple access to the same gpio bank */
0139 #define samsung_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
0140 #define samsung_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
0141 
0142 #endif /* __PLAT_SAMSUNG_GPIO_CORE_H */