Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * AMD CS5535/CS5536 GPIO driver
0004  * Copyright (C) 2006  Advanced Micro Devices, Inc.
0005  * Copyright (C) 2007-2009  Andres Salomon <dilinger@collabora.co.uk>
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/spinlock.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/gpio/driver.h>
0013 #include <linux/io.h>
0014 #include <linux/cs5535.h>
0015 #include <asm/msr.h>
0016 
0017 #define DRV_NAME "cs5535-gpio"
0018 
0019 /*
0020  * Some GPIO pins
0021  *  31-29,23 : reserved (always mask out)
0022  *  28       : Power Button
0023  *  26       : PME#
0024  *  22-16    : LPC
0025  *  14,15    : SMBus
0026  *  9,8      : UART1
0027  *  7        : PCI INTB
0028  *  3,4      : UART2/DDC
0029  *  2        : IDE_IRQ0
0030  *  1        : AC_BEEP
0031  *  0        : PCI INTA
0032  *
0033  * If a mask was not specified, allow all except
0034  * reserved and Power Button
0035  */
0036 #define GPIO_DEFAULT_MASK 0x0F7FFFFF
0037 
0038 static ulong mask = GPIO_DEFAULT_MASK;
0039 module_param_named(mask, mask, ulong, 0444);
0040 MODULE_PARM_DESC(mask, "GPIO channel mask.");
0041 
0042 /*
0043  * FIXME: convert this singleton driver to use the state container
0044  * design pattern, see Documentation/driver-api/driver-model/design-patterns.rst
0045  */
0046 static struct cs5535_gpio_chip {
0047     struct gpio_chip chip;
0048     resource_size_t base;
0049 
0050     struct platform_device *pdev;
0051     spinlock_t lock;
0052 } cs5535_gpio_chip;
0053 
0054 /*
0055  * The CS5535/CS5536 GPIOs support a number of extra features not defined
0056  * by the gpio_chip API, so these are exported.  For a full list of the
0057  * registers, see include/linux/cs5535.h.
0058  */
0059 
0060 static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
0061         unsigned int reg)
0062 {
0063     unsigned long addr = chip->base + 0x80 + reg;
0064 
0065     /*
0066      * According to the CS5536 errata (#36), after suspend
0067      * a write to the high bank GPIO register will clear all
0068      * non-selected bits; the recommended workaround is a
0069      * read-modify-write operation.
0070      *
0071      * Don't apply this errata to the edge status GPIOs, as writing
0072      * to their lower bits will clear them.
0073      */
0074     if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
0075         if (val & 0xffff)
0076             val |= (inl(addr) & 0xffff); /* ignore the high bits */
0077         else
0078             val |= (inl(addr) ^ (val >> 16));
0079     }
0080     outl(val, addr);
0081 }
0082 
0083 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
0084         unsigned int reg)
0085 {
0086     if (offset < 16)
0087         /* low bank register */
0088         outl(1 << offset, chip->base + reg);
0089     else
0090         /* high bank register */
0091         errata_outl(chip, 1 << (offset - 16), reg);
0092 }
0093 
0094 void cs5535_gpio_set(unsigned offset, unsigned int reg)
0095 {
0096     struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
0097     unsigned long flags;
0098 
0099     spin_lock_irqsave(&chip->lock, flags);
0100     __cs5535_gpio_set(chip, offset, reg);
0101     spin_unlock_irqrestore(&chip->lock, flags);
0102 }
0103 EXPORT_SYMBOL_GPL(cs5535_gpio_set);
0104 
0105 static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
0106         unsigned int reg)
0107 {
0108     if (offset < 16)
0109         /* low bank register */
0110         outl(1 << (offset + 16), chip->base + reg);
0111     else
0112         /* high bank register */
0113         errata_outl(chip, 1 << offset, reg);
0114 }
0115 
0116 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
0117 {
0118     struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
0119     unsigned long flags;
0120 
0121     spin_lock_irqsave(&chip->lock, flags);
0122     __cs5535_gpio_clear(chip, offset, reg);
0123     spin_unlock_irqrestore(&chip->lock, flags);
0124 }
0125 EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
0126 
0127 int cs5535_gpio_isset(unsigned offset, unsigned int reg)
0128 {
0129     struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
0130     unsigned long flags;
0131     long val;
0132 
0133     spin_lock_irqsave(&chip->lock, flags);
0134     if (offset < 16)
0135         /* low bank register */
0136         val = inl(chip->base + reg);
0137     else {
0138         /* high bank register */
0139         val = inl(chip->base + 0x80 + reg);
0140         offset -= 16;
0141     }
0142     spin_unlock_irqrestore(&chip->lock, flags);
0143 
0144     return (val & (1 << offset)) ? 1 : 0;
0145 }
0146 EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
0147 
0148 int cs5535_gpio_set_irq(unsigned group, unsigned irq)
0149 {
0150     uint32_t lo, hi;
0151 
0152     if (group > 7 || irq > 15)
0153         return -EINVAL;
0154 
0155     rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
0156 
0157     lo &= ~(0xF << (group * 4));
0158     lo |= (irq & 0xF) << (group * 4);
0159 
0160     wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
0161     return 0;
0162 }
0163 EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq);
0164 
0165 void cs5535_gpio_setup_event(unsigned offset, int pair, int pme)
0166 {
0167     struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
0168     uint32_t shift = (offset % 8) * 4;
0169     unsigned long flags;
0170     uint32_t val;
0171 
0172     if (offset >= 24)
0173         offset = GPIO_MAP_W;
0174     else if (offset >= 16)
0175         offset = GPIO_MAP_Z;
0176     else if (offset >= 8)
0177         offset = GPIO_MAP_Y;
0178     else
0179         offset = GPIO_MAP_X;
0180 
0181     spin_lock_irqsave(&chip->lock, flags);
0182     val = inl(chip->base + offset);
0183 
0184     /* Clear whatever was there before */
0185     val &= ~(0xF << shift);
0186 
0187     /* Set the new value */
0188     val |= ((pair & 7) << shift);
0189 
0190     /* Set the PME bit if this is a PME event */
0191     if (pme)
0192         val |= (1 << (shift + 3));
0193 
0194     outl(val, chip->base + offset);
0195     spin_unlock_irqrestore(&chip->lock, flags);
0196 }
0197 EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event);
0198 
0199 /*
0200  * Generic gpio_chip API support.
0201  */
0202 
0203 static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
0204 {
0205     struct cs5535_gpio_chip *chip = gpiochip_get_data(c);
0206     unsigned long flags;
0207 
0208     spin_lock_irqsave(&chip->lock, flags);
0209 
0210     /* check if this pin is available */
0211     if ((mask & (1 << offset)) == 0) {
0212         dev_info(&chip->pdev->dev,
0213             "pin %u is not available (check mask)\n", offset);
0214         spin_unlock_irqrestore(&chip->lock, flags);
0215         return -EINVAL;
0216     }
0217 
0218     /* disable output aux 1 & 2 on this pin */
0219     __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
0220     __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
0221 
0222     /* disable input aux 1 on this pin */
0223     __cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
0224 
0225     spin_unlock_irqrestore(&chip->lock, flags);
0226 
0227     return 0;
0228 }
0229 
0230 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
0231 {
0232     return cs5535_gpio_isset(offset, GPIO_READ_BACK);
0233 }
0234 
0235 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
0236 {
0237     if (val)
0238         cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
0239     else
0240         cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
0241 }
0242 
0243 static int chip_direction_input(struct gpio_chip *c, unsigned offset)
0244 {
0245     struct cs5535_gpio_chip *chip = gpiochip_get_data(c);
0246     unsigned long flags;
0247 
0248     spin_lock_irqsave(&chip->lock, flags);
0249     __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
0250     __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
0251     spin_unlock_irqrestore(&chip->lock, flags);
0252 
0253     return 0;
0254 }
0255 
0256 static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
0257 {
0258     struct cs5535_gpio_chip *chip = gpiochip_get_data(c);
0259     unsigned long flags;
0260 
0261     spin_lock_irqsave(&chip->lock, flags);
0262 
0263     __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
0264     __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
0265     if (val)
0266         __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
0267     else
0268         __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
0269 
0270     spin_unlock_irqrestore(&chip->lock, flags);
0271 
0272     return 0;
0273 }
0274 
0275 static const char * const cs5535_gpio_names[] = {
0276     "GPIO0", "GPIO1", "GPIO2", "GPIO3",
0277     "GPIO4", "GPIO5", "GPIO6", "GPIO7",
0278     "GPIO8", "GPIO9", "GPIO10", "GPIO11",
0279     "GPIO12", "GPIO13", "GPIO14", "GPIO15",
0280     "GPIO16", "GPIO17", "GPIO18", "GPIO19",
0281     "GPIO20", "GPIO21", "GPIO22", NULL,
0282     "GPIO24", "GPIO25", "GPIO26", "GPIO27",
0283     "GPIO28", NULL, NULL, NULL,
0284 };
0285 
0286 static struct cs5535_gpio_chip cs5535_gpio_chip = {
0287     .chip = {
0288         .owner = THIS_MODULE,
0289         .label = DRV_NAME,
0290 
0291         .base = 0,
0292         .ngpio = 32,
0293         .names = cs5535_gpio_names,
0294         .request = chip_gpio_request,
0295 
0296         .get = chip_gpio_get,
0297         .set = chip_gpio_set,
0298 
0299         .direction_input = chip_direction_input,
0300         .direction_output = chip_direction_output,
0301     },
0302 };
0303 
0304 static int cs5535_gpio_probe(struct platform_device *pdev)
0305 {
0306     struct resource *res;
0307     int err = -EIO;
0308     ulong mask_orig = mask;
0309 
0310     /* There are two ways to get the GPIO base address; one is by
0311      * fetching it from MSR_LBAR_GPIO, the other is by reading the
0312      * PCI BAR info.  The latter method is easier (especially across
0313      * different architectures), so we'll stick with that for now.  If
0314      * it turns out to be unreliable in the face of crappy BIOSes, we
0315      * can always go back to using MSRs.. */
0316 
0317     res = platform_get_resource(pdev, IORESOURCE_IO, 0);
0318     if (!res) {
0319         dev_err(&pdev->dev, "can't fetch device resource info\n");
0320         return err;
0321     }
0322 
0323     if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
0324                  pdev->name)) {
0325         dev_err(&pdev->dev, "can't request region\n");
0326         return err;
0327     }
0328 
0329     /* set up the driver-specific struct */
0330     cs5535_gpio_chip.base = res->start;
0331     cs5535_gpio_chip.pdev = pdev;
0332     spin_lock_init(&cs5535_gpio_chip.lock);
0333 
0334     dev_info(&pdev->dev, "reserved resource region %pR\n", res);
0335 
0336     /* mask out reserved pins */
0337     mask &= 0x1F7FFFFF;
0338 
0339     /* do not allow pin 28, Power Button, as there's special handling
0340      * in the PMC needed. (note 12, p. 48) */
0341     mask &= ~(1 << 28);
0342 
0343     if (mask_orig != mask)
0344         dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
0345                 mask_orig, mask);
0346 
0347     /* finally, register with the generic GPIO API */
0348     return devm_gpiochip_add_data(&pdev->dev, &cs5535_gpio_chip.chip,
0349                       &cs5535_gpio_chip);
0350 }
0351 
0352 static struct platform_driver cs5535_gpio_driver = {
0353     .driver = {
0354         .name = DRV_NAME,
0355     },
0356     .probe = cs5535_gpio_probe,
0357 };
0358 
0359 module_platform_driver(cs5535_gpio_driver);
0360 
0361 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
0362 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
0363 MODULE_LICENSE("GPL");
0364 MODULE_ALIAS("platform:" DRV_NAME);