linux/drivers/gpio/gpio-hlwd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// Copyright (C) 2008-2009 The GameCube Linux Team
   3// Copyright (C) 2008,2009 Albert Herranz
   4// Copyright (C) 2017-2018 Jonathan Neuschäfer
   5//
   6// Nintendo Wii (Hollywood) GPIO driver
   7
   8#include <linux/gpio/driver.h>
   9#include <linux/io.h>
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/of.h>
  13#include <linux/of_platform.h>
  14#include <linux/slab.h>
  15
  16/*
  17 * Register names and offsets courtesy of WiiBrew:
  18 * https://wiibrew.org/wiki/Hardware/Hollywood_GPIOs
  19 *
  20 * Note that for most registers, there are two versions:
  21 * - HW_GPIOB_* Is always accessible by the Broadway PowerPC core, but does
  22 *   always give access to all GPIO lines
  23 * - HW_GPIO_* Is only accessible by the Broadway PowerPC code if the memory
  24 *   firewall (AHBPROT) in the Hollywood chipset has been configured to allow
  25 *   such access.
  26 *
  27 * The ownership of each GPIO line can be configured in the HW_GPIO_OWNER
  28 * register: A one bit configures the line for access via the HW_GPIOB_*
  29 * registers, a zero bit indicates access via HW_GPIO_*. This driver uses
  30 * HW_GPIOB_*.
  31 */
  32#define HW_GPIOB_OUT            0x00
  33#define HW_GPIOB_DIR            0x04
  34#define HW_GPIOB_IN             0x08
  35#define HW_GPIOB_INTLVL         0x0c
  36#define HW_GPIOB_INTFLAG        0x10
  37#define HW_GPIOB_INTMASK        0x14
  38#define HW_GPIOB_INMIR          0x18
  39#define HW_GPIO_ENABLE          0x1c
  40#define HW_GPIO_OUT             0x20
  41#define HW_GPIO_DIR             0x24
  42#define HW_GPIO_IN              0x28
  43#define HW_GPIO_INTLVL          0x2c
  44#define HW_GPIO_INTFLAG         0x30
  45#define HW_GPIO_INTMASK         0x34
  46#define HW_GPIO_INMIR           0x38
  47#define HW_GPIO_OWNER           0x3c
  48
  49struct hlwd_gpio {
  50        struct gpio_chip gpioc;
  51        struct irq_chip irqc;
  52        void __iomem *regs;
  53        int irq;
  54        u32 edge_emulation;
  55        u32 rising_edge, falling_edge;
  56};
  57
  58static void hlwd_gpio_irqhandler(struct irq_desc *desc)
  59{
  60        struct hlwd_gpio *hlwd =
  61                gpiochip_get_data(irq_desc_get_handler_data(desc));
  62        struct irq_chip *chip = irq_desc_get_chip(desc);
  63        unsigned long flags;
  64        unsigned long pending;
  65        int hwirq;
  66        u32 emulated_pending;
  67
  68        spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
  69        pending = ioread32be(hlwd->regs + HW_GPIOB_INTFLAG);
  70        pending &= ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
  71
  72        /* Treat interrupts due to edge trigger emulation separately */
  73        emulated_pending = hlwd->edge_emulation & pending;
  74        pending &= ~emulated_pending;
  75        if (emulated_pending) {
  76                u32 level, rising, falling;
  77
  78                level = ioread32be(hlwd->regs + HW_GPIOB_INTLVL);
  79                rising = level & emulated_pending;
  80                falling = ~level & emulated_pending;
  81
  82                /* Invert the levels */
  83                iowrite32be(level ^ emulated_pending,
  84                            hlwd->regs + HW_GPIOB_INTLVL);
  85
  86                /* Ack all emulated-edge interrupts */
  87                iowrite32be(emulated_pending, hlwd->regs + HW_GPIOB_INTFLAG);
  88
  89                /* Signal interrupts only on the correct edge */
  90                rising &= hlwd->rising_edge;
  91                falling &= hlwd->falling_edge;
  92
  93                /* Mark emulated interrupts as pending */
  94                pending |= rising | falling;
  95        }
  96        spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
  97
  98        chained_irq_enter(chip, desc);
  99
 100        for_each_set_bit(hwirq, &pending, 32) {
 101                int irq = irq_find_mapping(hlwd->gpioc.irq.domain, hwirq);
 102
 103                generic_handle_irq(irq);
 104        }
 105
 106        chained_irq_exit(chip, desc);
 107}
 108
 109static void hlwd_gpio_irq_ack(struct irq_data *data)
 110{
 111        struct hlwd_gpio *hlwd =
 112                gpiochip_get_data(irq_data_get_irq_chip_data(data));
 113
 114        iowrite32be(BIT(data->hwirq), hlwd->regs + HW_GPIOB_INTFLAG);
 115}
 116
 117static void hlwd_gpio_irq_mask(struct irq_data *data)
 118{
 119        struct hlwd_gpio *hlwd =
 120                gpiochip_get_data(irq_data_get_irq_chip_data(data));
 121        unsigned long flags;
 122        u32 mask;
 123
 124        spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
 125        mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
 126        mask &= ~BIT(data->hwirq);
 127        iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
 128        spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
 129}
 130
 131static void hlwd_gpio_irq_unmask(struct irq_data *data)
 132{
 133        struct hlwd_gpio *hlwd =
 134                gpiochip_get_data(irq_data_get_irq_chip_data(data));
 135        unsigned long flags;
 136        u32 mask;
 137
 138        spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
 139        mask = ioread32be(hlwd->regs + HW_GPIOB_INTMASK);
 140        mask |= BIT(data->hwirq);
 141        iowrite32be(mask, hlwd->regs + HW_GPIOB_INTMASK);
 142        spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
 143}
 144
 145static void hlwd_gpio_irq_enable(struct irq_data *data)
 146{
 147        hlwd_gpio_irq_ack(data);
 148        hlwd_gpio_irq_unmask(data);
 149}
 150
 151static void hlwd_gpio_irq_setup_emulation(struct hlwd_gpio *hlwd, int hwirq,
 152                                          unsigned int flow_type)
 153{
 154        u32 level, state;
 155
 156        /* Set the trigger level to the inactive level */
 157        level = ioread32be(hlwd->regs + HW_GPIOB_INTLVL);
 158        state = ioread32be(hlwd->regs + HW_GPIOB_IN) & BIT(hwirq);
 159        level &= ~BIT(hwirq);
 160        level |= state ^ BIT(hwirq);
 161        iowrite32be(level, hlwd->regs + HW_GPIOB_INTLVL);
 162
 163        hlwd->edge_emulation |= BIT(hwirq);
 164        hlwd->rising_edge &= ~BIT(hwirq);
 165        hlwd->falling_edge &= ~BIT(hwirq);
 166        if (flow_type & IRQ_TYPE_EDGE_RISING)
 167                hlwd->rising_edge |= BIT(hwirq);
 168        if (flow_type & IRQ_TYPE_EDGE_FALLING)
 169                hlwd->falling_edge |= BIT(hwirq);
 170}
 171
 172static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
 173{
 174        struct hlwd_gpio *hlwd =
 175                gpiochip_get_data(irq_data_get_irq_chip_data(data));
 176        unsigned long flags;
 177        u32 level;
 178
 179        spin_lock_irqsave(&hlwd->gpioc.bgpio_lock, flags);
 180
 181        hlwd->edge_emulation &= ~BIT(data->hwirq);
 182
 183        switch (flow_type) {
 184        case IRQ_TYPE_LEVEL_HIGH:
 185                level = ioread32be(hlwd->regs + HW_GPIOB_INTLVL);
 186                level |= BIT(data->hwirq);
 187                iowrite32be(level, hlwd->regs + HW_GPIOB_INTLVL);
 188                break;
 189        case IRQ_TYPE_LEVEL_LOW:
 190                level = ioread32be(hlwd->regs + HW_GPIOB_INTLVL);
 191                level &= ~BIT(data->hwirq);
 192                iowrite32be(level, hlwd->regs + HW_GPIOB_INTLVL);
 193                break;
 194        case IRQ_TYPE_EDGE_RISING:
 195        case IRQ_TYPE_EDGE_FALLING:
 196        case IRQ_TYPE_EDGE_BOTH:
 197                hlwd_gpio_irq_setup_emulation(hlwd, data->hwirq, flow_type);
 198                break;
 199        default:
 200                spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
 201                return -EINVAL;
 202        }
 203
 204        spin_unlock_irqrestore(&hlwd->gpioc.bgpio_lock, flags);
 205        return 0;
 206}
 207
 208static int hlwd_gpio_probe(struct platform_device *pdev)
 209{
 210        struct hlwd_gpio *hlwd;
 211        struct resource *regs_resource;
 212        u32 ngpios;
 213        int res;
 214
 215        hlwd = devm_kzalloc(&pdev->dev, sizeof(*hlwd), GFP_KERNEL);
 216        if (!hlwd)
 217                return -ENOMEM;
 218
 219        regs_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 220        hlwd->regs = devm_ioremap_resource(&pdev->dev, regs_resource);
 221        if (IS_ERR(hlwd->regs))
 222                return PTR_ERR(hlwd->regs);
 223
 224        /*
 225         * Claim all GPIOs using the OWNER register. This will not work on
 226         * systems where the AHBPROT memory firewall hasn't been configured to
 227         * permit PPC access to HW_GPIO_*.
 228         *
 229         * Note that this has to happen before bgpio_init reads the
 230         * HW_GPIOB_OUT and HW_GPIOB_DIR, because otherwise it reads the wrong
 231         * values.
 232         */
 233        iowrite32be(0xffffffff, hlwd->regs + HW_GPIO_OWNER);
 234
 235        res = bgpio_init(&hlwd->gpioc, &pdev->dev, 4,
 236                        hlwd->regs + HW_GPIOB_IN, hlwd->regs + HW_GPIOB_OUT,
 237                        NULL, hlwd->regs + HW_GPIOB_DIR, NULL,
 238                        BGPIOF_BIG_ENDIAN_BYTE_ORDER);
 239        if (res < 0) {
 240                dev_warn(&pdev->dev, "bgpio_init failed: %d\n", res);
 241                return res;
 242        }
 243
 244        res = of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios);
 245        if (res)
 246                ngpios = 32;
 247        hlwd->gpioc.ngpio = ngpios;
 248
 249        res = devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
 250        if (res)
 251                return res;
 252
 253        /* Mask and ack all interrupts */
 254        iowrite32be(0, hlwd->regs + HW_GPIOB_INTMASK);
 255        iowrite32be(0xffffffff, hlwd->regs + HW_GPIOB_INTFLAG);
 256
 257        /*
 258         * If this GPIO controller is not marked as an interrupt controller in
 259         * the DT, return.
 260         */
 261        if (!of_property_read_bool(pdev->dev.of_node, "interrupt-controller"))
 262                return 0;
 263
 264        hlwd->irq = platform_get_irq(pdev, 0);
 265        if (hlwd->irq < 0) {
 266                dev_info(&pdev->dev, "platform_get_irq returned %d\n",
 267                         hlwd->irq);
 268                return hlwd->irq;
 269        }
 270
 271        hlwd->irqc.name = dev_name(&pdev->dev);
 272        hlwd->irqc.irq_mask = hlwd_gpio_irq_mask;
 273        hlwd->irqc.irq_unmask = hlwd_gpio_irq_unmask;
 274        hlwd->irqc.irq_enable = hlwd_gpio_irq_enable;
 275        hlwd->irqc.irq_set_type = hlwd_gpio_irq_set_type;
 276
 277        res = gpiochip_irqchip_add(&hlwd->gpioc, &hlwd->irqc, 0,
 278                                   handle_level_irq, IRQ_TYPE_NONE);
 279        if (res)
 280                return res;
 281
 282        gpiochip_set_chained_irqchip(&hlwd->gpioc, &hlwd->irqc,
 283                                     hlwd->irq, hlwd_gpio_irqhandler);
 284
 285        return 0;
 286}
 287
 288static const struct of_device_id hlwd_gpio_match[] = {
 289        { .compatible = "nintendo,hollywood-gpio", },
 290        {},
 291};
 292MODULE_DEVICE_TABLE(of, hlwd_gpio_match);
 293
 294static struct platform_driver hlwd_gpio_driver = {
 295        .driver = {
 296                .name           = "gpio-hlwd",
 297                .of_match_table = hlwd_gpio_match,
 298        },
 299        .probe  = hlwd_gpio_probe,
 300};
 301module_platform_driver(hlwd_gpio_driver);
 302
 303MODULE_AUTHOR("Jonathan Neuschäfer <j.neuschaefer@gmx.net>");
 304MODULE_DESCRIPTION("Nintendo Wii GPIO driver");
 305MODULE_LICENSE("GPL");
 306