^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * interface.c - contains everything related to the user interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Bjorn Helgaas <bjorn.helgaas@hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "base.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct pnp_info_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) char *buffer; /* pointer to begin of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) char *curr; /* current position in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) unsigned long size; /* current size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned long len; /* total length of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) int stop; /* stop flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int error; /* error code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) typedef struct pnp_info_buffer pnp_info_buffer_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (buffer->stop || buffer->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) res = vsnprintf(buffer->curr, buffer->len - buffer->size, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (buffer->size + res >= buffer->len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) buffer->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) buffer->curr += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) buffer->size += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct pnp_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "%i-bit address decoding\n", space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) (unsigned long long) port->min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) (unsigned long long) port->max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) port->align ? ((unsigned long long) port->align - 1) : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) (unsigned long long) port->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct pnp_irq *irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int first = 1, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) pnp_printf(buffer, "%sirq ", space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) for (i = 0; i < PNP_IRQ_NR; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (test_bit(i, irq->map.bits)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pnp_printf(buffer, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (i == 2 || i == 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pnp_printf(buffer, "2/9");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pnp_printf(buffer, "%i", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pnp_printf(buffer, "<none>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) pnp_printf(buffer, " High-Edge");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (irq->flags & IORESOURCE_IRQ_LOWEDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pnp_printf(buffer, " Low-Edge");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (irq->flags & IORESOURCE_IRQ_HIGHLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) pnp_printf(buffer, " High-Level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) pnp_printf(buffer, " Low-Level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pnp_printf(buffer, " (optional)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pnp_printf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void pnp_print_dma(pnp_info_buffer_t * buffer, char *space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct pnp_dma *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int first = 1, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) pnp_printf(buffer, "%sdma ", space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) for (i = 0; i < 8; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (dma->map & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) pnp_printf(buffer, ",");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) pnp_printf(buffer, "%i", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!dma->map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) pnp_printf(buffer, "<none>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) switch (dma->flags & IORESOURCE_DMA_TYPE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case IORESOURCE_DMA_8BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) s = "8-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) case IORESOURCE_DMA_8AND16BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) s = "8-bit&16-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) s = "16-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pnp_printf(buffer, " %s", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (dma->flags & IORESOURCE_DMA_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) pnp_printf(buffer, " master");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (dma->flags & IORESOURCE_DMA_BYTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pnp_printf(buffer, " byte-count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (dma->flags & IORESOURCE_DMA_WORD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) pnp_printf(buffer, " word-count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) switch (dma->flags & IORESOURCE_DMA_SPEED_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case IORESOURCE_DMA_TYPEA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) s = "type-A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case IORESOURCE_DMA_TYPEB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) s = "type-B";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case IORESOURCE_DMA_TYPEF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) s = "type-F";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) s = "compatible";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) pnp_printf(buffer, " %s\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct pnp_mem *mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) space, (unsigned long long) mem->min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) (unsigned long long) mem->max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) (unsigned long long) mem->align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) (unsigned long long) mem->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (mem->flags & IORESOURCE_MEM_WRITEABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) pnp_printf(buffer, ", writeable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (mem->flags & IORESOURCE_MEM_CACHEABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pnp_printf(buffer, ", cacheable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pnp_printf(buffer, ", range-length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) pnp_printf(buffer, ", shadowable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (mem->flags & IORESOURCE_MEM_EXPANSIONROM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) pnp_printf(buffer, ", expansion ROM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case IORESOURCE_MEM_8BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) s = "8-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case IORESOURCE_MEM_8AND16BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) s = "8-bit&16-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case IORESOURCE_MEM_32BIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) s = "32-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) s = "16-bit";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pnp_printf(buffer, ", %s\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct pnp_option *option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) switch (option->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case IORESOURCE_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) pnp_print_port(buffer, space, &option->u.port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case IORESOURCE_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) pnp_print_mem(buffer, space, &option->u.mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case IORESOURCE_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pnp_print_irq(buffer, space, &option->u.irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case IORESOURCE_DMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) pnp_print_dma(buffer, space, &option->u.dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static ssize_t options_show(struct device *dmdev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct pnp_dev *dev = to_pnp_dev(dmdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) pnp_info_buffer_t *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct pnp_option *option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int ret, dep = 0, set = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) char *indent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) buffer->len = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) buffer->buffer = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) buffer->curr = buffer->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) list_for_each_entry(option, &dev->options, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (pnp_option_is_dependent(option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) indent = " ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!dep || pnp_option_set(option) != set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) set = pnp_option_set(option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pnp_printf(buffer, "Dependent: %02i - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) "Priority %s\n", set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pnp_option_priority_name(option));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) indent = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) pnp_print_option(buffer, indent, option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = (buffer->curr - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static DEVICE_ATTR_RO(options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static ssize_t resources_show(struct device *dmdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct pnp_dev *dev = to_pnp_dev(dmdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) pnp_info_buffer_t *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct pnp_resource *pnp_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) buffer->len = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) buffer->buffer = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) buffer->curr = buffer->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) list_for_each_entry(pnp_res, &dev->resources, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) res = &pnp_res->res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) pnp_printf(buffer, pnp_resource_type_name(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (res->flags & IORESOURCE_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) pnp_printf(buffer, " disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) switch (pnp_resource_type(res)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case IORESOURCE_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case IORESOURCE_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case IORESOURCE_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) pnp_printf(buffer, " %#llx-%#llx%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) (unsigned long long) res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (unsigned long long) res->end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) res->flags & IORESOURCE_WINDOW ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) " window" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case IORESOURCE_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case IORESOURCE_DMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pnp_printf(buffer, " %lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) (unsigned long long) res->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ret = (buffer->curr - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static char *pnp_get_resource_value(char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned long type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) resource_size_t *start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) resource_size_t *end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned long *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) *start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) *end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* TBD: allow for disabled resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) buf = skip_spaces(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *start = simple_strtoull(buf, &buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) buf = skip_spaces(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (*buf == '-') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) buf = skip_spaces(buf + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *end = simple_strtoull(buf, &buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) *end = *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* TBD: allow for additional flags, e.g., IORESOURCE_WINDOW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static ssize_t resources_store(struct device *dmdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct device_attribute *attr, const char *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct pnp_dev *dev = to_pnp_dev(dmdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) char *buf = (void *)ubuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (dev->status & PNP_ATTACHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_info(&dev->dev, "in use; can't configure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) buf = skip_spaces(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!strncasecmp(buf, "disable", 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) retval = pnp_disable_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!strncasecmp(buf, "activate", 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) retval = pnp_activate_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!strncasecmp(buf, "fill", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (dev->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) retval = pnp_auto_config_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!strncasecmp(buf, "auto", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (dev->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) pnp_init_resources(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) retval = pnp_auto_config_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (!strncasecmp(buf, "clear", 5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (dev->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pnp_init_resources(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!strncasecmp(buf, "get", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mutex_lock(&pnp_res_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (pnp_can_read(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) dev->protocol->get(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mutex_unlock(&pnp_res_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!strncasecmp(buf, "set", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) resource_size_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) resource_size_t end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (dev->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) buf += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) pnp_init_resources(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_lock(&pnp_res_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) buf = skip_spaces(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!strncasecmp(buf, "io", 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) buf = pnp_get_resource_value(buf + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) &start, &end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) pnp_add_io_resource(dev, start, end, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) } else if (!strncasecmp(buf, "mem", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) buf = pnp_get_resource_value(buf + 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) &start, &end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pnp_add_mem_resource(dev, start, end, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) } else if (!strncasecmp(buf, "irq", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) buf = pnp_get_resource_value(buf + 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) &start, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) pnp_add_irq_resource(dev, start, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) } else if (!strncasecmp(buf, "dma", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) buf = pnp_get_resource_value(buf + 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) IORESOURCE_DMA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) &start, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pnp_add_dma_resource(dev, start, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) } else if (!strncasecmp(buf, "bus", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) buf = pnp_get_resource_value(buf + 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) IORESOURCE_BUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) &start, &end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) pnp_add_bus_resource(dev, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mutex_unlock(&pnp_res_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static DEVICE_ATTR_RW(resources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static ssize_t id_show(struct device *dmdev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) char *str = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct pnp_dev *dev = to_pnp_dev(dmdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct pnp_id *pos = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) while (pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) str += sprintf(str, "%s\n", pos->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pos = pos->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return (str - buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static DEVICE_ATTR_RO(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static struct attribute *pnp_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) &dev_attr_resources.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) &dev_attr_options.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) &dev_attr_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static const struct attribute_group pnp_dev_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .attrs = pnp_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) const struct attribute_group *pnp_dev_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) &pnp_dev_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) };