linux/arch/powerpc/platforms/powermac/pfunc_base.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/types.h>
   3#include <linux/init.h>
   4#include <linux/delay.h>
   5#include <linux/kernel.h>
   6#include <linux/interrupt.h>
   7#include <linux/spinlock.h>
   8#include <linux/of_irq.h>
   9
  10#include <asm/pmac_feature.h>
  11#include <asm/pmac_pfunc.h>
  12
  13#undef DEBUG
  14#ifdef DEBUG
  15#define DBG(fmt...)     printk(fmt)
  16#else
  17#define DBG(fmt...)
  18#endif
  19
  20static irqreturn_t macio_gpio_irq(int irq, void *data)
  21{
  22        pmf_do_irq(data);
  23
  24        return IRQ_HANDLED;
  25}
  26
  27static int macio_do_gpio_irq_enable(struct pmf_function *func)
  28{
  29        unsigned int irq = irq_of_parse_and_map(func->node, 0);
  30        if (!irq)
  31                return -EINVAL;
  32        return request_irq(irq, macio_gpio_irq, 0, func->node->name, func);
  33}
  34
  35static int macio_do_gpio_irq_disable(struct pmf_function *func)
  36{
  37        unsigned int irq = irq_of_parse_and_map(func->node, 0);
  38        if (!irq)
  39                return -EINVAL;
  40        free_irq(irq, func);
  41        return 0;
  42}
  43
  44static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask)
  45{
  46        u8 __iomem *addr = (u8 __iomem *)func->driver_data;
  47        unsigned long flags;
  48        u8 tmp;
  49
  50        /* Check polarity */
  51        if (args && args->count && !args->u[0].v)
  52                value = ~value;
  53
  54        /* Toggle the GPIO */
  55        raw_spin_lock_irqsave(&feature_lock, flags);
  56        tmp = readb(addr);
  57        tmp = (tmp & ~mask) | (value & mask);
  58        DBG("Do write 0x%02x to GPIO %pOF (%p)\n",
  59            tmp, func->node, addr);
  60        writeb(tmp, addr);
  61        raw_spin_unlock_irqrestore(&feature_lock, flags);
  62
  63        return 0;
  64}
  65
  66static int macio_do_gpio_read(PMF_STD_ARGS, u8 mask, int rshift, u8 xor)
  67{
  68        u8 __iomem *addr = (u8 __iomem *)func->driver_data;
  69        u32 value;
  70
  71        /* Check if we have room for reply */
  72        if (args == NULL || args->count == 0 || args->u[0].p == NULL)
  73                return -EINVAL;
  74
  75        value = readb(addr);
  76        *args->u[0].p = ((value & mask) >> rshift) ^ xor;
  77
  78        return 0;
  79}
  80
  81static int macio_do_delay(PMF_STD_ARGS, u32 duration)
  82{
  83        /* assume we can sleep ! */
  84        msleep((duration + 999) / 1000);
  85        return 0;
  86}
  87
  88static struct pmf_handlers macio_gpio_handlers = {
  89        .irq_enable     = macio_do_gpio_irq_enable,
  90        .irq_disable    = macio_do_gpio_irq_disable,
  91        .write_gpio     = macio_do_gpio_write,
  92        .read_gpio      = macio_do_gpio_read,
  93        .delay          = macio_do_delay,
  94};
  95
  96static void macio_gpio_init_one(struct macio_chip *macio)
  97{
  98        struct device_node *gparent, *gp;
  99
 100        /*
 101         * Find the "gpio" parent node
 102         */
 103
 104        for_each_child_of_node(macio->of_node, gparent)
 105                if (of_node_name_eq(gparent, "gpio"))
 106                        break;
 107        if (gparent == NULL)
 108                return;
 109
 110        DBG("Installing GPIO functions for macio %pOF\n",
 111            macio->of_node);
 112
 113        /*
 114         * Ok, got one, we dont need anything special to track them down, so
 115         * we just create them all
 116         */
 117        for_each_child_of_node(gparent, gp) {
 118                const u32 *reg = of_get_property(gp, "reg", NULL);
 119                unsigned long offset;
 120                if (reg == NULL)
 121                        continue;
 122                offset = *reg;
 123                /* Deal with old style device-tree. We can safely hard code the
 124                 * offset for now too even if it's a bit gross ...
 125                 */
 126                if (offset < 0x50)
 127                        offset += 0x50;
 128                offset += (unsigned long)macio->base;
 129                pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset);
 130        }
 131
 132        DBG("Calling initial GPIO functions for macio %pOF\n",
 133            macio->of_node);
 134
 135        /* And now we run all the init ones */
 136        for_each_child_of_node(gparent, gp)
 137                pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
 138
 139        /* Note: We do not at this point implement the "at sleep" or "at wake"
 140         * functions. I yet to find any for GPIOs anyway
 141         */
 142}
 143
 144static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
 145{
 146        struct macio_chip *macio = func->driver_data;
 147        unsigned long flags;
 148
 149        raw_spin_lock_irqsave(&feature_lock, flags);
 150        MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask));
 151        raw_spin_unlock_irqrestore(&feature_lock, flags);
 152        return 0;
 153}
 154
 155static int macio_do_read_reg32(PMF_STD_ARGS, u32 offset)
 156{
 157        struct macio_chip *macio = func->driver_data;
 158
 159        /* Check if we have room for reply */
 160        if (args == NULL || args->count == 0 || args->u[0].p == NULL)
 161                return -EINVAL;
 162
 163        *args->u[0].p = MACIO_IN32(offset);
 164        return 0;
 165}
 166
 167static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask)
 168{
 169        struct macio_chip *macio = func->driver_data;
 170        unsigned long flags;
 171
 172        raw_spin_lock_irqsave(&feature_lock, flags);
 173        MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask));
 174        raw_spin_unlock_irqrestore(&feature_lock, flags);
 175        return 0;
 176}
 177
 178static int macio_do_read_reg8(PMF_STD_ARGS, u32 offset)
 179{
 180        struct macio_chip *macio = func->driver_data;
 181
 182        /* Check if we have room for reply */
 183        if (args == NULL || args->count == 0 || args->u[0].p == NULL)
 184                return -EINVAL;
 185
 186        *((u8 *)(args->u[0].p)) = MACIO_IN8(offset);
 187        return 0;
 188}
 189
 190static int macio_do_read_reg32_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
 191                                    u32 shift, u32 xor)
 192{
 193        struct macio_chip *macio = func->driver_data;
 194
 195        /* Check if we have room for reply */
 196        if (args == NULL || args->count == 0 || args->u[0].p == NULL)
 197                return -EINVAL;
 198
 199        *args->u[0].p = ((MACIO_IN32(offset) & mask) >> shift) ^ xor;
 200        return 0;
 201}
 202
 203static int macio_do_read_reg8_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
 204                                   u32 shift, u32 xor)
 205{
 206        struct macio_chip *macio = func->driver_data;
 207
 208        /* Check if we have room for reply */
 209        if (args == NULL || args->count == 0 || args->u[0].p == NULL)
 210                return -EINVAL;
 211
 212        *((u8 *)(args->u[0].p)) = ((MACIO_IN8(offset) & mask) >> shift) ^ xor;
 213        return 0;
 214}
 215
 216static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift,
 217                                    u32 mask)
 218{
 219        struct macio_chip *macio = func->driver_data;
 220        unsigned long flags;
 221        u32 tmp, val;
 222
 223        /* Check args */
 224        if (args == NULL || args->count == 0)
 225                return -EINVAL;
 226
 227        raw_spin_lock_irqsave(&feature_lock, flags);
 228        tmp = MACIO_IN32(offset);
 229        val = args->u[0].v << shift;
 230        tmp = (tmp & ~mask) | (val & mask);
 231        MACIO_OUT32(offset, tmp);
 232        raw_spin_unlock_irqrestore(&feature_lock, flags);
 233        return 0;
 234}
 235
 236static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift,
 237                                   u32 mask)
 238{
 239        struct macio_chip *macio = func->driver_data;
 240        unsigned long flags;
 241        u32 tmp, val;
 242
 243        /* Check args */
 244        if (args == NULL || args->count == 0)
 245                return -EINVAL;
 246
 247        raw_spin_lock_irqsave(&feature_lock, flags);
 248        tmp = MACIO_IN8(offset);
 249        val = args->u[0].v << shift;
 250        tmp = (tmp & ~mask) | (val & mask);
 251        MACIO_OUT8(offset, tmp);
 252        raw_spin_unlock_irqrestore(&feature_lock, flags);
 253        return 0;
 254}
 255
 256static struct pmf_handlers macio_mmio_handlers = {
 257        .write_reg32            = macio_do_write_reg32,
 258        .read_reg32             = macio_do_read_reg32,
 259        .write_reg8             = macio_do_write_reg8,
 260        .read_reg8              = macio_do_read_reg8,
 261        .read_reg32_msrx        = macio_do_read_reg32_msrx,
 262        .read_reg8_msrx         = macio_do_read_reg8_msrx,
 263        .write_reg32_slm        = macio_do_write_reg32_slm,
 264        .write_reg8_slm         = macio_do_write_reg8_slm,
 265        .delay                  = macio_do_delay,
 266};
 267
 268static void macio_mmio_init_one(struct macio_chip *macio)
 269{
 270        DBG("Installing MMIO functions for macio %pOF\n",
 271            macio->of_node);
 272
 273        pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio);
 274}
 275
 276static struct device_node *unin_hwclock;
 277
 278static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
 279{
 280        unsigned long flags;
 281
 282        raw_spin_lock_irqsave(&feature_lock, flags);
 283        /* This is fairly bogus in darwin, but it should work for our needs
 284         * implemeted that way:
 285         */
 286        UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask));
 287        raw_spin_unlock_irqrestore(&feature_lock, flags);
 288        return 0;
 289}
 290
 291
 292static struct pmf_handlers unin_mmio_handlers = {
 293        .write_reg32            = unin_do_write_reg32,
 294        .delay                  = macio_do_delay,
 295};
 296
 297static void uninorth_install_pfunc(void)
 298{
 299        struct device_node *np;
 300
 301        DBG("Installing functions for UniN %pOF\n",
 302            uninorth_node);
 303
 304        /*
 305         * Install handlers for the bridge itself
 306         */
 307        pmf_register_driver(uninorth_node, &unin_mmio_handlers, NULL);
 308        pmf_do_functions(uninorth_node, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
 309
 310
 311        /*
 312         * Install handlers for the hwclock child if any
 313         */
 314        for (np = NULL; (np = of_get_next_child(uninorth_node, np)) != NULL;)
 315                if (of_node_name_eq(np, "hw-clock")) {
 316                        unin_hwclock = np;
 317                        break;
 318                }
 319        if (unin_hwclock) {
 320                DBG("Installing functions for UniN clock %pOF\n",
 321                    unin_hwclock);
 322                pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL);
 323                pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT,
 324                                 NULL);
 325        }
 326}
 327
 328/* We export this as the SMP code might init us early */
 329int __init pmac_pfunc_base_install(void)
 330{
 331        static int pfbase_inited;
 332        int i;
 333
 334        if (pfbase_inited)
 335                return 0;
 336        pfbase_inited = 1;
 337
 338        if (!machine_is(powermac))
 339                return 0;
 340
 341        DBG("Installing base platform functions...\n");
 342
 343        /*
 344         * Locate mac-io chips and install handlers
 345         */
 346        for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
 347                if (macio_chips[i].of_node) {
 348                        macio_mmio_init_one(&macio_chips[i]);
 349                        macio_gpio_init_one(&macio_chips[i]);
 350                }
 351        }
 352
 353        /*
 354         * Install handlers for northbridge and direct mapped hwclock
 355         * if any. We do not implement the config space access callback
 356         * which is only ever used for functions that we do not call in
 357         * the current driver (enabling/disabling cells in U2, mostly used
 358         * to restore the PCI settings, we do that differently)
 359         */
 360        if (uninorth_node && uninorth_base)
 361                uninorth_install_pfunc();
 362
 363        DBG("All base functions installed\n");
 364
 365        return 0;
 366}
 367machine_arch_initcall(powermac, pmac_pfunc_base_install);
 368
 369#ifdef CONFIG_PM
 370
 371/* Those can be called by pmac_feature. Ultimately, I should use a sysdev
 372 * or a device, but for now, that's good enough until I sort out some
 373 * ordering issues. Also, we do not bother with GPIOs, as so far I yet have
 374 * to see a case where a GPIO function has the on-suspend or on-resume bit
 375 */
 376void pmac_pfunc_base_suspend(void)
 377{
 378        int i;
 379
 380        for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
 381                if (macio_chips[i].of_node)
 382                        pmf_do_functions(macio_chips[i].of_node, NULL, 0,
 383                                         PMF_FLAGS_ON_SLEEP, NULL);
 384        }
 385        if (uninorth_node)
 386                pmf_do_functions(uninorth_node, NULL, 0,
 387                                 PMF_FLAGS_ON_SLEEP, NULL);
 388        if (unin_hwclock)
 389                pmf_do_functions(unin_hwclock, NULL, 0,
 390                                 PMF_FLAGS_ON_SLEEP, NULL);
 391}
 392
 393void pmac_pfunc_base_resume(void)
 394{
 395        int i;
 396
 397        if (unin_hwclock)
 398                pmf_do_functions(unin_hwclock, NULL, 0,
 399                                 PMF_FLAGS_ON_WAKE, NULL);
 400        if (uninorth_node)
 401                pmf_do_functions(uninorth_node, NULL, 0,
 402                                 PMF_FLAGS_ON_WAKE, NULL);
 403        for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
 404                if (macio_chips[i].of_node)
 405                        pmf_do_functions(macio_chips[i].of_node, NULL, 0,
 406                                         PMF_FLAGS_ON_WAKE, NULL);
 407        }
 408}
 409
 410#endif /* CONFIG_PM */
 411