[chrome-os:chromeos-4.4 32/36] /tmp/sch_atm-753877.s:799: Warning: no instruction mnemonic suffix given and no register operands; using default for `bts'
by kernel test robot
tree: https://chromium.googlesource.com/chromiumos/third_party/kernel chromeos-4.4
head: 2d9bf6a74db95986dbd9e1f83bdb02577f2bd8ad
commit: 6c114632758e5acf9d11db539fd03fc0bcdf76bb [32/36] UPSTREAM: ACPI / processor: Finish making acpi_processor_ppc_has_changed() void
config: x86_64-randconfig-a014-20200817 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project de71b46a519db014ce906a39f8a0e1b235ef1568)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
git checkout 6c114632758e5acf9d11db539fd03fc0bcdf76bb
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>):
return atomic_read(&ht->nelems) < (tbl->size * 3 / 10) &&
~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~
include/linux/rhashtable.h:289:34: warning: comparison of integers of different signs: 'int' and 'const unsigned int' [-Wsign-compare]
return atomic_read(&ht->nelems) > tbl->size &&
~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
include/linux/rhashtable.h:302:34: warning: comparison of integers of different signs: 'int' and 'const unsigned int' [-Wsign-compare]
atomic_read(&ht->nelems) >= ht->p.insecure_max_entries;
~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
In file included from include/net/sock.h:51:
include/linux/netdevice.h:2413:34: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
skb_checksum_start_offset(skb) <
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
include/linux/netdevice.h:3051:15: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
BUG_ON(index >= dev->num_rx_queues);
~~~~~ ^ ~~~~~~~~~~~~~~~~~~
include/asm-generic/bug.h:58:45: note: expanded from macro 'BUG_ON'
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
^~~~~~~~~
include/linux/compiler.h:182:42: note: expanded from macro 'unlikely'
# define unlikely(x) __builtin_expect(!!(x), 0)
^
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
In file included from include/net/sock.h:51:
include/linux/netdevice.h:3325:37: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
if (debug_value < 0 || debug_value >= (sizeof(u32) * 8))
~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
In file included from include/net/sock.h:63:
In file included from include/linux/filter.h:16:
In file included from include/net/sch_generic.h:12:
In file included from include/net/rtnetlink.h:5:
include/net/netlink.h:345:18: warning: comparison of integers of different signs: 'const __u32' (aka 'const unsigned int') and 'int' [-Wsign-compare]
nlh->nlmsg_len <= remaining);
~~~~~~~~~~~~~~ ^ ~~~~~~~~~
include/net/netlink.h:380:21: warning: comparison of integers of different signs: 'const __u32' (aka 'const unsigned int') and 'int' [-Wsign-compare]
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~
include/net/netlink.h:413:21: warning: comparison of integers of different signs: 'const __u32' (aka 'const unsigned int') and 'int' [-Wsign-compare]
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
In file included from include/net/sock.h:63:
In file included from include/linux/filter.h:16:
In file included from include/net/sch_generic.h:12:
include/net/rtnetlink.h:20:21: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg))
~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
In file included from include/net/sock.h:63:
In file included from include/linux/filter.h:16:
include/net/sch_generic.h:267:33: warning: comparison of integers of different signs: 'unsigned long' and 'int' [-Wsign-compare]
BUILD_BUG_ON(sizeof(qcb->data) < sz);
~~~~~~~~~~~~~~~~~ ^ ~~
include/linux/build_bug.h:71:19: note: expanded from macro 'BUILD_BUG_ON'
BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
^~~~~~~~~
include/linux/build_bug.h:47:58: note: expanded from macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~
include/linux/compiler.h:509:22: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^~~~~~~~~
include/linux/compiler.h:497:23: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^~~~~~~~~
include/linux/compiler.h:489:19: note: expanded from macro '__compiletime_assert'
bool __cond = !(condition); \
^~~~~~~~~
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
In file included from include/net/sock.h:63:
include/linux/filter.h:517:16: warning: comparison of integers of different signs: 'const __u32' (aka 'const unsigned int') and 'int' [-Wsign-compare]
if (first->k == SKF_AD_OFF + SKF_AD_ALU_XOR_X)
~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from net/sched/sch_atm.c:12:
In file included from include/linux/atmdev.h:12:
include/net/sock.h:1878:54: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if (csum_and_copy_from_iter(to, copy, &csum, from) != copy)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
include/net/sock.h:1882:46: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if (copy_from_iter_nocache(to, copy, from) != copy)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
include/net/sock.h:1884:44: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
} else if (copy_from_iter(to, copy, from) != copy)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
In file included from net/sched/sch_atm.c:12:
include/linux/atmdev.h:257:59: warning: comparison of integers of different signs: 'unsigned int' and 'int' [-Wsign-compare]
return (size + atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) <
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
net/sched/sch_atm.c:478:26: warning: comparison of integers of different signs: 'unsigned int' and 'int' [-Wsign-compare]
if (skb_headroom(skb) < flow->hdr_len) {
~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~
28 warnings generated.
/tmp/sch_atm-753877.s: Assembler messages:
>> /tmp/sch_atm-753877.s:799: Warning: no instruction mnemonic suffix given and no register operands; using default for `bts'
/tmp/sch_atm-753877.s:987: Warning: no instruction mnemonic suffix given and no register operands; using default for `bts'
/tmp/sch_atm-753877.s:1114: Warning: no instruction mnemonic suffix given and no register operands; using default for `bts'
/tmp/sch_atm-753877.s:5165: Warning: no instruction mnemonic suffix given and no register operands; using default for `bts'
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
arch/mips/sgi-ip27/ip27-hubio.c:30:15: warning: no previous prototype for 'hub_pio_map'
by kernel test robot
Hi Thomas,
FYI, the error/warning still remains.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 9123e3a74ec7b934a4a099e98af6a61c2f80bbf5
commit: b78e9d63a3b6307b6b786e6ba189d3978b60ceb5 MIPS: SGI-IP27: use asm/sn/agent.h for including HUB related stuff
date: 7 months ago
config: mips-randconfig-r023-20200817 (attached as .config)
compiler: mips64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout b78e9d63a3b6307b6b786e6ba189d3978b60ceb5
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>):
>> arch/mips/sgi-ip27/ip27-hubio.c:30:15: warning: no previous prototype for 'hub_pio_map' [-Wmissing-prototypes]
30 | unsigned long hub_pio_map(nasid_t nasid, xwidgetnum_t widget,
| ^~~~~~~~~~~
>> arch/mips/sgi-ip27/ip27-hubio.c:175:6: warning: no previous prototype for 'hub_pio_init' [-Wmissing-prototypes]
175 | void hub_pio_init(nasid_t nasid)
| ^~~~~~~~~~~~
{standard input}: Assembler messages:
{standard input}:130: Error: found '(', expected: ')'
{standard input}:130: Error: found '(', expected: ')'
{standard input}:130: Error: non-constant expression in ".if" statement
{standard input}:130: Error: junk at end of line, first unrecognized character is `('
{standard input}:155: Error: found '(', expected: ')'
{standard input}:155: Error: found '(', expected: ')'
{standard input}:155: Error: non-constant expression in ".if" statement
{standard input}:155: Error: junk at end of line, first unrecognized character is `('
{standard input}:641: Error: found '(', expected: ')'
{standard input}:641: Error: found '(', expected: ')'
{standard input}:641: Error: non-constant expression in ".if" statement
{standard input}:641: Error: junk at end of line, first unrecognized character is `('
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit...
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout b78e9d63a3b6307b6b786e6ba189d3978b60ceb5
vim +/hub_pio_map +30 arch/mips/sgi-ip27/ip27-hubio.c
^1da177e4c3f41 Linus Torvalds 2005-04-16 20
^1da177e4c3f41 Linus Torvalds 2005-04-16 21 /**
^1da177e4c3f41 Linus Torvalds 2005-04-16 22 * hub_pio_map - establish a HUB PIO mapping
^1da177e4c3f41 Linus Torvalds 2005-04-16 23 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 24 * @hub: hub to perform PIO mapping on
^1da177e4c3f41 Linus Torvalds 2005-04-16 25 * @widget: widget ID to perform PIO mapping for
^1da177e4c3f41 Linus Torvalds 2005-04-16 26 * @xtalk_addr: xtalk_address that needs to be mapped
^1da177e4c3f41 Linus Torvalds 2005-04-16 27 * @size: size of the PIO mapping
^1da177e4c3f41 Linus Torvalds 2005-04-16 28 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 29 **/
4bf841ebf17aaa Thomas Bogendoerfer 2019-10-03 @30 unsigned long hub_pio_map(nasid_t nasid, xwidgetnum_t widget,
^1da177e4c3f41 Linus Torvalds 2005-04-16 31 unsigned long xtalk_addr, size_t size)
^1da177e4c3f41 Linus Torvalds 2005-04-16 32 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 33 unsigned i;
^1da177e4c3f41 Linus Torvalds 2005-04-16 34
^1da177e4c3f41 Linus Torvalds 2005-04-16 35 /* use small-window mapping if possible */
^1da177e4c3f41 Linus Torvalds 2005-04-16 36 if ((xtalk_addr % SWIN_SIZE) + size <= SWIN_SIZE)
^1da177e4c3f41 Linus Torvalds 2005-04-16 37 return NODE_SWIN_BASE(nasid, widget) + (xtalk_addr % SWIN_SIZE);
^1da177e4c3f41 Linus Torvalds 2005-04-16 38
^1da177e4c3f41 Linus Torvalds 2005-04-16 39 if ((xtalk_addr % BWIN_SIZE) + size > BWIN_SIZE) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 40 printk(KERN_WARNING "PIO mapping at hub %d widget %d addr 0x%lx"
^1da177e4c3f41 Linus Torvalds 2005-04-16 41 " too big (%ld)\n",
^1da177e4c3f41 Linus Torvalds 2005-04-16 42 nasid, widget, xtalk_addr, size);
^1da177e4c3f41 Linus Torvalds 2005-04-16 43 return 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 44 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 45
^1da177e4c3f41 Linus Torvalds 2005-04-16 46 xtalk_addr &= ~(BWIN_SIZE-1);
^1da177e4c3f41 Linus Torvalds 2005-04-16 47 for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) {
4bf841ebf17aaa Thomas Bogendoerfer 2019-10-03 48 if (test_and_set_bit(i, hub_data(nasid)->h_bigwin_used))
^1da177e4c3f41 Linus Torvalds 2005-04-16 49 continue;
^1da177e4c3f41 Linus Torvalds 2005-04-16 50
^1da177e4c3f41 Linus Torvalds 2005-04-16 51 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 52 * The code below does a PIO write to setup an ITTE entry.
^1da177e4c3f41 Linus Torvalds 2005-04-16 53 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 54 * We need to prevent other CPUs from seeing our updated
^1da177e4c3f41 Linus Torvalds 2005-04-16 55 * memory shadow of the ITTE (in the piomap) until the ITTE
^1da177e4c3f41 Linus Torvalds 2005-04-16 56 * entry is actually set up; otherwise, another CPU might
^1da177e4c3f41 Linus Torvalds 2005-04-16 57 * attempt a PIO prematurely.
^1da177e4c3f41 Linus Torvalds 2005-04-16 58 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 59 * Also, the only way we can know that an entry has been
^1da177e4c3f41 Linus Torvalds 2005-04-16 60 * received by the hub and can be used by future PIO reads/
^1da177e4c3f41 Linus Torvalds 2005-04-16 61 * writes is by reading back the ITTE entry after writing it.
^1da177e4c3f41 Linus Torvalds 2005-04-16 62 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 63 * For these two reasons, we PIO read back the ITTE entry
^1da177e4c3f41 Linus Torvalds 2005-04-16 64 * after we write it.
^1da177e4c3f41 Linus Torvalds 2005-04-16 65 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 66 IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
db0e7d4e42b055 Thomas Bogendoerfer 2019-02-19 67 __raw_readq(IIO_ITTE_GET(nasid, i));
^1da177e4c3f41 Linus Torvalds 2005-04-16 68
^1da177e4c3f41 Linus Torvalds 2005-04-16 69 return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE);
^1da177e4c3f41 Linus Torvalds 2005-04-16 70 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 71
^1da177e4c3f41 Linus Torvalds 2005-04-16 72 printk(KERN_WARNING "unable to establish PIO mapping for at"
^1da177e4c3f41 Linus Torvalds 2005-04-16 73 " hub %d widget %d addr 0x%lx\n",
^1da177e4c3f41 Linus Torvalds 2005-04-16 74 nasid, widget, xtalk_addr);
^1da177e4c3f41 Linus Torvalds 2005-04-16 75 return 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 76 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 77
^1da177e4c3f41 Linus Torvalds 2005-04-16 78
^1da177e4c3f41 Linus Torvalds 2005-04-16 79 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 80 * hub_setup_prb(nasid, prbnum, credits, conveyor)
^1da177e4c3f41 Linus Torvalds 2005-04-16 81 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 82 * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
^1da177e4c3f41 Linus Torvalds 2005-04-16 83 * put it into conveyor belt mode with the specified number of credits.
^1da177e4c3f41 Linus Torvalds 2005-04-16 84 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 85 static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
^1da177e4c3f41 Linus Torvalds 2005-04-16 86 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 87 iprb_t prb;
^1da177e4c3f41 Linus Torvalds 2005-04-16 88 int prb_offset;
^1da177e4c3f41 Linus Torvalds 2005-04-16 89
^1da177e4c3f41 Linus Torvalds 2005-04-16 90 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 91 * Get the current register value.
^1da177e4c3f41 Linus Torvalds 2005-04-16 92 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 93 prb_offset = IIO_IOPRB(prbnum);
^1da177e4c3f41 Linus Torvalds 2005-04-16 94 prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset);
^1da177e4c3f41 Linus Torvalds 2005-04-16 95
^1da177e4c3f41 Linus Torvalds 2005-04-16 96 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 97 * Clear out some fields.
^1da177e4c3f41 Linus Torvalds 2005-04-16 98 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 99 prb.iprb_ovflow = 1;
^1da177e4c3f41 Linus Torvalds 2005-04-16 100 prb.iprb_bnakctr = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 101 prb.iprb_anakctr = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 102
^1da177e4c3f41 Linus Torvalds 2005-04-16 103 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 104 * Enable or disable fire-and-forget mode.
^1da177e4c3f41 Linus Torvalds 2005-04-16 105 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 106 prb.iprb_ff = force_fire_and_forget ? 1 : 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 107
^1da177e4c3f41 Linus Torvalds 2005-04-16 108 /*
87fd4e2692a2ad Andrea Gelmini 2016-05-21 109 * Set the appropriate number of PIO credits for the widget.
^1da177e4c3f41 Linus Torvalds 2005-04-16 110 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 111 prb.iprb_xtalkctr = credits;
^1da177e4c3f41 Linus Torvalds 2005-04-16 112
^1da177e4c3f41 Linus Torvalds 2005-04-16 113 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 114 * Store the new value to the register.
^1da177e4c3f41 Linus Torvalds 2005-04-16 115 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 116 REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval);
^1da177e4c3f41 Linus Torvalds 2005-04-16 117 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 118
^1da177e4c3f41 Linus Torvalds 2005-04-16 119 /**
^1da177e4c3f41 Linus Torvalds 2005-04-16 120 * hub_set_piomode - set pio mode for a given hub
^1da177e4c3f41 Linus Torvalds 2005-04-16 121 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 122 * @nasid: physical node ID for the hub in question
^1da177e4c3f41 Linus Torvalds 2005-04-16 123 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 124 * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget" mode.
^1da177e4c3f41 Linus Torvalds 2005-04-16 125 * To do this, we have to make absolutely sure that no PIOs are in progress
^1da177e4c3f41 Linus Torvalds 2005-04-16 126 * so we turn off access to all widgets for the duration of the function.
^1da177e4c3f41 Linus Torvalds 2005-04-16 127 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 128 * XXX - This code should really check what kind of widget we're talking
^1da177e4c3f41 Linus Torvalds 2005-04-16 129 * to. Bridges can only handle three requests, but XG will do more.
^1da177e4c3f41 Linus Torvalds 2005-04-16 130 * How many can crossbow handle to widget 0? We're assuming 1.
^1da177e4c3f41 Linus Torvalds 2005-04-16 131 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 132 * XXX - There is a bug in the crossbow that link reset PIOs do not
^1da177e4c3f41 Linus Torvalds 2005-04-16 133 * return write responses. The easiest solution to this problem is to
^1da177e4c3f41 Linus Torvalds 2005-04-16 134 * leave widget 0 (xbow) in fire-and-forget mode at all times. This
^1da177e4c3f41 Linus Torvalds 2005-04-16 135 * only affects pio's to xbow registers, which should be rare.
^1da177e4c3f41 Linus Torvalds 2005-04-16 136 **/
^1da177e4c3f41 Linus Torvalds 2005-04-16 137 static void hub_set_piomode(nasid_t nasid)
^1da177e4c3f41 Linus Torvalds 2005-04-16 138 {
db0e7d4e42b055 Thomas Bogendoerfer 2019-02-19 139 u64 ii_iowa;
^1da177e4c3f41 Linus Torvalds 2005-04-16 140 hubii_wcr_t ii_wcr;
^1da177e4c3f41 Linus Torvalds 2005-04-16 141 unsigned i;
^1da177e4c3f41 Linus Torvalds 2005-04-16 142
^1da177e4c3f41 Linus Torvalds 2005-04-16 143 ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
^1da177e4c3f41 Linus Torvalds 2005-04-16 144 REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
^1da177e4c3f41 Linus Torvalds 2005-04-16 145
^1da177e4c3f41 Linus Torvalds 2005-04-16 146 ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR);
^1da177e4c3f41 Linus Torvalds 2005-04-16 147
^1da177e4c3f41 Linus Torvalds 2005-04-16 148 if (ii_wcr.iwcr_dir_con) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 149 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 150 * Assume a bridge here.
^1da177e4c3f41 Linus Torvalds 2005-04-16 151 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 152 hub_setup_prb(nasid, 0, 3);
^1da177e4c3f41 Linus Torvalds 2005-04-16 153 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 154 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 155 * Assume a crossbow here.
^1da177e4c3f41 Linus Torvalds 2005-04-16 156 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 157 hub_setup_prb(nasid, 0, 1);
^1da177e4c3f41 Linus Torvalds 2005-04-16 158 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 159
^1da177e4c3f41 Linus Torvalds 2005-04-16 160 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 161 * XXX - Here's where we should take the widget type into
^1da177e4c3f41 Linus Torvalds 2005-04-16 162 * when account assigning credits.
^1da177e4c3f41 Linus Torvalds 2005-04-16 163 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 164 for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++)
^1da177e4c3f41 Linus Torvalds 2005-04-16 165 hub_setup_prb(nasid, i, 3);
^1da177e4c3f41 Linus Torvalds 2005-04-16 166
^1da177e4c3f41 Linus Torvalds 2005-04-16 167 REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
^1da177e4c3f41 Linus Torvalds 2005-04-16 168 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 169
^1da177e4c3f41 Linus Torvalds 2005-04-16 170 /*
603e82edf78ad6 Joe Perches 2008-02-03 171 * hub_pio_init - PIO-related hub initialization
^1da177e4c3f41 Linus Torvalds 2005-04-16 172 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 173 * @hub: hubinfo structure for our hub
^1da177e4c3f41 Linus Torvalds 2005-04-16 174 */
4bf841ebf17aaa Thomas Bogendoerfer 2019-10-03 @175 void hub_pio_init(nasid_t nasid)
:::::: The code at line 30 was first introduced by commit
:::::: 4bf841ebf17aaa0f7712623896c699b44fa92f44 MIPS: SGI-IP27: get rid of compact node ids
:::::: TO: Thomas Bogendoerfer <tbogendoerfer(a)suse.de>
:::::: CC: Paul Burton <paul.burton(a)mips.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
drivers/media/platform/fsl-viu.c:36: warning: "out_be32" redefined
by kernel test robot
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 9123e3a74ec7b934a4a099e98af6a61c2f80bbf5
commit: a19f228b8dd9a67e8de4ebd4eac8a4c94ec39d1a media: Kconfig: not all V4L2 platform drivers are for camera
date: 4 months ago
config: m68k-randconfig-r021-20200817 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout a19f228b8dd9a67e8de4ebd4eac8a4c94ec39d1a
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>):
In file included from arch/m68k/include/asm/io_mm.h:25,
from arch/m68k/include/asm/io.h:8,
from include/linux/io.h:13,
from include/linux/irq.h:20,
from include/asm-generic/hardirq.h:13,
from ./arch/m68k/include/generated/asm/hardirq.h:1,
from include/linux/hardirq.h:9,
from include/linux/interrupt.h:11,
from drivers/media/platform/fsl-viu.c:17:
arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsb':
arch/m68k/include/asm/raw_io.h:83:7: warning: variable '__w' set but not used [-Wunused-but-set-variable]
83 | ({u8 __w, __v = (b); u32 _addr = ((u32) (addr)); \
| ^~~
arch/m68k/include/asm/raw_io.h:430:3: note: in expansion of macro 'rom_out_8'
430 | rom_out_8(port, *buf++);
| ^~~~~~~~~
arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsw':
arch/m68k/include/asm/raw_io.h:86:8: warning: variable '__w' set but not used [-Wunused-but-set-variable]
86 | ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
| ^~~
arch/m68k/include/asm/raw_io.h:448:3: note: in expansion of macro 'rom_out_be16'
448 | rom_out_be16(port, *buf++);
| ^~~~~~~~~~~~
arch/m68k/include/asm/raw_io.h: In function 'raw_rom_outsw_swapw':
arch/m68k/include/asm/raw_io.h:90:8: warning: variable '__w' set but not used [-Wunused-but-set-variable]
90 | ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
| ^~~
arch/m68k/include/asm/raw_io.h:466:3: note: in expansion of macro 'rom_out_le16'
466 | rom_out_le16(port, *buf++);
| ^~~~~~~~~~~~
In file included from include/linux/kernel.h:11,
from include/linux/list.h:9,
from include/linux/module.h:12,
from drivers/media/platform/fsl-viu.c:12:
include/linux/scatterlist.h: In function 'sg_set_buf':
arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
| ^~
include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
78 | # define unlikely(x) __builtin_expect(!!(x), 0)
| ^
include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
143 | BUG_ON(!virt_addr_valid(buf));
| ^~~~~~
include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
143 | BUG_ON(!virt_addr_valid(buf));
| ^~~~~~~~~~~~~~~
In file included from arch/m68k/include/asm/bug.h:32,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from include/asm-generic/preempt.h:5,
from ./arch/m68k/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/seqlock.h:36,
from include/linux/time.h:6,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from drivers/media/platform/fsl-viu.c:12:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/m68k/include/asm/page_mm.h:169:49: warning: ordered comparison of pointer with null pointer [-Wextra]
169 | #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
| ^~
include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
139 | int __ret_warn_once = !!(condition); \
| ^~~~~~~~~
arch/m68k/include/asm/page_mm.h:170:25: note: in expansion of macro 'virt_addr_valid'
170 | #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
| ^~~~~~~~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 | if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
| ^~~~~~~~~
drivers/media/platform/fsl-viu.c: At top level:
>> drivers/media/platform/fsl-viu.c:36: warning: "out_be32" redefined
36 | #define out_be32(v, a) iowrite32be(a, (void __iomem *)v)
|
In file included from arch/m68k/include/asm/io_mm.h:25,
from arch/m68k/include/asm/io.h:8,
from include/linux/io.h:13,
from include/linux/irq.h:20,
from include/asm-generic/hardirq.h:13,
from ./arch/m68k/include/generated/asm/hardirq.h:1,
from include/linux/hardirq.h:9,
from include/linux/interrupt.h:11,
from drivers/media/platform/fsl-viu.c:17:
arch/m68k/include/asm/raw_io.h:32: note: this is the location of the previous definition
32 | #define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l))
|
>> drivers/media/platform/fsl-viu.c:37: warning: "in_be32" redefined
37 | #define in_be32(a) ioread32be((void __iomem *)a)
|
In file included from arch/m68k/include/asm/io_mm.h:25,
from arch/m68k/include/asm/io.h:8,
from include/linux/io.h:13,
from include/linux/irq.h:20,
from include/asm-generic/hardirq.h:13,
from ./arch/m68k/include/generated/asm/hardirq.h:1,
from include/linux/hardirq.h:9,
from include/linux/interrupt.h:11,
from drivers/media/platform/fsl-viu.c:17:
arch/m68k/include/asm/raw_io.h:23: note: this is the location of the previous definition
23 | #define in_be32(addr) \
|
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit...
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout a19f228b8dd9a67e8de4ebd4eac8a4c94ec39d1a
vim +/out_be32 +36 drivers/media/platform/fsl-viu.c
95c5d605ca6fd6a drivers/media/video/fsl-viu.c Anatolij Gustschin 2010-07-02 33
29d750686331a1a drivers/media/platform/fsl-viu.c Mauro Carvalho Chehab 2018-04-05 34 /* Allow building this driver with COMPILE_TEST */
6898dd580a04534 drivers/media/platform/fsl-viu.c Randy Dunlap 2019-08-06 35 #if !defined(CONFIG_PPC) && !defined(CONFIG_MICROBLAZE)
29d750686331a1a drivers/media/platform/fsl-viu.c Mauro Carvalho Chehab 2018-04-05 @36 #define out_be32(v, a) iowrite32be(a, (void __iomem *)v)
29d750686331a1a drivers/media/platform/fsl-viu.c Mauro Carvalho Chehab 2018-04-05 @37 #define in_be32(a) ioread32be((void __iomem *)a)
29d750686331a1a drivers/media/platform/fsl-viu.c Mauro Carvalho Chehab 2018-04-05 38 #endif
29d750686331a1a drivers/media/platform/fsl-viu.c Mauro Carvalho Chehab 2018-04-05 39
:::::: The code at line 36 was first introduced by commit
:::::: 29d750686331a1a9ceeb97e81d3770f57bed5f72 media: fsl-viu: allow building it with COMPILE_TEST
:::::: TO: Mauro Carvalho Chehab <mchehab(a)s-opensource.com>
:::::: CC: Mauro Carvalho Chehab <mchehab(a)s-opensource.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
[RFC PATCH] fs/proc: proc_memctl_operations can be static
by kernel test robot
Signed-off-by: kernel test robot <lkp(a)intel.com>
---
base.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 28a1afeb67a9c..463a92cf8a95d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3241,7 +3241,7 @@ static ssize_t proc_memctl_write(struct file *file, const char __user *buf,
return err < 0 ? err : count;
}
-const struct file_operations proc_memctl_operations = {
+static const struct file_operations proc_memctl_operations = {
.read = proc_memctl_read,
.write = proc_memctl_write,
.llseek = generic_file_llseek,
2 years, 1 month
Re: [RFC PATCH 4/8] fs/proc: Support a new procfs memctl file
by kernel test robot
Hi Waiman,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on hnaz-linux-mm/master]
[also build test WARNING on linus/master v5.9-rc1 next-20200817]
[cannot apply to tip/sched/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Waiman-Long/memcg-Enable-fine-gr...
base: https://github.com/hnaz/linux-mm master
config: x86_64-randconfig-s022-20200817 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.2-180-g49f7e13a-dirty
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
sparse warnings: (new ones prefixed by >>)
fs/proc/base.c:2231:25: sparse: sparse: cast to restricted fmode_t
fs/proc/base.c:2288:42: sparse: sparse: cast from restricted fmode_t
fs/proc/base.c:2385:48: sparse: sparse: cast from restricted fmode_t
>> fs/proc/base.c:3244:30: sparse: sparse: symbol 'proc_memctl_operations' was not declared. Should it be static?
fs/proc/base.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...):
include/linux/sched/signal.h:695:37: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
include/linux/sched/signal.h:695:37: sparse: expected struct spinlock [usertype] *lock
include/linux/sched/signal.h:695:37: sparse: got struct spinlock [noderef] __rcu *
fs/proc/base.c:1104:36: sparse: sparse: context imbalance in '__set_oom_adj' - unexpected unlock
Please review and possibly fold the followup patch.
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
[ti:ti-rt-linux-5.4.y 3733/9325] drivers/pci/controller/cadence/pci-j721e.c:109 j721e_pcie_legacy_irq_handler() warn: inconsistent indenting
by kernel test robot
tree: git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git ti-rt-linux-5.4.y
head: 679110506d7f5755fd05b3007b24dffd735e816a
commit: c577d6c429a54c2aa978e90f5cf5c2fb332e5e63 [3733/9325] PCI: j721e: Add PCI legacy interrupt support for J721E
config: i386-randconfig-m021-20200816 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
smatch warnings:
drivers/pci/controller/cadence/pci-j721e.c:109 j721e_pcie_legacy_irq_handler() warn: inconsistent indenting
git remote add ti git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git
git fetch --no-tags ti ti-rt-linux-5.4.y
git checkout c577d6c429a54c2aa978e90f5cf5c2fb332e5e63
vim +109 drivers/pci/controller/cadence/pci-j721e.c
93
94 static void j721e_pcie_legacy_irq_handler(struct irq_desc *desc)
95 {
96 int i;
97 u32 reg;
98 int virq;
99 struct j721e_pcie *pcie = irq_desc_get_handler_data(desc);
100 struct irq_chip *chip = irq_desc_get_chip(desc);
101
102 chained_irq_enter(chip, desc);
103
104 for (i = 0; i < PCI_NUM_INTX; i++) {
105 reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_0);
106 if (!(reg & INTx_EN(i)))
107 continue;
108
> 109 virq = irq_find_mapping(pcie->legacy_irq_domain, 3 - i);
110 generic_handle_irq(virq);
111 j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_0, INTx_EN(i));
112 j721e_pcie_intd_writel(pcie, EOI_REG, 3 - i);
113 }
114
115 chained_irq_exit(chip, desc);
116 }
117
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
[lkundrak-linux-mmp:lr/ariel 8/53] drivers/gpu/drm/gud/gud_drm_gadget.c:1161:2: error: implicit declaration of function 'backlight_put'; did you mean
by kernel test robot
tree: git://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/linux-mmp.git lr/ariel
head: 7cc415fb77d00206be843ee9b9f6dc5405a186af
commit: a1a73cc57e193d90beaf46ffea2099ce3f4abaff [8/53] Merge remote-tracking branch 'xo/lr/gud2' into merged
config: arc-allyesconfig (attached as .config)
compiler: arc-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout a1a73cc57e193d90beaf46ffea2099ce3f4abaff
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All errors (new ones prefixed by >>):
drivers/gpu/drm/gud/gud_drm_gadget.c: In function 'gud_drm_gadget_fini':
>> drivers/gpu/drm/gud/gud_drm_gadget.c:1161:2: error: implicit declaration of function 'backlight_put'; did you mean 'backlight_enable'? [-Werror=implicit-function-declaration]
1161 | backlight_put(gdg->backlight);
| ^~~~~~~~~~~~~
| backlight_enable
cc1: some warnings being treated as errors
# https://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/linux-mmp.git/co...
git remote add lkundrak-linux-mmp git://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/linux-mmp.git
git fetch --no-tags lkundrak-linux-mmp lr/ariel
git checkout a1a73cc57e193d90beaf46ffea2099ce3f4abaff
vim +1161 drivers/gpu/drm/gud/gud_drm_gadget.c
364f31b46de06f Noralf Trønnes 2020-05-29 1 // SPDX-License-Identifier: GPL-2.0
364f31b46de06f Noralf Trønnes 2020-05-29 2 /*
364f31b46de06f Noralf Trønnes 2020-05-29 3 * Copyright 2020 Noralf Trønnes
364f31b46de06f Noralf Trønnes 2020-05-29 4 */
364f31b46de06f Noralf Trønnes 2020-05-29 5
364f31b46de06f Noralf Trønnes 2020-05-29 6 #include <linux/backlight.h>
364f31b46de06f Noralf Trønnes 2020-05-29 7 #include <linux/delay.h>
364f31b46de06f Noralf Trønnes 2020-05-29 8 #include <linux/lz4.h>
364f31b46de06f Noralf Trønnes 2020-05-29 9 #include <linux/module.h>
364f31b46de06f Noralf Trønnes 2020-05-29 10 #include <linux/slab.h>
364f31b46de06f Noralf Trønnes 2020-05-29 11 #include <linux/spinlock.h>
364f31b46de06f Noralf Trønnes 2020-05-29 12 #include <linux/string.h>
364f31b46de06f Noralf Trønnes 2020-05-29 13
364f31b46de06f Noralf Trønnes 2020-05-29 14 #include <drm/drm_client.h>
364f31b46de06f Noralf Trønnes 2020-05-29 15 #include <drm/drm_connector.h>
364f31b46de06f Noralf Trønnes 2020-05-29 16 #include <drm/drm_crtc.h>
364f31b46de06f Noralf Trønnes 2020-05-29 17 #include <drm/drm_fourcc.h>
364f31b46de06f Noralf Trønnes 2020-05-29 18 #include <drm/drm_mode_object.h>
364f31b46de06f Noralf Trønnes 2020-05-29 19 #include <drm/drm_plane.h>
364f31b46de06f Noralf Trønnes 2020-05-29 20 #include <drm/drm_rect.h>
364f31b46de06f Noralf Trønnes 2020-05-29 21 #include <drm/gud_drm.h>
364f31b46de06f Noralf Trønnes 2020-05-29 22
364f31b46de06f Noralf Trønnes 2020-05-29 23 #include "gud_drm_internal.h"
364f31b46de06f Noralf Trønnes 2020-05-29 24
364f31b46de06f Noralf Trønnes 2020-05-29 25 /*
364f31b46de06f Noralf Trønnes 2020-05-29 26 * Concurrency:
364f31b46de06f Noralf Trønnes 2020-05-29 27 * Calls into this module from f_gud_drm are serialized and run in process
364f31b46de06f Noralf Trønnes 2020-05-29 28 * context except gud_drm_gadget_ctrl_get() which is run in interrupt context.
364f31b46de06f Noralf Trønnes 2020-05-29 29 *
364f31b46de06f Noralf Trønnes 2020-05-29 30 * Termination:
364f31b46de06f Noralf Trønnes 2020-05-29 31 * A DRM client can not release itself, only the DRM driver which resources the
364f31b46de06f Noralf Trønnes 2020-05-29 32 * client uses can do that.
364f31b46de06f Noralf Trønnes 2020-05-29 33 * This means that there are 2 paths to stop the gadget function:
364f31b46de06f Noralf Trønnes 2020-05-29 34 * - Unregistering the DRM driver (module unload)
364f31b46de06f Noralf Trønnes 2020-05-29 35 * - Disabling the USB gadget (configfs unbind)
364f31b46de06f Noralf Trønnes 2020-05-29 36 *
364f31b46de06f Noralf Trønnes 2020-05-29 37 * A use counter protects the gadget should the client go away. A kref is used
364f31b46de06f Noralf Trønnes 2020-05-29 38 * to control the release of the gud_drm_gadget structure shared by the 2 actors.
364f31b46de06f Noralf Trønnes 2020-05-29 39 *
364f31b46de06f Noralf Trønnes 2020-05-29 40 * Backlight:
364f31b46de06f Noralf Trønnes 2020-05-29 41 * If there's a backlight device it's attached to the first connector.
364f31b46de06f Noralf Trønnes 2020-05-29 42 */
364f31b46de06f Noralf Trønnes 2020-05-29 43
364f31b46de06f Noralf Trønnes 2020-05-29 44 struct gud_drm_gadget_connector {
364f31b46de06f Noralf Trønnes 2020-05-29 45 struct drm_connector *connector;
364f31b46de06f Noralf Trønnes 2020-05-29 46
364f31b46de06f Noralf Trønnes 2020-05-29 47 const struct gud_drm_property *properties;
364f31b46de06f Noralf Trønnes 2020-05-29 48 unsigned int num_properties;
364f31b46de06f Noralf Trønnes 2020-05-29 49 const char *tv_mode_enum_names;
364f31b46de06f Noralf Trønnes 2020-05-29 50 unsigned int num_tv_mode_enum_names;
364f31b46de06f Noralf Trønnes 2020-05-29 51 struct backlight_device *backlight;
364f31b46de06f Noralf Trønnes 2020-05-29 52
364f31b46de06f Noralf Trønnes 2020-05-29 53 spinlock_t lock; /* Protects the following members: */
364f31b46de06f Noralf Trønnes 2020-05-29 54 enum drm_connector_status status;
364f31b46de06f Noralf Trønnes 2020-05-29 55 unsigned int width_mm;
364f31b46de06f Noralf Trønnes 2020-05-29 56 unsigned int height_mm;
364f31b46de06f Noralf Trønnes 2020-05-29 57 struct gud_drm_display_mode *modes;
364f31b46de06f Noralf Trønnes 2020-05-29 58 unsigned int num_modes;
364f31b46de06f Noralf Trønnes 2020-05-29 59 void *edid;
364f31b46de06f Noralf Trønnes 2020-05-29 60 size_t edid_len;
364f31b46de06f Noralf Trønnes 2020-05-29 61 bool changed;
364f31b46de06f Noralf Trønnes 2020-05-29 62 };
364f31b46de06f Noralf Trønnes 2020-05-29 63
364f31b46de06f Noralf Trønnes 2020-05-29 64 struct gud_drm_gadget {
364f31b46de06f Noralf Trønnes 2020-05-29 65 struct kref refcount;
364f31b46de06f Noralf Trønnes 2020-05-29 66 refcount_t usecnt;
364f31b46de06f Noralf Trønnes 2020-05-29 67 struct drm_client_dev client;
364f31b46de06f Noralf Trønnes 2020-05-29 68 struct backlight_device *backlight;
364f31b46de06f Noralf Trønnes 2020-05-29 69
364f31b46de06f Noralf Trønnes 2020-05-29 70 const u32 *formats;
364f31b46de06f Noralf Trønnes 2020-05-29 71 unsigned int format_count;
364f31b46de06f Noralf Trønnes 2020-05-29 72
364f31b46de06f Noralf Trønnes 2020-05-29 73 const struct gud_drm_property *properties;
364f31b46de06f Noralf Trønnes 2020-05-29 74 unsigned int num_properties;
364f31b46de06f Noralf Trønnes 2020-05-29 75
364f31b46de06f Noralf Trønnes 2020-05-29 76 struct gud_drm_gadget_connector *connectors;
364f31b46de06f Noralf Trønnes 2020-05-29 77 unsigned int connector_count;
364f31b46de06f Noralf Trønnes 2020-05-29 78
364f31b46de06f Noralf Trønnes 2020-05-29 79 struct drm_rect set_buffer_rect;
364f31b46de06f Noralf Trønnes 2020-05-29 80 u32 set_buffer_length;
364f31b46de06f Noralf Trønnes 2020-05-29 81 u8 set_buffer_compression;
364f31b46de06f Noralf Trønnes 2020-05-29 82 u32 set_buffer_compressed_length;
364f31b46de06f Noralf Trønnes 2020-05-29 83
364f31b46de06f Noralf Trønnes 2020-05-29 84 struct drm_client_buffer *buffer;
364f31b46de06f Noralf Trønnes 2020-05-29 85 struct drm_client_buffer *buffer_check;
364f31b46de06f Noralf Trønnes 2020-05-29 86 u8 brightness;
364f31b46de06f Noralf Trønnes 2020-05-29 87 bool check_ok;
364f31b46de06f Noralf Trønnes 2020-05-29 88
364f31b46de06f Noralf Trønnes 2020-05-29 89 size_t max_buffer_size;
364f31b46de06f Noralf Trønnes 2020-05-29 90 void *work_buf;
364f31b46de06f Noralf Trønnes 2020-05-29 91 };
364f31b46de06f Noralf Trønnes 2020-05-29 92
364f31b46de06f Noralf Trønnes 2020-05-29 93 static int gud_drm_gadget_probe_connector(struct gud_drm_gadget_connector *gconn)
364f31b46de06f Noralf Trønnes 2020-05-29 94 {
364f31b46de06f Noralf Trønnes 2020-05-29 95 struct drm_connector *connector = gconn->connector;
364f31b46de06f Noralf Trønnes 2020-05-29 96 struct gud_drm_display_mode *modes = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 97 struct drm_device *drm = connector->dev;
364f31b46de06f Noralf Trønnes 2020-05-29 98 struct drm_display_mode *mode;
364f31b46de06f Noralf Trønnes 2020-05-29 99 void *edid_data, *edid = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 100 unsigned int num_modes = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 101 size_t edid_len = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 102 unsigned long flags;
364f31b46de06f Noralf Trønnes 2020-05-29 103 unsigned int i = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 104 int ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 105
364f31b46de06f Noralf Trønnes 2020-05-29 106 mutex_lock(&drm->mode_config.mutex);
364f31b46de06f Noralf Trønnes 2020-05-29 107
364f31b46de06f Noralf Trønnes 2020-05-29 108 connector->funcs->fill_modes(connector,
364f31b46de06f Noralf Trønnes 2020-05-29 109 drm->mode_config.max_width,
364f31b46de06f Noralf Trønnes 2020-05-29 110 drm->mode_config.max_height);
364f31b46de06f Noralf Trønnes 2020-05-29 111
364f31b46de06f Noralf Trønnes 2020-05-29 112 list_for_each_entry(mode, &connector->modes, head)
364f31b46de06f Noralf Trønnes 2020-05-29 113 num_modes++;
364f31b46de06f Noralf Trønnes 2020-05-29 114
364f31b46de06f Noralf Trønnes 2020-05-29 115 if (!num_modes)
364f31b46de06f Noralf Trønnes 2020-05-29 116 goto update;
364f31b46de06f Noralf Trønnes 2020-05-29 117
364f31b46de06f Noralf Trønnes 2020-05-29 118 modes = kmalloc_array(num_modes, sizeof(*modes), GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 119 if (!modes) {
364f31b46de06f Noralf Trønnes 2020-05-29 120 ret = -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 121 num_modes = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 122 goto update;
364f31b46de06f Noralf Trønnes 2020-05-29 123 }
364f31b46de06f Noralf Trønnes 2020-05-29 124
364f31b46de06f Noralf Trønnes 2020-05-29 125 list_for_each_entry(mode, &connector->modes, head)
364f31b46de06f Noralf Trønnes 2020-05-29 126 gud_drm_from_display_mode(&modes[i++], mode);
364f31b46de06f Noralf Trønnes 2020-05-29 127
364f31b46de06f Noralf Trønnes 2020-05-29 128 if (!connector->edid_blob_ptr)
364f31b46de06f Noralf Trønnes 2020-05-29 129 goto update;
364f31b46de06f Noralf Trønnes 2020-05-29 130
364f31b46de06f Noralf Trønnes 2020-05-29 131 edid_data = connector->edid_blob_ptr->data;
364f31b46de06f Noralf Trønnes 2020-05-29 132 edid_len = connector->edid_blob_ptr->length;
364f31b46de06f Noralf Trønnes 2020-05-29 133 if (!edid_data || !edid_len) {
364f31b46de06f Noralf Trønnes 2020-05-29 134 edid_len = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 135 goto update;
364f31b46de06f Noralf Trønnes 2020-05-29 136 }
364f31b46de06f Noralf Trønnes 2020-05-29 137
364f31b46de06f Noralf Trønnes 2020-05-29 138 edid = kmemdup(edid_data, edid_len, GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 139 if (!edid) {
364f31b46de06f Noralf Trønnes 2020-05-29 140 ret = -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 141 edid_len = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 142 }
364f31b46de06f Noralf Trønnes 2020-05-29 143
364f31b46de06f Noralf Trønnes 2020-05-29 144 update:
364f31b46de06f Noralf Trønnes 2020-05-29 145 spin_lock_irqsave(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 146 if (gconn->status != connector->status || gconn->num_modes != num_modes ||
364f31b46de06f Noralf Trønnes 2020-05-29 147 gconn->edid_len != edid_len ||
364f31b46de06f Noralf Trønnes 2020-05-29 148 (gconn->modes && modes && memcmp(gconn->modes, modes, num_modes * sizeof(*modes))) ||
364f31b46de06f Noralf Trønnes 2020-05-29 149 (gconn->edid && edid && memcmp(gconn->edid, edid, edid_len)))
364f31b46de06f Noralf Trønnes 2020-05-29 150 gconn->changed = true;
364f31b46de06f Noralf Trønnes 2020-05-29 151 swap(gconn->modes, modes);
364f31b46de06f Noralf Trønnes 2020-05-29 152 gconn->num_modes = num_modes;
364f31b46de06f Noralf Trønnes 2020-05-29 153 swap(gconn->edid, edid);
364f31b46de06f Noralf Trønnes 2020-05-29 154 gconn->edid_len = edid_len;
364f31b46de06f Noralf Trønnes 2020-05-29 155 gconn->width_mm = connector->display_info.width_mm;
364f31b46de06f Noralf Trønnes 2020-05-29 156 gconn->height_mm = connector->display_info.height_mm;
364f31b46de06f Noralf Trønnes 2020-05-29 157 gconn->status = connector->status;
364f31b46de06f Noralf Trønnes 2020-05-29 158 spin_unlock_irqrestore(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 159
364f31b46de06f Noralf Trønnes 2020-05-29 160 mutex_unlock(&drm->mode_config.mutex);
364f31b46de06f Noralf Trønnes 2020-05-29 161
364f31b46de06f Noralf Trønnes 2020-05-29 162 kfree(edid);
364f31b46de06f Noralf Trønnes 2020-05-29 163 kfree(modes);
364f31b46de06f Noralf Trønnes 2020-05-29 164
364f31b46de06f Noralf Trønnes 2020-05-29 165 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 166 }
364f31b46de06f Noralf Trønnes 2020-05-29 167
364f31b46de06f Noralf Trønnes 2020-05-29 168 static void gud_drm_gadget_probe_connectors(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 169 {
364f31b46de06f Noralf Trønnes 2020-05-29 170 unsigned int i;
364f31b46de06f Noralf Trønnes 2020-05-29 171
364f31b46de06f Noralf Trønnes 2020-05-29 172 for (i = 0; i < gdg->connector_count; i++)
364f31b46de06f Noralf Trønnes 2020-05-29 173 gud_drm_gadget_probe_connector(&gdg->connectors[i]);
364f31b46de06f Noralf Trønnes 2020-05-29 174 }
364f31b46de06f Noralf Trønnes 2020-05-29 175
364f31b46de06f Noralf Trønnes 2020-05-29 176 static bool gud_drm_gadget_check_buffer(struct gud_drm_gadget *gdg,
364f31b46de06f Noralf Trønnes 2020-05-29 177 struct drm_client_buffer *buffer,
364f31b46de06f Noralf Trønnes 2020-05-29 178 struct drm_display_mode *mode,
364f31b46de06f Noralf Trønnes 2020-05-29 179 u32 format)
364f31b46de06f Noralf Trønnes 2020-05-29 180 {
364f31b46de06f Noralf Trønnes 2020-05-29 181 struct drm_framebuffer *fb;
364f31b46de06f Noralf Trønnes 2020-05-29 182
364f31b46de06f Noralf Trønnes 2020-05-29 183 if (!buffer)
364f31b46de06f Noralf Trønnes 2020-05-29 184 return false;
364f31b46de06f Noralf Trønnes 2020-05-29 185
364f31b46de06f Noralf Trønnes 2020-05-29 186 fb = buffer->fb;
364f31b46de06f Noralf Trønnes 2020-05-29 187
364f31b46de06f Noralf Trønnes 2020-05-29 188 return fb->format->format == format &&
364f31b46de06f Noralf Trønnes 2020-05-29 189 fb->width == mode->hdisplay && fb->height == mode->vdisplay;
364f31b46de06f Noralf Trønnes 2020-05-29 190 }
364f31b46de06f Noralf Trønnes 2020-05-29 191
364f31b46de06f Noralf Trønnes 2020-05-29 192 static bool gud_drm_gadget_set_connector_property(struct drm_client_dev *client,
364f31b46de06f Noralf Trønnes 2020-05-29 193 struct drm_connector *connector,
364f31b46de06f Noralf Trønnes 2020-05-29 194 u16 prop, u64 val, int *ret)
364f31b46de06f Noralf Trønnes 2020-05-29 195 {
364f31b46de06f Noralf Trønnes 2020-05-29 196 struct drm_mode_config *config = &connector->dev->mode_config;
364f31b46de06f Noralf Trønnes 2020-05-29 197 struct drm_property *property;
364f31b46de06f Noralf Trønnes 2020-05-29 198
364f31b46de06f Noralf Trønnes 2020-05-29 199 switch (prop) {
364f31b46de06f Noralf Trønnes 2020-05-29 200 case GUD_DRM_PROPERTY_TV_SELECT_SUBCONNECTOR:
364f31b46de06f Noralf Trønnes 2020-05-29 201 property = config->tv_select_subconnector_property;
364f31b46de06f Noralf Trønnes 2020-05-29 202 break;
364f31b46de06f Noralf Trønnes 2020-05-29 203 case GUD_DRM_PROPERTY_TV_LEFT_MARGIN:
364f31b46de06f Noralf Trønnes 2020-05-29 204 property = config->tv_left_margin_property;
364f31b46de06f Noralf Trønnes 2020-05-29 205 break;
364f31b46de06f Noralf Trønnes 2020-05-29 206 case GUD_DRM_PROPERTY_TV_RIGHT_MARGIN:
364f31b46de06f Noralf Trønnes 2020-05-29 207 property = config->tv_right_margin_property;
364f31b46de06f Noralf Trønnes 2020-05-29 208 break;
364f31b46de06f Noralf Trønnes 2020-05-29 209 case GUD_DRM_PROPERTY_TV_TOP_MARGIN:
364f31b46de06f Noralf Trønnes 2020-05-29 210 property = config->tv_top_margin_property;
364f31b46de06f Noralf Trønnes 2020-05-29 211 break;
364f31b46de06f Noralf Trønnes 2020-05-29 212 case GUD_DRM_PROPERTY_TV_BOTTOM_MARGIN:
364f31b46de06f Noralf Trønnes 2020-05-29 213 property = config->tv_bottom_margin_property;
364f31b46de06f Noralf Trønnes 2020-05-29 214 break;
364f31b46de06f Noralf Trønnes 2020-05-29 215 case GUD_DRM_PROPERTY_TV_MODE:
364f31b46de06f Noralf Trønnes 2020-05-29 216 property = config->tv_mode_property;
364f31b46de06f Noralf Trønnes 2020-05-29 217 break;
364f31b46de06f Noralf Trønnes 2020-05-29 218 case GUD_DRM_PROPERTY_TV_BRIGHTNESS:
364f31b46de06f Noralf Trønnes 2020-05-29 219 property = config->tv_brightness_property;
364f31b46de06f Noralf Trønnes 2020-05-29 220 break;
364f31b46de06f Noralf Trønnes 2020-05-29 221 case GUD_DRM_PROPERTY_TV_CONTRAST:
364f31b46de06f Noralf Trønnes 2020-05-29 222 property = config->tv_contrast_property;
364f31b46de06f Noralf Trønnes 2020-05-29 223 break;
364f31b46de06f Noralf Trønnes 2020-05-29 224 case GUD_DRM_PROPERTY_TV_FLICKER_REDUCTION:
364f31b46de06f Noralf Trønnes 2020-05-29 225 property = config->tv_flicker_reduction_property;
364f31b46de06f Noralf Trønnes 2020-05-29 226 break;
364f31b46de06f Noralf Trønnes 2020-05-29 227 case GUD_DRM_PROPERTY_TV_OVERSCAN:
364f31b46de06f Noralf Trønnes 2020-05-29 228 property = config->tv_overscan_property;
364f31b46de06f Noralf Trønnes 2020-05-29 229 break;
364f31b46de06f Noralf Trønnes 2020-05-29 230 case GUD_DRM_PROPERTY_TV_SATURATION:
364f31b46de06f Noralf Trønnes 2020-05-29 231 property = config->tv_saturation_property;
364f31b46de06f Noralf Trønnes 2020-05-29 232 break;
364f31b46de06f Noralf Trønnes 2020-05-29 233 case GUD_DRM_PROPERTY_TV_HUE:
364f31b46de06f Noralf Trønnes 2020-05-29 234 property = config->tv_hue_property;
364f31b46de06f Noralf Trønnes 2020-05-29 235 break;
364f31b46de06f Noralf Trønnes 2020-05-29 236 default:
364f31b46de06f Noralf Trønnes 2020-05-29 237 return false;
364f31b46de06f Noralf Trønnes 2020-05-29 238 }
364f31b46de06f Noralf Trønnes 2020-05-29 239
364f31b46de06f Noralf Trønnes 2020-05-29 240 *ret = drm_client_modeset_set_property(client, &connector->base, property, val);
364f31b46de06f Noralf Trønnes 2020-05-29 241
364f31b46de06f Noralf Trønnes 2020-05-29 242 return true;
364f31b46de06f Noralf Trønnes 2020-05-29 243 }
364f31b46de06f Noralf Trønnes 2020-05-29 244
364f31b46de06f Noralf Trønnes 2020-05-29 245 static int gud_drm_gadget_check(struct gud_drm_gadget *gdg, struct gud_drm_req_set_state *req,
364f31b46de06f Noralf Trønnes 2020-05-29 246 size_t size)
364f31b46de06f Noralf Trønnes 2020-05-29 247 {
364f31b46de06f Noralf Trønnes 2020-05-29 248 struct drm_client_dev *client = &gdg->client;
364f31b46de06f Noralf Trønnes 2020-05-29 249 u32 format = le32_to_cpu(req->format);
364f31b46de06f Noralf Trønnes 2020-05-29 250 struct drm_client_buffer *buffer;
364f31b46de06f Noralf Trønnes 2020-05-29 251 struct drm_connector *connector;
364f31b46de06f Noralf Trønnes 2020-05-29 252 struct drm_display_mode mode;
364f31b46de06f Noralf Trønnes 2020-05-29 253 unsigned int i;
364f31b46de06f Noralf Trønnes 2020-05-29 254 void *vaddr;
364f31b46de06f Noralf Trønnes 2020-05-29 255 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 256
364f31b46de06f Noralf Trønnes 2020-05-29 257 if (size < sizeof(struct gud_drm_req_set_state))
364f31b46de06f Noralf Trønnes 2020-05-29 258 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 259
364f31b46de06f Noralf Trønnes 2020-05-29 260 if (size != struct_size(req, properties, req->num_properties))
364f31b46de06f Noralf Trønnes 2020-05-29 261 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 262
364f31b46de06f Noralf Trønnes 2020-05-29 263 memset(&mode, 0, sizeof(mode));
364f31b46de06f Noralf Trønnes 2020-05-29 264 gud_drm_to_display_mode(&mode, &req->mode);
364f31b46de06f Noralf Trønnes 2020-05-29 265
364f31b46de06f Noralf Trønnes 2020-05-29 266 gdg->check_ok = false;
364f31b46de06f Noralf Trønnes 2020-05-29 267
364f31b46de06f Noralf Trønnes 2020-05-29 268 if (!mode.hdisplay || !format)
364f31b46de06f Noralf Trønnes 2020-05-29 269 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 270
364f31b46de06f Noralf Trønnes 2020-05-29 271 if (req->connector >= gdg->connector_count)
364f31b46de06f Noralf Trønnes 2020-05-29 272 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 273
364f31b46de06f Noralf Trønnes 2020-05-29 274 connector = gdg->connectors[req->connector].connector;
364f31b46de06f Noralf Trønnes 2020-05-29 275
364f31b46de06f Noralf Trønnes 2020-05-29 276 if (gdg->buffer_check) {
364f31b46de06f Noralf Trønnes 2020-05-29 277 drm_client_framebuffer_delete(gdg->buffer_check);
364f31b46de06f Noralf Trønnes 2020-05-29 278 gdg->buffer_check = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 279 }
364f31b46de06f Noralf Trønnes 2020-05-29 280
364f31b46de06f Noralf Trønnes 2020-05-29 281 if (!gud_drm_gadget_check_buffer(gdg, gdg->buffer, &mode, format)) {
364f31b46de06f Noralf Trønnes 2020-05-29 282 buffer = drm_client_framebuffer_create(client, mode.hdisplay, mode.vdisplay,
364f31b46de06f Noralf Trønnes 2020-05-29 283 format);
364f31b46de06f Noralf Trønnes 2020-05-29 284 if (IS_ERR(buffer))
364f31b46de06f Noralf Trønnes 2020-05-29 285 return PTR_ERR(buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 286
364f31b46de06f Noralf Trønnes 2020-05-29 287 vaddr = drm_client_buffer_vmap(buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 288 if (IS_ERR(vaddr)) {
364f31b46de06f Noralf Trønnes 2020-05-29 289 drm_client_framebuffer_delete(buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 290 return PTR_ERR(vaddr);
364f31b46de06f Noralf Trønnes 2020-05-29 291 }
364f31b46de06f Noralf Trønnes 2020-05-29 292
364f31b46de06f Noralf Trønnes 2020-05-29 293 gdg->buffer_check = buffer;
364f31b46de06f Noralf Trønnes 2020-05-29 294 } else {
364f31b46de06f Noralf Trønnes 2020-05-29 295 buffer = gdg->buffer;
364f31b46de06f Noralf Trønnes 2020-05-29 296 }
364f31b46de06f Noralf Trønnes 2020-05-29 297
364f31b46de06f Noralf Trønnes 2020-05-29 298 ret = drm_client_modeset_set(client, connector, &mode, buffer->fb);
364f31b46de06f Noralf Trønnes 2020-05-29 299 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 300 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 301
364f31b46de06f Noralf Trønnes 2020-05-29 302 for (i = 0; i < req->num_properties; i++) {
364f31b46de06f Noralf Trønnes 2020-05-29 303 u16 prop = le16_to_cpu(req->properties[i].prop);
364f31b46de06f Noralf Trønnes 2020-05-29 304 u64 val = le64_to_cpu(req->properties[i].val);
364f31b46de06f Noralf Trønnes 2020-05-29 305
364f31b46de06f Noralf Trønnes 2020-05-29 306 if (gud_drm_gadget_set_connector_property(client, connector, prop, val, &ret)) {
364f31b46de06f Noralf Trønnes 2020-05-29 307 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 308 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 309 continue;
364f31b46de06f Noralf Trønnes 2020-05-29 310 }
364f31b46de06f Noralf Trønnes 2020-05-29 311
364f31b46de06f Noralf Trønnes 2020-05-29 312 switch (prop) {
364f31b46de06f Noralf Trønnes 2020-05-29 313 case GUD_DRM_PROPERTY_BACKLIGHT_BRIGHTNESS:
364f31b46de06f Noralf Trønnes 2020-05-29 314 if (val > 100)
364f31b46de06f Noralf Trønnes 2020-05-29 315 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 316 gdg->brightness = val;
364f31b46de06f Noralf Trønnes 2020-05-29 317 break;
364f31b46de06f Noralf Trønnes 2020-05-29 318 case GUD_DRM_PROPERTY_ROTATION:
364f31b46de06f Noralf Trønnes 2020-05-29 319 ret = drm_client_modeset_set_rotation(client, val);
364f31b46de06f Noralf Trønnes 2020-05-29 320 break;
364f31b46de06f Noralf Trønnes 2020-05-29 321 default:
364f31b46de06f Noralf Trønnes 2020-05-29 322 pr_err("%s: Unknown property: %u\n", __func__, prop);
364f31b46de06f Noralf Trønnes 2020-05-29 323 continue;
364f31b46de06f Noralf Trønnes 2020-05-29 324 }
364f31b46de06f Noralf Trønnes 2020-05-29 325
364f31b46de06f Noralf Trønnes 2020-05-29 326 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 327 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 328 }
364f31b46de06f Noralf Trønnes 2020-05-29 329
364f31b46de06f Noralf Trønnes 2020-05-29 330 ret = drm_client_modeset_check(&gdg->client);
364f31b46de06f Noralf Trønnes 2020-05-29 331 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 332 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 333
364f31b46de06f Noralf Trønnes 2020-05-29 334 gdg->check_ok = true;
364f31b46de06f Noralf Trønnes 2020-05-29 335
364f31b46de06f Noralf Trønnes 2020-05-29 336 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 337 }
364f31b46de06f Noralf Trønnes 2020-05-29 338
364f31b46de06f Noralf Trønnes 2020-05-29 339 static int gud_drm_gadget_commit(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 340 {
364f31b46de06f Noralf Trønnes 2020-05-29 341 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 342
364f31b46de06f Noralf Trønnes 2020-05-29 343 if (!gdg->check_ok)
364f31b46de06f Noralf Trønnes 2020-05-29 344 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 345
364f31b46de06f Noralf Trønnes 2020-05-29 346 if (gdg->backlight) {
364f31b46de06f Noralf Trønnes 2020-05-29 347 int val, max_brightness = gdg->backlight->props.max_brightness;
364f31b46de06f Noralf Trønnes 2020-05-29 348
364f31b46de06f Noralf Trønnes 2020-05-29 349 val = DIV64_U64_ROUND_UP(gdg->brightness * max_brightness, 100);
364f31b46de06f Noralf Trønnes 2020-05-29 350 ret = backlight_device_set_brightness(gdg->backlight, val);
364f31b46de06f Noralf Trønnes 2020-05-29 351 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 352 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 353 }
364f31b46de06f Noralf Trønnes 2020-05-29 354
364f31b46de06f Noralf Trønnes 2020-05-29 355 ret = drm_client_modeset_commit(&gdg->client);
364f31b46de06f Noralf Trønnes 2020-05-29 356 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 357 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 358
364f31b46de06f Noralf Trønnes 2020-05-29 359 if (gdg->buffer_check) {
364f31b46de06f Noralf Trønnes 2020-05-29 360 drm_client_framebuffer_delete(gdg->buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 361 gdg->buffer = gdg->buffer_check;
364f31b46de06f Noralf Trønnes 2020-05-29 362 gdg->buffer_check = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 363 }
364f31b46de06f Noralf Trønnes 2020-05-29 364
364f31b46de06f Noralf Trønnes 2020-05-29 365 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 366 }
364f31b46de06f Noralf Trønnes 2020-05-29 367
364f31b46de06f Noralf Trønnes 2020-05-29 368 static size_t gud_drm_gadget_write_buffer_memcpy(struct drm_client_buffer *buffer,
364f31b46de06f Noralf Trønnes 2020-05-29 369 const void *src, size_t len,
364f31b46de06f Noralf Trønnes 2020-05-29 370 struct drm_rect *rect)
364f31b46de06f Noralf Trønnes 2020-05-29 371 {
364f31b46de06f Noralf Trønnes 2020-05-29 372 unsigned int cpp = buffer->fb->format->cpp[0];
364f31b46de06f Noralf Trønnes 2020-05-29 373 size_t dst_pitch = buffer->fb->pitches[0];
364f31b46de06f Noralf Trønnes 2020-05-29 374 size_t src_pitch = drm_rect_width(rect) * cpp;
364f31b46de06f Noralf Trønnes 2020-05-29 375 unsigned int y;
364f31b46de06f Noralf Trønnes 2020-05-29 376 void *dst;
364f31b46de06f Noralf Trønnes 2020-05-29 377
364f31b46de06f Noralf Trønnes 2020-05-29 378 /* Get the address, it's already mapped */
364f31b46de06f Noralf Trønnes 2020-05-29 379 dst = drm_client_buffer_vmap(buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 380 dst += rect->y1 * dst_pitch;
364f31b46de06f Noralf Trønnes 2020-05-29 381 dst += rect->x1 * cpp;
364f31b46de06f Noralf Trønnes 2020-05-29 382
364f31b46de06f Noralf Trønnes 2020-05-29 383 for (y = 0; y < drm_rect_height(rect) && len; y++) {
364f31b46de06f Noralf Trønnes 2020-05-29 384 src_pitch = min(src_pitch, len);
364f31b46de06f Noralf Trønnes 2020-05-29 385 memcpy(dst, src, src_pitch);
364f31b46de06f Noralf Trønnes 2020-05-29 386 src += src_pitch;
364f31b46de06f Noralf Trønnes 2020-05-29 387 dst += dst_pitch;
364f31b46de06f Noralf Trønnes 2020-05-29 388 len -= src_pitch;
364f31b46de06f Noralf Trønnes 2020-05-29 389 }
364f31b46de06f Noralf Trønnes 2020-05-29 390
364f31b46de06f Noralf Trønnes 2020-05-29 391 return len;
364f31b46de06f Noralf Trønnes 2020-05-29 392 }
364f31b46de06f Noralf Trønnes 2020-05-29 393
364f31b46de06f Noralf Trønnes 2020-05-29 394 static bool gud_drm_gadget_check_rect(struct drm_client_buffer *buffer, struct drm_rect *rect)
364f31b46de06f Noralf Trønnes 2020-05-29 395 {
364f31b46de06f Noralf Trønnes 2020-05-29 396 return buffer->fb && rect->x1 < rect->x2 && rect->y1 < rect->y2 &&
364f31b46de06f Noralf Trønnes 2020-05-29 397 rect->x2 <= buffer->fb->width && rect->y2 <= buffer->fb->height;
364f31b46de06f Noralf Trønnes 2020-05-29 398 }
364f31b46de06f Noralf Trønnes 2020-05-29 399
364f31b46de06f Noralf Trønnes 2020-05-29 400 int gud_drm_gadget_write_buffer(struct gud_drm_gadget *gdg, const void *buf, size_t len)
364f31b46de06f Noralf Trønnes 2020-05-29 401 {
364f31b46de06f Noralf Trønnes 2020-05-29 402 struct drm_client_buffer *buffer = gdg->buffer ? gdg->buffer : gdg->buffer_check;
364f31b46de06f Noralf Trønnes 2020-05-29 403 struct drm_rect *rect = &gdg->set_buffer_rect;
364f31b46de06f Noralf Trønnes 2020-05-29 404 u8 compression = gdg->set_buffer_compression;
364f31b46de06f Noralf Trønnes 2020-05-29 405 struct drm_framebuffer *fb;
364f31b46de06f Noralf Trønnes 2020-05-29 406 size_t remain;
364f31b46de06f Noralf Trønnes 2020-05-29 407 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 408
364f31b46de06f Noralf Trønnes 2020-05-29 409 pr_debug("%s: len=%zu compression=0x%x\n", __func__, len, compression);
364f31b46de06f Noralf Trønnes 2020-05-29 410
364f31b46de06f Noralf Trønnes 2020-05-29 411 if (WARN_ON_ONCE(!buffer))
364f31b46de06f Noralf Trønnes 2020-05-29 412 return -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 413
364f31b46de06f Noralf Trønnes 2020-05-29 414 if (!gud_drm_gadget_check_rect(buffer, rect)) {
364f31b46de06f Noralf Trønnes 2020-05-29 415 pr_err("%s: Rectangle doesn't fit: " DRM_RECT_FMT "\n",
364f31b46de06f Noralf Trønnes 2020-05-29 416 __func__, DRM_RECT_ARG(rect));
364f31b46de06f Noralf Trønnes 2020-05-29 417 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 418 }
364f31b46de06f Noralf Trønnes 2020-05-29 419
364f31b46de06f Noralf Trønnes 2020-05-29 420 fb = buffer->fb;
364f31b46de06f Noralf Trønnes 2020-05-29 421
364f31b46de06f Noralf Trønnes 2020-05-29 422 if (compression & GUD_DRM_COMPRESSION_LZ4) {
364f31b46de06f Noralf Trønnes 2020-05-29 423 if (len != gdg->set_buffer_compressed_length) {
364f31b46de06f Noralf Trønnes 2020-05-29 424 pr_err("%s: Buffer compressed len differs: %zu != %zu\n",
364f31b46de06f Noralf Trønnes 2020-05-29 425 __func__, len, gdg->set_buffer_compressed_length);
364f31b46de06f Noralf Trønnes 2020-05-29 426 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 427 }
364f31b46de06f Noralf Trønnes 2020-05-29 428
364f31b46de06f Noralf Trønnes 2020-05-29 429 ret = LZ4_decompress_safe(buf, gdg->work_buf, len, gdg->max_buffer_size);
364f31b46de06f Noralf Trønnes 2020-05-29 430 if (ret < 0) {
364f31b46de06f Noralf Trønnes 2020-05-29 431 pr_err("%s: Failed to decompress buffer\n", __func__);
364f31b46de06f Noralf Trønnes 2020-05-29 432 return -EIO;
364f31b46de06f Noralf Trønnes 2020-05-29 433 }
364f31b46de06f Noralf Trønnes 2020-05-29 434
364f31b46de06f Noralf Trønnes 2020-05-29 435 buf = gdg->work_buf;
364f31b46de06f Noralf Trønnes 2020-05-29 436 len = ret;
364f31b46de06f Noralf Trønnes 2020-05-29 437 }
364f31b46de06f Noralf Trønnes 2020-05-29 438
364f31b46de06f Noralf Trønnes 2020-05-29 439 if (len != gdg->set_buffer_length) {
364f31b46de06f Noralf Trønnes 2020-05-29 440 pr_err("%s: Buffer len differs: %zu != %zu\n",
364f31b46de06f Noralf Trønnes 2020-05-29 441 __func__, len, gdg->set_buffer_length);
364f31b46de06f Noralf Trønnes 2020-05-29 442 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 443 }
364f31b46de06f Noralf Trønnes 2020-05-29 444
364f31b46de06f Noralf Trønnes 2020-05-29 445 if (len > (drm_rect_width(rect) * drm_rect_height(rect) * fb->format->cpp[0])) {
364f31b46de06f Noralf Trønnes 2020-05-29 446 pr_err("%s: Buffer is too big for rectangle: " DRM_RECT_FMT " len=%zu\n",
364f31b46de06f Noralf Trønnes 2020-05-29 447 __func__, DRM_RECT_ARG(rect), len);
364f31b46de06f Noralf Trønnes 2020-05-29 448 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 449 }
364f31b46de06f Noralf Trønnes 2020-05-29 450
364f31b46de06f Noralf Trønnes 2020-05-29 451 remain = gud_drm_gadget_write_buffer_memcpy(buffer, buf, len, rect);
364f31b46de06f Noralf Trønnes 2020-05-29 452 if (remain) {
364f31b46de06f Noralf Trønnes 2020-05-29 453 pr_err("%s: Failed to write buffer: remain=%zu\n", __func__, remain);
364f31b46de06f Noralf Trønnes 2020-05-29 454 return -EIO;
364f31b46de06f Noralf Trønnes 2020-05-29 455 }
364f31b46de06f Noralf Trønnes 2020-05-29 456
364f31b46de06f Noralf Trønnes 2020-05-29 457 return drm_client_framebuffer_flush(buffer, rect);
364f31b46de06f Noralf Trønnes 2020-05-29 458 }
364f31b46de06f Noralf Trønnes 2020-05-29 459 EXPORT_SYMBOL(gud_drm_gadget_write_buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 460
364f31b46de06f Noralf Trønnes 2020-05-29 461 int gud_drm_gadget_set_buffer(struct gud_drm_gadget *gdg, struct gud_drm_req_set_buffer *req)
364f31b46de06f Noralf Trønnes 2020-05-29 462 {
364f31b46de06f Noralf Trønnes 2020-05-29 463 u32 compressed_length = le32_to_cpu(req->compressed_length);
364f31b46de06f Noralf Trønnes 2020-05-29 464 u32 length = le32_to_cpu(req->length);
364f31b46de06f Noralf Trønnes 2020-05-29 465 struct drm_client_buffer *buffer;
364f31b46de06f Noralf Trønnes 2020-05-29 466 struct drm_rect rect;
364f31b46de06f Noralf Trønnes 2020-05-29 467 int ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 468
364f31b46de06f Noralf Trønnes 2020-05-29 469 if (!refcount_inc_not_zero(&gdg->usecnt))
364f31b46de06f Noralf Trønnes 2020-05-29 470 return -ENODEV;
364f31b46de06f Noralf Trønnes 2020-05-29 471
364f31b46de06f Noralf Trønnes 2020-05-29 472 buffer = gdg->buffer ? gdg->buffer : gdg->buffer_check;
364f31b46de06f Noralf Trønnes 2020-05-29 473 if (!buffer) {
364f31b46de06f Noralf Trønnes 2020-05-29 474 ret = -ENOENT;
364f31b46de06f Noralf Trønnes 2020-05-29 475 goto out;
364f31b46de06f Noralf Trønnes 2020-05-29 476 }
364f31b46de06f Noralf Trønnes 2020-05-29 477
364f31b46de06f Noralf Trønnes 2020-05-29 478 drm_rect_init(&rect, le32_to_cpu(req->x), le32_to_cpu(req->y),
364f31b46de06f Noralf Trønnes 2020-05-29 479 le32_to_cpu(req->width), le32_to_cpu(req->height));
364f31b46de06f Noralf Trønnes 2020-05-29 480
364f31b46de06f Noralf Trønnes 2020-05-29 481 pr_debug("%s: " DRM_RECT_FMT "\n", __func__, DRM_RECT_ARG(&rect));
364f31b46de06f Noralf Trønnes 2020-05-29 482
364f31b46de06f Noralf Trønnes 2020-05-29 483 if (!gud_drm_gadget_check_rect(buffer, &rect)) {
364f31b46de06f Noralf Trønnes 2020-05-29 484 ret = -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 485 goto out;
364f31b46de06f Noralf Trønnes 2020-05-29 486 }
364f31b46de06f Noralf Trønnes 2020-05-29 487
364f31b46de06f Noralf Trønnes 2020-05-29 488 if (req->compression & ~GUD_DRM_COMPRESSION_LZ4) {
364f31b46de06f Noralf Trønnes 2020-05-29 489 ret = -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 490 goto out;
364f31b46de06f Noralf Trønnes 2020-05-29 491 }
364f31b46de06f Noralf Trønnes 2020-05-29 492
364f31b46de06f Noralf Trønnes 2020-05-29 493 gdg->set_buffer_rect = rect;
364f31b46de06f Noralf Trønnes 2020-05-29 494 gdg->set_buffer_length = length;
364f31b46de06f Noralf Trønnes 2020-05-29 495
364f31b46de06f Noralf Trønnes 2020-05-29 496 if (req->compression) {
364f31b46de06f Noralf Trønnes 2020-05-29 497 if (!compressed_length) {
364f31b46de06f Noralf Trønnes 2020-05-29 498 ret = -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 499 goto out;
364f31b46de06f Noralf Trønnes 2020-05-29 500 }
364f31b46de06f Noralf Trønnes 2020-05-29 501 gdg->set_buffer_compression = req->compression;
364f31b46de06f Noralf Trønnes 2020-05-29 502 gdg->set_buffer_compressed_length = compressed_length;
364f31b46de06f Noralf Trønnes 2020-05-29 503 length = compressed_length;
364f31b46de06f Noralf Trønnes 2020-05-29 504 } else {
364f31b46de06f Noralf Trønnes 2020-05-29 505 gdg->set_buffer_compression = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 506 gdg->set_buffer_compressed_length = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 507 }
364f31b46de06f Noralf Trønnes 2020-05-29 508 out:
364f31b46de06f Noralf Trønnes 2020-05-29 509 refcount_dec(&gdg->usecnt);
364f31b46de06f Noralf Trønnes 2020-05-29 510
364f31b46de06f Noralf Trønnes 2020-05-29 511 return ret ? ret : length;
364f31b46de06f Noralf Trønnes 2020-05-29 512 }
364f31b46de06f Noralf Trønnes 2020-05-29 513 EXPORT_SYMBOL(gud_drm_gadget_set_buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 514
364f31b46de06f Noralf Trønnes 2020-05-29 515 static void gud_drm_gadget_delete_buffers(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 516 {
364f31b46de06f Noralf Trønnes 2020-05-29 517 drm_client_framebuffer_delete(gdg->buffer_check);
364f31b46de06f Noralf Trønnes 2020-05-29 518 drm_client_framebuffer_delete(gdg->buffer);
364f31b46de06f Noralf Trønnes 2020-05-29 519 gdg->buffer_check = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 520 gdg->buffer = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 521 }
364f31b46de06f Noralf Trønnes 2020-05-29 522
364f31b46de06f Noralf Trønnes 2020-05-29 523 int gud_drm_gadget_disable_pipe(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 524 {
364f31b46de06f Noralf Trønnes 2020-05-29 525 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 526
364f31b46de06f Noralf Trønnes 2020-05-29 527 ret = drm_client_modeset_disable(&gdg->client);
364f31b46de06f Noralf Trønnes 2020-05-29 528 gud_drm_gadget_delete_buffers(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 529
364f31b46de06f Noralf Trønnes 2020-05-29 530 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 531 }
364f31b46de06f Noralf Trønnes 2020-05-29 532 EXPORT_SYMBOL(gud_drm_gadget_disable_pipe);
364f31b46de06f Noralf Trønnes 2020-05-29 533
364f31b46de06f Noralf Trønnes 2020-05-29 534 static int gud_drm_gadget_ctrl_get_display_descriptor(struct gud_drm_gadget *gdg, u16 value,
364f31b46de06f Noralf Trønnes 2020-05-29 535 void *data, size_t size)
364f31b46de06f Noralf Trønnes 2020-05-29 536 {
364f31b46de06f Noralf Trønnes 2020-05-29 537 struct drm_device *drm = gdg->client.dev;
364f31b46de06f Noralf Trønnes 2020-05-29 538 struct gud_drm_display_descriptor desc;
364f31b46de06f Noralf Trønnes 2020-05-29 539 u8 type = value >> 8;
364f31b46de06f Noralf Trønnes 2020-05-29 540 u8 index = value & 0xff;
364f31b46de06f Noralf Trønnes 2020-05-29 541
364f31b46de06f Noralf Trønnes 2020-05-29 542 if (type != GUD_DRM_USB_DT_DISPLAY || index)
364f31b46de06f Noralf Trønnes 2020-05-29 543 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 544
364f31b46de06f Noralf Trønnes 2020-05-29 545 desc.bLength = sizeof(desc);
364f31b46de06f Noralf Trønnes 2020-05-29 546 desc.bDescriptorType = GUD_DRM_USB_DT_DISPLAY;
364f31b46de06f Noralf Trønnes 2020-05-29 547
364f31b46de06f Noralf Trønnes 2020-05-29 548 desc.bVersion = 1;
364f31b46de06f Noralf Trønnes 2020-05-29 549 desc.bMaxBufferSizeOrder = ilog2(gdg->max_buffer_size);
364f31b46de06f Noralf Trønnes 2020-05-29 550 desc.bmFlags = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 551 desc.bCompression = GUD_DRM_COMPRESSION_LZ4;
364f31b46de06f Noralf Trønnes 2020-05-29 552
364f31b46de06f Noralf Trønnes 2020-05-29 553 desc.dwMinWidth = cpu_to_le32(drm->mode_config.min_width);
364f31b46de06f Noralf Trønnes 2020-05-29 554 desc.dwMaxWidth = cpu_to_le32(drm->mode_config.max_width);
364f31b46de06f Noralf Trønnes 2020-05-29 555 desc.dwMinHeight = cpu_to_le32(drm->mode_config.min_height);
364f31b46de06f Noralf Trønnes 2020-05-29 556 desc.dwMaxHeight = cpu_to_le32(drm->mode_config.max_height);
364f31b46de06f Noralf Trønnes 2020-05-29 557 desc.bNumFormats = gdg->format_count;
364f31b46de06f Noralf Trønnes 2020-05-29 558 desc.bNumProperties = gdg->num_properties;
364f31b46de06f Noralf Trønnes 2020-05-29 559 desc.bNumConnectors = gdg->connector_count;
364f31b46de06f Noralf Trønnes 2020-05-29 560
364f31b46de06f Noralf Trønnes 2020-05-29 561 size = min(size, sizeof(desc));
364f31b46de06f Noralf Trønnes 2020-05-29 562 memcpy(data, &desc, size);
364f31b46de06f Noralf Trønnes 2020-05-29 563
364f31b46de06f Noralf Trønnes 2020-05-29 564 return size;
364f31b46de06f Noralf Trønnes 2020-05-29 565 }
364f31b46de06f Noralf Trønnes 2020-05-29 566
364f31b46de06f Noralf Trønnes 2020-05-29 567 static void gud_drm_gadget_ctrl_get_formats(struct gud_drm_gadget *gdg, __le32 *formats)
364f31b46de06f Noralf Trønnes 2020-05-29 568 {
364f31b46de06f Noralf Trønnes 2020-05-29 569 unsigned int i;
364f31b46de06f Noralf Trønnes 2020-05-29 570
364f31b46de06f Noralf Trønnes 2020-05-29 571 for (i = 0; i < gdg->format_count; i++)
364f31b46de06f Noralf Trønnes 2020-05-29 572 formats[i] = cpu_to_le32(gdg->formats[i]);
364f31b46de06f Noralf Trønnes 2020-05-29 573 }
364f31b46de06f Noralf Trønnes 2020-05-29 574
364f31b46de06f Noralf Trønnes 2020-05-29 575 static int gud_drm_gadget_ctrl_get_connector(struct gud_drm_gadget *gdg, unsigned int index,
364f31b46de06f Noralf Trønnes 2020-05-29 576 struct gud_drm_req_get_connector *desc)
364f31b46de06f Noralf Trønnes 2020-05-29 577 {
364f31b46de06f Noralf Trønnes 2020-05-29 578 struct gud_drm_gadget_connector *gconn;
364f31b46de06f Noralf Trønnes 2020-05-29 579
364f31b46de06f Noralf Trønnes 2020-05-29 580 if (index >= gdg->connector_count)
364f31b46de06f Noralf Trønnes 2020-05-29 581 return -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 582
364f31b46de06f Noralf Trønnes 2020-05-29 583 memset(desc, 0, sizeof(*desc));
364f31b46de06f Noralf Trønnes 2020-05-29 584
364f31b46de06f Noralf Trønnes 2020-05-29 585 gconn = &gdg->connectors[index];
364f31b46de06f Noralf Trønnes 2020-05-29 586
364f31b46de06f Noralf Trønnes 2020-05-29 587 desc->connector_type = gconn->connector->connector_type;
364f31b46de06f Noralf Trønnes 2020-05-29 588 desc->flags = cpu_to_le32(GUD_DRM_CONNECTOR_FLAGS_POLL);
364f31b46de06f Noralf Trønnes 2020-05-29 589 desc->num_properties = gconn->num_properties;
364f31b46de06f Noralf Trønnes 2020-05-29 590
364f31b46de06f Noralf Trønnes 2020-05-29 591 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 592 }
364f31b46de06f Noralf Trønnes 2020-05-29 593
364f31b46de06f Noralf Trønnes 2020-05-29 594 static struct gud_drm_gadget_connector *
364f31b46de06f Noralf Trønnes 2020-05-29 595 gud_drm_gadget_get_gconn(struct gud_drm_gadget *gdg, unsigned int index)
364f31b46de06f Noralf Trønnes 2020-05-29 596 {
364f31b46de06f Noralf Trønnes 2020-05-29 597 if (index >= gdg->connector_count)
364f31b46de06f Noralf Trønnes 2020-05-29 598 return NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 599
364f31b46de06f Noralf Trønnes 2020-05-29 600 return &gdg->connectors[index];
364f31b46de06f Noralf Trønnes 2020-05-29 601 }
364f31b46de06f Noralf Trønnes 2020-05-29 602
364f31b46de06f Noralf Trønnes 2020-05-29 603 static int gud_drm_gadget_ctrl_get_connector_status(struct gud_drm_gadget *gdg, unsigned int index,
364f31b46de06f Noralf Trønnes 2020-05-29 604 struct gud_drm_req_get_connector_status *status)
364f31b46de06f Noralf Trønnes 2020-05-29 605 {
364f31b46de06f Noralf Trønnes 2020-05-29 606 struct gud_drm_gadget_connector *gconn;
364f31b46de06f Noralf Trønnes 2020-05-29 607 unsigned long flags;
364f31b46de06f Noralf Trønnes 2020-05-29 608
364f31b46de06f Noralf Trønnes 2020-05-29 609 gconn = gud_drm_gadget_get_gconn(gdg, index);
364f31b46de06f Noralf Trønnes 2020-05-29 610 if (!gconn)
364f31b46de06f Noralf Trønnes 2020-05-29 611 return -ENOENT;
364f31b46de06f Noralf Trønnes 2020-05-29 612
364f31b46de06f Noralf Trønnes 2020-05-29 613 memset(status, 0, sizeof(*status));
364f31b46de06f Noralf Trønnes 2020-05-29 614
364f31b46de06f Noralf Trønnes 2020-05-29 615 spin_lock_irqsave(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 616 status->status = gconn->status;
364f31b46de06f Noralf Trønnes 2020-05-29 617 if (gconn->changed) {
364f31b46de06f Noralf Trønnes 2020-05-29 618 status->status |= GUD_DRM_CONNECTOR_STATUS_CHANGED;
364f31b46de06f Noralf Trønnes 2020-05-29 619 gconn->changed = false;
364f31b46de06f Noralf Trønnes 2020-05-29 620 }
364f31b46de06f Noralf Trønnes 2020-05-29 621 if (gconn->num_modes)
364f31b46de06f Noralf Trønnes 2020-05-29 622 status->num_modes = cpu_to_le16(gconn->num_modes);
364f31b46de06f Noralf Trønnes 2020-05-29 623 if (gconn->edid_len)
364f31b46de06f Noralf Trønnes 2020-05-29 624 status->edid_len = cpu_to_le16(gconn->edid_len);
364f31b46de06f Noralf Trønnes 2020-05-29 625 spin_unlock_irqrestore(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 626
364f31b46de06f Noralf Trønnes 2020-05-29 627 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 628 }
364f31b46de06f Noralf Trønnes 2020-05-29 629
364f31b46de06f Noralf Trønnes 2020-05-29 630 /* This runs in interrupt context */
364f31b46de06f Noralf Trønnes 2020-05-29 631 int gud_drm_gadget_ctrl_get(struct gud_drm_gadget *gdg, u8 request,
364f31b46de06f Noralf Trønnes 2020-05-29 632 u16 index, void *data, size_t size)
364f31b46de06f Noralf Trønnes 2020-05-29 633 {
364f31b46de06f Noralf Trønnes 2020-05-29 634 struct gud_drm_gadget_connector *gconn;
364f31b46de06f Noralf Trønnes 2020-05-29 635 unsigned long flags;
364f31b46de06f Noralf Trønnes 2020-05-29 636 int ret = -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 637
364f31b46de06f Noralf Trønnes 2020-05-29 638 pr_debug("%s: request=0x%x index=%u size=%zu\n", __func__, request, index, size);
364f31b46de06f Noralf Trønnes 2020-05-29 639
364f31b46de06f Noralf Trønnes 2020-05-29 640 if (!refcount_inc_not_zero(&gdg->usecnt))
364f31b46de06f Noralf Trønnes 2020-05-29 641 return -ENODEV;
364f31b46de06f Noralf Trønnes 2020-05-29 642
364f31b46de06f Noralf Trønnes 2020-05-29 643 if (!size)
364f31b46de06f Noralf Trønnes 2020-05-29 644 goto out;
364f31b46de06f Noralf Trønnes 2020-05-29 645
364f31b46de06f Noralf Trønnes 2020-05-29 646 switch (request) {
364f31b46de06f Noralf Trønnes 2020-05-29 647 case USB_REQ_GET_DESCRIPTOR:
364f31b46de06f Noralf Trønnes 2020-05-29 648 ret = gud_drm_gadget_ctrl_get_display_descriptor(gdg, index, data, size);
364f31b46de06f Noralf Trønnes 2020-05-29 649 break;
364f31b46de06f Noralf Trønnes 2020-05-29 650 case GUD_DRM_USB_REQ_GET_FORMATS:
364f31b46de06f Noralf Trønnes 2020-05-29 651 if (!index && size == gdg->format_count * sizeof(u32)) {
364f31b46de06f Noralf Trønnes 2020-05-29 652 gud_drm_gadget_ctrl_get_formats(gdg, data);
364f31b46de06f Noralf Trønnes 2020-05-29 653 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 654 }
364f31b46de06f Noralf Trønnes 2020-05-29 655 break;
364f31b46de06f Noralf Trønnes 2020-05-29 656 case GUD_DRM_USB_REQ_GET_PROPERTIES:
364f31b46de06f Noralf Trønnes 2020-05-29 657 if (!index && size == gdg->num_properties * sizeof(*gdg->properties)) {
364f31b46de06f Noralf Trønnes 2020-05-29 658 memcpy(data, gdg->properties, size);
364f31b46de06f Noralf Trønnes 2020-05-29 659 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 660 }
364f31b46de06f Noralf Trønnes 2020-05-29 661 break;
364f31b46de06f Noralf Trønnes 2020-05-29 662 case GUD_DRM_USB_REQ_GET_CONNECTOR:
364f31b46de06f Noralf Trønnes 2020-05-29 663 if (size == sizeof(struct gud_drm_req_get_connector))
364f31b46de06f Noralf Trønnes 2020-05-29 664 ret = gud_drm_gadget_ctrl_get_connector(gdg, index, data);
364f31b46de06f Noralf Trønnes 2020-05-29 665 break;
364f31b46de06f Noralf Trønnes 2020-05-29 666 case GUD_DRM_USB_REQ_GET_CONNECTOR_PROPERTIES:
364f31b46de06f Noralf Trønnes 2020-05-29 667 gconn = gud_drm_gadget_get_gconn(gdg, index);
364f31b46de06f Noralf Trønnes 2020-05-29 668 if (gconn && size == gconn->num_properties * sizeof(*gconn->properties)) {
364f31b46de06f Noralf Trønnes 2020-05-29 669 memcpy(data, gconn->properties, size);
364f31b46de06f Noralf Trønnes 2020-05-29 670 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 671 }
364f31b46de06f Noralf Trønnes 2020-05-29 672 break;
364f31b46de06f Noralf Trønnes 2020-05-29 673 case GUD_DRM_USB_REQ_GET_CONNECTOR_TV_MODE_VALUES:
364f31b46de06f Noralf Trønnes 2020-05-29 674 gconn = gud_drm_gadget_get_gconn(gdg, index);
364f31b46de06f Noralf Trønnes 2020-05-29 675 if (gconn && size == gconn->num_tv_mode_enum_names * DRM_PROP_NAME_LEN) {
364f31b46de06f Noralf Trønnes 2020-05-29 676 memcpy(data, gconn->tv_mode_enum_names, size);
364f31b46de06f Noralf Trønnes 2020-05-29 677 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 678 }
364f31b46de06f Noralf Trønnes 2020-05-29 679 break;
364f31b46de06f Noralf Trønnes 2020-05-29 680 case GUD_DRM_USB_REQ_GET_CONNECTOR_STATUS:
364f31b46de06f Noralf Trønnes 2020-05-29 681 if (size == sizeof(struct gud_drm_req_get_connector_status))
364f31b46de06f Noralf Trønnes 2020-05-29 682 ret = gud_drm_gadget_ctrl_get_connector_status(gdg, index, data);
364f31b46de06f Noralf Trønnes 2020-05-29 683 break;
364f31b46de06f Noralf Trønnes 2020-05-29 684 case GUD_DRM_USB_REQ_GET_CONNECTOR_MODES:
364f31b46de06f Noralf Trønnes 2020-05-29 685 gconn = gud_drm_gadget_get_gconn(gdg, index);
364f31b46de06f Noralf Trønnes 2020-05-29 686 spin_lock_irqsave(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 687 if (gconn && size == gconn->num_modes * sizeof(*gconn->modes)) {
364f31b46de06f Noralf Trønnes 2020-05-29 688 memcpy(data, gconn->modes, size);
364f31b46de06f Noralf Trønnes 2020-05-29 689 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 690 }
364f31b46de06f Noralf Trønnes 2020-05-29 691 spin_unlock_irqrestore(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 692 break;
364f31b46de06f Noralf Trønnes 2020-05-29 693 case GUD_DRM_USB_REQ_GET_CONNECTOR_EDID:
364f31b46de06f Noralf Trønnes 2020-05-29 694 gconn = gud_drm_gadget_get_gconn(gdg, index);
364f31b46de06f Noralf Trønnes 2020-05-29 695 spin_lock_irqsave(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 696 if (gconn && size == gconn->edid_len) {
364f31b46de06f Noralf Trønnes 2020-05-29 697 memcpy(data, gconn->edid, size);
364f31b46de06f Noralf Trønnes 2020-05-29 698 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 699 }
364f31b46de06f Noralf Trønnes 2020-05-29 700 spin_unlock_irqrestore(&gconn->lock, flags);
364f31b46de06f Noralf Trønnes 2020-05-29 701 break;
364f31b46de06f Noralf Trønnes 2020-05-29 702 }
364f31b46de06f Noralf Trønnes 2020-05-29 703 out:
364f31b46de06f Noralf Trønnes 2020-05-29 704 refcount_dec(&gdg->usecnt);
364f31b46de06f Noralf Trønnes 2020-05-29 705
364f31b46de06f Noralf Trønnes 2020-05-29 706 return !ret ? size : ret;
364f31b46de06f Noralf Trønnes 2020-05-29 707 }
364f31b46de06f Noralf Trønnes 2020-05-29 708 EXPORT_SYMBOL(gud_drm_gadget_ctrl_get);
364f31b46de06f Noralf Trønnes 2020-05-29 709
364f31b46de06f Noralf Trønnes 2020-05-29 710 int gud_drm_gadget_ctrl_set(struct gud_drm_gadget *gdg, u8 request,
364f31b46de06f Noralf Trønnes 2020-05-29 711 u16 index, void *data, size_t size)
364f31b46de06f Noralf Trønnes 2020-05-29 712 {
364f31b46de06f Noralf Trønnes 2020-05-29 713 struct gud_drm_gadget_connector *gconn;
364f31b46de06f Noralf Trønnes 2020-05-29 714 int dpms, ret = -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 715
364f31b46de06f Noralf Trønnes 2020-05-29 716 pr_debug("%s: request=0x%x index=%u size=%zu\n", __func__, request, index, size);
364f31b46de06f Noralf Trønnes 2020-05-29 717
364f31b46de06f Noralf Trønnes 2020-05-29 718 if (!refcount_inc_not_zero(&gdg->usecnt))
364f31b46de06f Noralf Trønnes 2020-05-29 719 return -ENODEV;
364f31b46de06f Noralf Trønnes 2020-05-29 720
364f31b46de06f Noralf Trønnes 2020-05-29 721 switch (request) {
364f31b46de06f Noralf Trønnes 2020-05-29 722 case GUD_DRM_USB_REQ_SET_CONNECTOR_FORCE_DETECT:
364f31b46de06f Noralf Trønnes 2020-05-29 723 gconn = gud_drm_gadget_get_gconn(gdg, index);
364f31b46de06f Noralf Trønnes 2020-05-29 724 if (gconn)
364f31b46de06f Noralf Trønnes 2020-05-29 725 ret = gud_drm_gadget_probe_connector(gconn);
364f31b46de06f Noralf Trønnes 2020-05-29 726 break;
364f31b46de06f Noralf Trønnes 2020-05-29 727 case GUD_DRM_USB_REQ_SET_STATE_CHECK:
364f31b46de06f Noralf Trønnes 2020-05-29 728 ret = gud_drm_gadget_check(gdg, data, size);
364f31b46de06f Noralf Trønnes 2020-05-29 729 break;
364f31b46de06f Noralf Trønnes 2020-05-29 730 case GUD_DRM_USB_REQ_SET_STATE_COMMIT:
364f31b46de06f Noralf Trønnes 2020-05-29 731 if (!size)
364f31b46de06f Noralf Trønnes 2020-05-29 732 ret = gud_drm_gadget_commit(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 733 break;
364f31b46de06f Noralf Trønnes 2020-05-29 734 case GUD_DRM_USB_REQ_SET_CONTROLLER_ENABLE:
364f31b46de06f Noralf Trønnes 2020-05-29 735 if (size == sizeof(u8)) {
364f31b46de06f Noralf Trønnes 2020-05-29 736 if (*(u8 *)data == 0)
364f31b46de06f Noralf Trønnes 2020-05-29 737 ret = gud_drm_gadget_disable_pipe(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 738 else
364f31b46de06f Noralf Trønnes 2020-05-29 739 ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 740 }
364f31b46de06f Noralf Trønnes 2020-05-29 741 break;
364f31b46de06f Noralf Trønnes 2020-05-29 742 case GUD_DRM_USB_REQ_SET_DISPLAY_ENABLE:
364f31b46de06f Noralf Trønnes 2020-05-29 743 if (size == sizeof(u8)) {
364f31b46de06f Noralf Trønnes 2020-05-29 744 dpms = *(u8 *)data ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF;
364f31b46de06f Noralf Trønnes 2020-05-29 745 ret = drm_client_modeset_dpms(&gdg->client, dpms);
364f31b46de06f Noralf Trønnes 2020-05-29 746 }
364f31b46de06f Noralf Trønnes 2020-05-29 747 break;
364f31b46de06f Noralf Trønnes 2020-05-29 748 }
364f31b46de06f Noralf Trønnes 2020-05-29 749
364f31b46de06f Noralf Trønnes 2020-05-29 750 refcount_dec(&gdg->usecnt);
364f31b46de06f Noralf Trønnes 2020-05-29 751
364f31b46de06f Noralf Trønnes 2020-05-29 752 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 753 }
364f31b46de06f Noralf Trønnes 2020-05-29 754 EXPORT_SYMBOL(gud_drm_gadget_ctrl_set);
364f31b46de06f Noralf Trønnes 2020-05-29 755
364f31b46de06f Noralf Trønnes 2020-05-29 756 static int gud_drm_gadget_get_formats(struct gud_drm_gadget *gdg, u8 *max_cpp)
364f31b46de06f Noralf Trønnes 2020-05-29 757 {
364f31b46de06f Noralf Trønnes 2020-05-29 758 struct drm_device *drm = gdg->client.dev;
364f31b46de06f Noralf Trønnes 2020-05-29 759 struct drm_plane *plane;
364f31b46de06f Noralf Trønnes 2020-05-29 760 unsigned int i;
364f31b46de06f Noralf Trønnes 2020-05-29 761 u32 *formats;
364f31b46de06f Noralf Trønnes 2020-05-29 762 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 763
364f31b46de06f Noralf Trønnes 2020-05-29 764 *max_cpp = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 765
364f31b46de06f Noralf Trønnes 2020-05-29 766 drm_for_each_plane(plane, drm) {
364f31b46de06f Noralf Trønnes 2020-05-29 767 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
364f31b46de06f Noralf Trønnes 2020-05-29 768 break;
364f31b46de06f Noralf Trønnes 2020-05-29 769 }
364f31b46de06f Noralf Trønnes 2020-05-29 770
364f31b46de06f Noralf Trønnes 2020-05-29 771 formats = kcalloc(plane->format_count, sizeof(u32), GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 772 if (!formats)
364f31b46de06f Noralf Trønnes 2020-05-29 773 return -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 774
364f31b46de06f Noralf Trønnes 2020-05-29 775 for (i = 0; i < plane->format_count; i++) {
364f31b46de06f Noralf Trønnes 2020-05-29 776 const struct drm_format_info *fmt;
364f31b46de06f Noralf Trønnes 2020-05-29 777
364f31b46de06f Noralf Trønnes 2020-05-29 778 fmt = drm_format_info(plane->format_types[i]);
364f31b46de06f Noralf Trønnes 2020-05-29 779 if (fmt->num_planes != 1)
364f31b46de06f Noralf Trønnes 2020-05-29 780 continue;
364f31b46de06f Noralf Trønnes 2020-05-29 781
364f31b46de06f Noralf Trønnes 2020-05-29 782 /*
364f31b46de06f Noralf Trønnes 2020-05-29 783 * Supporting 24-bit bpp would add complexity so don't bother.
364f31b46de06f Noralf Trønnes 2020-05-29 784 * It's hardly used and compression removes much of the gain.
364f31b46de06f Noralf Trønnes 2020-05-29 785 */
364f31b46de06f Noralf Trønnes 2020-05-29 786 if (fmt->cpp[0] == 3)
364f31b46de06f Noralf Trønnes 2020-05-29 787 continue;
364f31b46de06f Noralf Trønnes 2020-05-29 788
364f31b46de06f Noralf Trønnes 2020-05-29 789 if (*max_cpp < fmt->cpp[0])
364f31b46de06f Noralf Trønnes 2020-05-29 790 *max_cpp = fmt->cpp[0];
364f31b46de06f Noralf Trønnes 2020-05-29 791
364f31b46de06f Noralf Trønnes 2020-05-29 792 formats[gdg->format_count++] = plane->format_types[i];
364f31b46de06f Noralf Trønnes 2020-05-29 793 }
364f31b46de06f Noralf Trønnes 2020-05-29 794
364f31b46de06f Noralf Trønnes 2020-05-29 795 if (!gdg->format_count) {
364f31b46de06f Noralf Trønnes 2020-05-29 796 ret = -ENOENT;
364f31b46de06f Noralf Trønnes 2020-05-29 797 goto err_free;
364f31b46de06f Noralf Trønnes 2020-05-29 798 }
364f31b46de06f Noralf Trønnes 2020-05-29 799
364f31b46de06f Noralf Trønnes 2020-05-29 800 gdg->formats = formats;
364f31b46de06f Noralf Trønnes 2020-05-29 801
364f31b46de06f Noralf Trønnes 2020-05-29 802 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 803
364f31b46de06f Noralf Trønnes 2020-05-29 804 err_free:
364f31b46de06f Noralf Trønnes 2020-05-29 805 kfree(formats);
364f31b46de06f Noralf Trønnes 2020-05-29 806
364f31b46de06f Noralf Trønnes 2020-05-29 807 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 808 }
364f31b46de06f Noralf Trønnes 2020-05-29 809
364f31b46de06f Noralf Trønnes 2020-05-29 810 static int gud_drm_gadget_get_rotation_property(struct drm_device *drm, u16 *prop, u64 *val)
364f31b46de06f Noralf Trønnes 2020-05-29 811 {
364f31b46de06f Noralf Trønnes 2020-05-29 812 struct drm_property_enum *prop_enum;
364f31b46de06f Noralf Trønnes 2020-05-29 813 struct drm_plane *plane;
364f31b46de06f Noralf Trønnes 2020-05-29 814 unsigned int num_props = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 815 u16 bitmask = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 816
364f31b46de06f Noralf Trønnes 2020-05-29 817 drm_for_each_plane(plane, drm) {
364f31b46de06f Noralf Trønnes 2020-05-29 818 if (plane->type == DRM_PLANE_TYPE_PRIMARY)
364f31b46de06f Noralf Trønnes 2020-05-29 819 break;
364f31b46de06f Noralf Trønnes 2020-05-29 820 }
364f31b46de06f Noralf Trønnes 2020-05-29 821
364f31b46de06f Noralf Trønnes 2020-05-29 822 if (!plane->rotation_property)
364f31b46de06f Noralf Trønnes 2020-05-29 823 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 824
364f31b46de06f Noralf Trønnes 2020-05-29 825 list_for_each_entry(prop_enum, &plane->rotation_property->enum_list, head) {
364f31b46de06f Noralf Trønnes 2020-05-29 826 num_props++;
364f31b46de06f Noralf Trønnes 2020-05-29 827 bitmask |= BIT(prop_enum->value);
364f31b46de06f Noralf Trønnes 2020-05-29 828 }
364f31b46de06f Noralf Trønnes 2020-05-29 829
364f31b46de06f Noralf Trønnes 2020-05-29 830 *prop = GUD_DRM_PROPERTY_ROTATION;
364f31b46de06f Noralf Trønnes 2020-05-29 831 *val = bitmask;
364f31b46de06f Noralf Trønnes 2020-05-29 832
364f31b46de06f Noralf Trønnes 2020-05-29 833 return 1;
364f31b46de06f Noralf Trønnes 2020-05-29 834 }
364f31b46de06f Noralf Trønnes 2020-05-29 835
364f31b46de06f Noralf Trønnes 2020-05-29 836 static int gud_drm_gadget_get_properties(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 837 {
364f31b46de06f Noralf Trønnes 2020-05-29 838 struct gud_drm_property *properties;
364f31b46de06f Noralf Trønnes 2020-05-29 839 u16 prop;
364f31b46de06f Noralf Trønnes 2020-05-29 840 u64 val;
364f31b46de06f Noralf Trønnes 2020-05-29 841 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 842
364f31b46de06f Noralf Trønnes 2020-05-29 843 ret = gud_drm_gadget_get_rotation_property(gdg->client.dev, &prop, &val);
364f31b46de06f Noralf Trønnes 2020-05-29 844 if (ret <= 0)
364f31b46de06f Noralf Trønnes 2020-05-29 845 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 846
364f31b46de06f Noralf Trønnes 2020-05-29 847 properties = kcalloc(1, sizeof(*properties), GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 848 if (!properties)
364f31b46de06f Noralf Trønnes 2020-05-29 849 return -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 850
364f31b46de06f Noralf Trønnes 2020-05-29 851 gdg->properties = properties;
364f31b46de06f Noralf Trønnes 2020-05-29 852 gdg->num_properties++;
364f31b46de06f Noralf Trønnes 2020-05-29 853
364f31b46de06f Noralf Trønnes 2020-05-29 854 properties[0].prop = cpu_to_le16(prop);
364f31b46de06f Noralf Trønnes 2020-05-29 855 properties[0].val = cpu_to_le64(val);
364f31b46de06f Noralf Trønnes 2020-05-29 856
364f31b46de06f Noralf Trønnes 2020-05-29 857 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 858 }
364f31b46de06f Noralf Trønnes 2020-05-29 859
364f31b46de06f Noralf Trønnes 2020-05-29 860 static int gud_drm_gadget_get_connector_properties(struct gud_drm_gadget *gdg,
364f31b46de06f Noralf Trønnes 2020-05-29 861 struct gud_drm_gadget_connector *gconn)
364f31b46de06f Noralf Trønnes 2020-05-29 862 {
364f31b46de06f Noralf Trønnes 2020-05-29 863 struct drm_device *drm = gdg->client.dev;
364f31b46de06f Noralf Trønnes 2020-05-29 864 struct drm_mode_config *config = &drm->mode_config;
364f31b46de06f Noralf Trønnes 2020-05-29 865 struct drm_connector *connector = gconn->connector;
364f31b46de06f Noralf Trønnes 2020-05-29 866 struct drm_object_properties *conn_props = connector->base.properties;
364f31b46de06f Noralf Trønnes 2020-05-29 867 struct gud_drm_property *properties;
364f31b46de06f Noralf Trønnes 2020-05-29 868 unsigned int i, ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 869 u16 prop;
364f31b46de06f Noralf Trønnes 2020-05-29 870 u64 val;
364f31b46de06f Noralf Trønnes 2020-05-29 871
364f31b46de06f Noralf Trønnes 2020-05-29 872 mutex_lock(&drm->mode_config.mutex);
364f31b46de06f Noralf Trønnes 2020-05-29 873
364f31b46de06f Noralf Trønnes 2020-05-29 874 if (!conn_props->count)
364f31b46de06f Noralf Trønnes 2020-05-29 875 goto unlock;
364f31b46de06f Noralf Trønnes 2020-05-29 876
364f31b46de06f Noralf Trønnes 2020-05-29 877 /* Add room for possible backlight */
364f31b46de06f Noralf Trønnes 2020-05-29 878 properties = kcalloc(conn_props->count + 1, sizeof(*properties), GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 879 if (!properties) {
364f31b46de06f Noralf Trønnes 2020-05-29 880 ret = -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 881 goto unlock;
364f31b46de06f Noralf Trønnes 2020-05-29 882 }
364f31b46de06f Noralf Trønnes 2020-05-29 883
364f31b46de06f Noralf Trønnes 2020-05-29 884 gconn->properties = properties;
364f31b46de06f Noralf Trønnes 2020-05-29 885
364f31b46de06f Noralf Trønnes 2020-05-29 886 for (i = 0; i < conn_props->count; i++) {
364f31b46de06f Noralf Trønnes 2020-05-29 887 struct drm_property *property = conn_props->properties[i];
364f31b46de06f Noralf Trønnes 2020-05-29 888
364f31b46de06f Noralf Trønnes 2020-05-29 889 if (property == config->tv_select_subconnector_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 890 prop = GUD_DRM_PROPERTY_TV_SELECT_SUBCONNECTOR;
364f31b46de06f Noralf Trønnes 2020-05-29 891 val = connector->state->tv.subconnector;
364f31b46de06f Noralf Trønnes 2020-05-29 892 } else if (property == config->tv_left_margin_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 893 prop = GUD_DRM_PROPERTY_TV_LEFT_MARGIN;
364f31b46de06f Noralf Trønnes 2020-05-29 894 val = connector->state->tv.margins.left;
364f31b46de06f Noralf Trønnes 2020-05-29 895 } else if (property == config->tv_right_margin_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 896 prop = GUD_DRM_PROPERTY_TV_RIGHT_MARGIN;
364f31b46de06f Noralf Trønnes 2020-05-29 897 val = connector->state->tv.margins.right;
364f31b46de06f Noralf Trønnes 2020-05-29 898 } else if (property == config->tv_top_margin_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 899 prop = GUD_DRM_PROPERTY_TV_TOP_MARGIN;
364f31b46de06f Noralf Trønnes 2020-05-29 900 val = connector->state->tv.margins.top;
364f31b46de06f Noralf Trønnes 2020-05-29 901 } else if (property == config->tv_bottom_margin_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 902 prop = GUD_DRM_PROPERTY_TV_BOTTOM_MARGIN;
364f31b46de06f Noralf Trønnes 2020-05-29 903 val = connector->state->tv.margins.bottom;
364f31b46de06f Noralf Trønnes 2020-05-29 904 } else if (property == config->tv_mode_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 905 struct drm_property_enum *prop_enum;
364f31b46de06f Noralf Trønnes 2020-05-29 906 char *buf;
364f31b46de06f Noralf Trønnes 2020-05-29 907
364f31b46de06f Noralf Trønnes 2020-05-29 908 list_for_each_entry(prop_enum, &property->enum_list, head)
364f31b46de06f Noralf Trønnes 2020-05-29 909 gconn->num_tv_mode_enum_names++;
364f31b46de06f Noralf Trønnes 2020-05-29 910
364f31b46de06f Noralf Trønnes 2020-05-29 911 if (WARN_ON(!gconn->num_tv_mode_enum_names)) {
364f31b46de06f Noralf Trønnes 2020-05-29 912 ret = -EINVAL;
364f31b46de06f Noralf Trønnes 2020-05-29 913 goto unlock;
364f31b46de06f Noralf Trønnes 2020-05-29 914 }
364f31b46de06f Noralf Trønnes 2020-05-29 915
364f31b46de06f Noralf Trønnes 2020-05-29 916 buf = kcalloc(gconn->num_tv_mode_enum_names, DRM_PROP_NAME_LEN, GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 917 if (!buf) {
364f31b46de06f Noralf Trønnes 2020-05-29 918 ret = -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 919 goto unlock;
364f31b46de06f Noralf Trønnes 2020-05-29 920 }
364f31b46de06f Noralf Trønnes 2020-05-29 921
364f31b46de06f Noralf Trønnes 2020-05-29 922 gconn->tv_mode_enum_names = buf;
364f31b46de06f Noralf Trønnes 2020-05-29 923
364f31b46de06f Noralf Trønnes 2020-05-29 924 list_for_each_entry(prop_enum, &property->enum_list, head) {
364f31b46de06f Noralf Trønnes 2020-05-29 925 strncpy(buf, prop_enum->name, DRM_PROP_NAME_LEN);
364f31b46de06f Noralf Trønnes 2020-05-29 926 buf += DRM_PROP_NAME_LEN;
364f31b46de06f Noralf Trønnes 2020-05-29 927 }
364f31b46de06f Noralf Trønnes 2020-05-29 928
364f31b46de06f Noralf Trønnes 2020-05-29 929 prop = GUD_DRM_PROPERTY_TV_MODE;
364f31b46de06f Noralf Trønnes 2020-05-29 930 val = connector->state->tv.mode;
364f31b46de06f Noralf Trønnes 2020-05-29 931 val |= gconn->num_tv_mode_enum_names << GUD_DRM_USB_CONNECTOR_TV_MODE_NUM_SHIFT;
364f31b46de06f Noralf Trønnes 2020-05-29 932 } else if (property == config->tv_brightness_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 933 prop = GUD_DRM_PROPERTY_TV_BRIGHTNESS;
364f31b46de06f Noralf Trønnes 2020-05-29 934 val = connector->state->tv.brightness;
364f31b46de06f Noralf Trønnes 2020-05-29 935 } else if (property == config->tv_contrast_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 936 prop = GUD_DRM_PROPERTY_TV_CONTRAST;
364f31b46de06f Noralf Trønnes 2020-05-29 937 val = connector->state->tv.contrast;
364f31b46de06f Noralf Trønnes 2020-05-29 938 } else if (property == config->tv_flicker_reduction_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 939 prop = GUD_DRM_PROPERTY_TV_FLICKER_REDUCTION;
364f31b46de06f Noralf Trønnes 2020-05-29 940 val = connector->state->tv.flicker_reduction;
364f31b46de06f Noralf Trønnes 2020-05-29 941 } else if (property == config->tv_overscan_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 942 prop = GUD_DRM_PROPERTY_TV_OVERSCAN;
364f31b46de06f Noralf Trønnes 2020-05-29 943 val = connector->state->tv.overscan;
364f31b46de06f Noralf Trønnes 2020-05-29 944 } else if (property == config->tv_saturation_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 945 prop = GUD_DRM_PROPERTY_TV_SATURATION;
364f31b46de06f Noralf Trønnes 2020-05-29 946 val = connector->state->tv.saturation;
364f31b46de06f Noralf Trønnes 2020-05-29 947 } else if (property == config->tv_hue_property) {
364f31b46de06f Noralf Trønnes 2020-05-29 948 prop = GUD_DRM_PROPERTY_TV_HUE;
364f31b46de06f Noralf Trønnes 2020-05-29 949 val = connector->state->tv.hue;
364f31b46de06f Noralf Trønnes 2020-05-29 950 } else {
364f31b46de06f Noralf Trønnes 2020-05-29 951 continue;
364f31b46de06f Noralf Trønnes 2020-05-29 952 }
364f31b46de06f Noralf Trønnes 2020-05-29 953
364f31b46de06f Noralf Trønnes 2020-05-29 954 properties[gconn->num_properties].prop = cpu_to_le16(prop);
364f31b46de06f Noralf Trønnes 2020-05-29 955 properties[gconn->num_properties++].val = cpu_to_le64(val);
364f31b46de06f Noralf Trønnes 2020-05-29 956 }
364f31b46de06f Noralf Trønnes 2020-05-29 957
364f31b46de06f Noralf Trønnes 2020-05-29 958 if (!connector->index && gdg->backlight) {
364f31b46de06f Noralf Trønnes 2020-05-29 959 struct backlight_properties *props = &gdg->backlight->props;
364f31b46de06f Noralf Trønnes 2020-05-29 960
364f31b46de06f Noralf Trønnes 2020-05-29 961 prop = GUD_DRM_PROPERTY_BACKLIGHT_BRIGHTNESS;
364f31b46de06f Noralf Trønnes 2020-05-29 962 val = DIV64_U64_ROUND_UP(props->brightness * 100, props->max_brightness);
364f31b46de06f Noralf Trønnes 2020-05-29 963 properties[gconn->num_properties].prop = cpu_to_le16(prop);
364f31b46de06f Noralf Trønnes 2020-05-29 964 properties[gconn->num_properties++].val = cpu_to_le64(val);
364f31b46de06f Noralf Trønnes 2020-05-29 965 gconn->backlight = gdg->backlight;
364f31b46de06f Noralf Trønnes 2020-05-29 966 }
364f31b46de06f Noralf Trønnes 2020-05-29 967 unlock:
364f31b46de06f Noralf Trønnes 2020-05-29 968 mutex_unlock(&drm->mode_config.mutex);
364f31b46de06f Noralf Trønnes 2020-05-29 969
364f31b46de06f Noralf Trønnes 2020-05-29 970 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 971 }
364f31b46de06f Noralf Trønnes 2020-05-29 972
364f31b46de06f Noralf Trønnes 2020-05-29 973 static int gud_drm_gadget_get_connectors(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 974 {
364f31b46de06f Noralf Trønnes 2020-05-29 975 struct gud_drm_gadget_connector *connectors = NULL;
364f31b46de06f Noralf Trønnes 2020-05-29 976 struct drm_connector_list_iter conn_iter;
364f31b46de06f Noralf Trønnes 2020-05-29 977 struct drm_device *drm = gdg->client.dev;
364f31b46de06f Noralf Trønnes 2020-05-29 978 unsigned int connector_count = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 979 struct drm_connector *connector;
364f31b46de06f Noralf Trønnes 2020-05-29 980 int ret = 0;
364f31b46de06f Noralf Trønnes 2020-05-29 981
364f31b46de06f Noralf Trønnes 2020-05-29 982 drm_connector_list_iter_begin(drm, &conn_iter);
364f31b46de06f Noralf Trønnes 2020-05-29 983 drm_client_for_each_connector_iter(connector, &conn_iter) {
364f31b46de06f Noralf Trønnes 2020-05-29 984 struct gud_drm_gadget_connector *tmp, *gconn;
364f31b46de06f Noralf Trønnes 2020-05-29 985
364f31b46de06f Noralf Trønnes 2020-05-29 986 tmp = krealloc(connectors, (connector_count + 1) * sizeof(*connectors),
364f31b46de06f Noralf Trønnes 2020-05-29 987 GFP_KERNEL | __GFP_ZERO);
364f31b46de06f Noralf Trønnes 2020-05-29 988 if (!tmp) {
364f31b46de06f Noralf Trønnes 2020-05-29 989 ret = -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 990 break;
364f31b46de06f Noralf Trønnes 2020-05-29 991 }
364f31b46de06f Noralf Trønnes 2020-05-29 992
364f31b46de06f Noralf Trønnes 2020-05-29 993 connectors = tmp;
364f31b46de06f Noralf Trønnes 2020-05-29 994 drm_connector_get(connector);
364f31b46de06f Noralf Trønnes 2020-05-29 995 gconn = &connectors[connector_count++];
364f31b46de06f Noralf Trønnes 2020-05-29 996 gconn->connector = connector;
364f31b46de06f Noralf Trønnes 2020-05-29 997 spin_lock_init(&gconn->lock);
364f31b46de06f Noralf Trønnes 2020-05-29 998
364f31b46de06f Noralf Trønnes 2020-05-29 999 ret = gud_drm_gadget_get_connector_properties(gdg, gconn);
364f31b46de06f Noralf Trønnes 2020-05-29 1000 if (ret)
364f31b46de06f Noralf Trønnes 2020-05-29 1001 break;
364f31b46de06f Noralf Trønnes 2020-05-29 1002 }
364f31b46de06f Noralf Trønnes 2020-05-29 1003 drm_connector_list_iter_end(&conn_iter);
364f31b46de06f Noralf Trønnes 2020-05-29 1004
364f31b46de06f Noralf Trønnes 2020-05-29 1005 gdg->connectors = connectors;
364f31b46de06f Noralf Trønnes 2020-05-29 1006 gdg->connector_count = connector_count;
364f31b46de06f Noralf Trønnes 2020-05-29 1007
364f31b46de06f Noralf Trønnes 2020-05-29 1008 return ret;
364f31b46de06f Noralf Trønnes 2020-05-29 1009 }
364f31b46de06f Noralf Trønnes 2020-05-29 1010
364f31b46de06f Noralf Trønnes 2020-05-29 1011 static void gud_drm_gadget_release(struct kref *kref)
364f31b46de06f Noralf Trønnes 2020-05-29 1012 {
364f31b46de06f Noralf Trønnes 2020-05-29 1013 struct gud_drm_gadget *gdg = container_of(kref, struct gud_drm_gadget, refcount);
364f31b46de06f Noralf Trønnes 2020-05-29 1014
364f31b46de06f Noralf Trønnes 2020-05-29 1015 kfree(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1016 }
364f31b46de06f Noralf Trønnes 2020-05-29 1017
364f31b46de06f Noralf Trønnes 2020-05-29 1018 static void gud_drm_gadget_put(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 1019 {
364f31b46de06f Noralf Trønnes 2020-05-29 1020 kref_put(&gdg->refcount, gud_drm_gadget_release);
364f31b46de06f Noralf Trønnes 2020-05-29 1021 }
364f31b46de06f Noralf Trønnes 2020-05-29 1022
364f31b46de06f Noralf Trønnes 2020-05-29 1023 static void gud_drm_gadget_client_unregister(struct drm_client_dev *client)
364f31b46de06f Noralf Trønnes 2020-05-29 1024 {
364f31b46de06f Noralf Trønnes 2020-05-29 1025 struct gud_drm_gadget *gdg = container_of(client, struct gud_drm_gadget, client);
364f31b46de06f Noralf Trønnes 2020-05-29 1026 int timeout = 10000 / 50;
364f31b46de06f Noralf Trønnes 2020-05-29 1027 unsigned int i;
364f31b46de06f Noralf Trønnes 2020-05-29 1028
364f31b46de06f Noralf Trønnes 2020-05-29 1029 /*
364f31b46de06f Noralf Trønnes 2020-05-29 1030 * If usecnt doesn't drop to zero, try waiting for the gadget, but we
364f31b46de06f Noralf Trønnes 2020-05-29 1031 * can't block the DRM driver forever. The worst case wait the gadget side
364f31b46de06f Noralf Trønnes 2020-05-29 1032 * can hit are tens of seconds through the call to drm_client_modeset_commit().
364f31b46de06f Noralf Trønnes 2020-05-29 1033 */
364f31b46de06f Noralf Trønnes 2020-05-29 1034 if (refcount_dec_and_test(&gdg->usecnt)) {
364f31b46de06f Noralf Trønnes 2020-05-29 1035 for (; timeout && refcount_read(&gdg->usecnt); timeout--)
364f31b46de06f Noralf Trønnes 2020-05-29 1036 msleep(50);
364f31b46de06f Noralf Trønnes 2020-05-29 1037 }
364f31b46de06f Noralf Trønnes 2020-05-29 1038
364f31b46de06f Noralf Trønnes 2020-05-29 1039 if (!timeout) {
364f31b46de06f Noralf Trønnes 2020-05-29 1040 pr_err("%s: Timeout waiting for gadget side, will leak memory\n", __func__);
364f31b46de06f Noralf Trønnes 2020-05-29 1041 return;
364f31b46de06f Noralf Trønnes 2020-05-29 1042 }
364f31b46de06f Noralf Trønnes 2020-05-29 1043
364f31b46de06f Noralf Trønnes 2020-05-29 1044 vfree(gdg->work_buf);
364f31b46de06f Noralf Trønnes 2020-05-29 1045 kfree(gdg->formats);
364f31b46de06f Noralf Trønnes 2020-05-29 1046 kfree(gdg->properties);
364f31b46de06f Noralf Trønnes 2020-05-29 1047
364f31b46de06f Noralf Trønnes 2020-05-29 1048 for (i = 0; i < gdg->connector_count; i++) {
364f31b46de06f Noralf Trønnes 2020-05-29 1049 struct gud_drm_gadget_connector *gconn = &gdg->connectors[i];
364f31b46de06f Noralf Trønnes 2020-05-29 1050
364f31b46de06f Noralf Trønnes 2020-05-29 1051 drm_connector_put(gconn->connector);
364f31b46de06f Noralf Trønnes 2020-05-29 1052 kfree(gconn->properties);
364f31b46de06f Noralf Trønnes 2020-05-29 1053 kfree(gconn->tv_mode_enum_names);
364f31b46de06f Noralf Trønnes 2020-05-29 1054 kfree(gconn->modes);
364f31b46de06f Noralf Trønnes 2020-05-29 1055 kfree(gconn->edid);
364f31b46de06f Noralf Trønnes 2020-05-29 1056 }
364f31b46de06f Noralf Trønnes 2020-05-29 1057 kfree(gdg->connectors);
364f31b46de06f Noralf Trønnes 2020-05-29 1058
364f31b46de06f Noralf Trønnes 2020-05-29 1059 gud_drm_gadget_delete_buffers(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1060 drm_client_release(client);
364f31b46de06f Noralf Trønnes 2020-05-29 1061 gud_drm_gadget_put(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1062 }
364f31b46de06f Noralf Trønnes 2020-05-29 1063
364f31b46de06f Noralf Trønnes 2020-05-29 1064 static int gud_drm_gadget_client_hotplug(struct drm_client_dev *client)
364f31b46de06f Noralf Trønnes 2020-05-29 1065 {
364f31b46de06f Noralf Trønnes 2020-05-29 1066 struct gud_drm_gadget *gdg = container_of(client, struct gud_drm_gadget, client);
364f31b46de06f Noralf Trønnes 2020-05-29 1067
364f31b46de06f Noralf Trønnes 2020-05-29 1068 gud_drm_gadget_probe_connectors(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1069
364f31b46de06f Noralf Trønnes 2020-05-29 1070 return 0;
364f31b46de06f Noralf Trønnes 2020-05-29 1071 }
364f31b46de06f Noralf Trønnes 2020-05-29 1072
364f31b46de06f Noralf Trønnes 2020-05-29 1073 static const struct drm_client_funcs gdg_client_funcs = {
364f31b46de06f Noralf Trønnes 2020-05-29 1074 .owner = THIS_MODULE,
364f31b46de06f Noralf Trønnes 2020-05-29 1075 .unregister = gud_drm_gadget_client_unregister,
364f31b46de06f Noralf Trønnes 2020-05-29 1076 .hotplug = gud_drm_gadget_client_hotplug,
364f31b46de06f Noralf Trønnes 2020-05-29 1077 };
364f31b46de06f Noralf Trønnes 2020-05-29 1078
364f31b46de06f Noralf Trønnes 2020-05-29 1079 struct gud_drm_gadget *gud_drm_gadget_init(unsigned int minor_id, const char *backlight,
364f31b46de06f Noralf Trønnes 2020-05-29 1080 size_t *max_buffer_size)
364f31b46de06f Noralf Trønnes 2020-05-29 1081 {
364f31b46de06f Noralf Trønnes 2020-05-29 1082 struct gud_drm_gadget *gdg;
364f31b46de06f Noralf Trønnes 2020-05-29 1083 u8 max_cpp;
364f31b46de06f Noralf Trønnes 2020-05-29 1084 int ret;
364f31b46de06f Noralf Trønnes 2020-05-29 1085
364f31b46de06f Noralf Trønnes 2020-05-29 1086 gdg = kzalloc(sizeof(*gdg), GFP_KERNEL);
364f31b46de06f Noralf Trønnes 2020-05-29 1087 if (!gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 1088 return ERR_PTR(-ENOMEM);
364f31b46de06f Noralf Trønnes 2020-05-29 1089
364f31b46de06f Noralf Trønnes 2020-05-29 1090 ret = drm_client_init_from_id(minor_id, &gdg->client, "gud-drm-gadget", &gdg_client_funcs);
364f31b46de06f Noralf Trønnes 2020-05-29 1091 if (ret) {
364f31b46de06f Noralf Trønnes 2020-05-29 1092 pr_err("Failed to aquire minor=%u\n", minor_id);
364f31b46de06f Noralf Trønnes 2020-05-29 1093 kfree(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1094 return ERR_PTR(ret);
364f31b46de06f Noralf Trønnes 2020-05-29 1095 }
364f31b46de06f Noralf Trønnes 2020-05-29 1096
364f31b46de06f Noralf Trønnes 2020-05-29 1097 refcount_set(&gdg->usecnt, 1);
364f31b46de06f Noralf Trønnes 2020-05-29 1098 /* The DRM driver (through the client) and f_gud_drm need one ref each */
364f31b46de06f Noralf Trønnes 2020-05-29 1099 kref_init(&gdg->refcount);
364f31b46de06f Noralf Trønnes 2020-05-29 1100 kref_get(&gdg->refcount);
364f31b46de06f Noralf Trønnes 2020-05-29 1101
364f31b46de06f Noralf Trønnes 2020-05-29 1102 if (backlight) {
364f31b46de06f Noralf Trønnes 2020-05-29 1103 gdg->backlight = backlight_device_get_by_name(backlight);
364f31b46de06f Noralf Trønnes 2020-05-29 1104 if (!gdg->backlight) {
364f31b46de06f Noralf Trønnes 2020-05-29 1105 pr_err("Failed to find backlight: %s\n", backlight);
364f31b46de06f Noralf Trønnes 2020-05-29 1106 ret = -ENODEV;
364f31b46de06f Noralf Trønnes 2020-05-29 1107 goto error_release;
364f31b46de06f Noralf Trønnes 2020-05-29 1108 }
364f31b46de06f Noralf Trønnes 2020-05-29 1109 }
364f31b46de06f Noralf Trønnes 2020-05-29 1110
364f31b46de06f Noralf Trønnes 2020-05-29 1111 ret = gud_drm_gadget_get_formats(gdg, &max_cpp);
364f31b46de06f Noralf Trønnes 2020-05-29 1112 if (ret) {
364f31b46de06f Noralf Trønnes 2020-05-29 1113 pr_err("Failed to get formats\n");
364f31b46de06f Noralf Trønnes 2020-05-29 1114 goto error_release;
364f31b46de06f Noralf Trønnes 2020-05-29 1115 }
364f31b46de06f Noralf Trønnes 2020-05-29 1116
364f31b46de06f Noralf Trønnes 2020-05-29 1117 *max_buffer_size = gdg->client.dev->mode_config.max_width *
364f31b46de06f Noralf Trønnes 2020-05-29 1118 gdg->client.dev->mode_config.max_height * max_cpp;
364f31b46de06f Noralf Trønnes 2020-05-29 1119 /* f_gud_drm will kmalloc a buffer of this size */
364f31b46de06f Noralf Trønnes 2020-05-29 1120 *max_buffer_size = min_t(size_t, *max_buffer_size, KMALLOC_MAX_SIZE);
364f31b46de06f Noralf Trønnes 2020-05-29 1121
364f31b46de06f Noralf Trønnes 2020-05-29 1122 gdg->max_buffer_size = *max_buffer_size;
364f31b46de06f Noralf Trønnes 2020-05-29 1123 gdg->work_buf = vmalloc(gdg->max_buffer_size);
364f31b46de06f Noralf Trønnes 2020-05-29 1124 if (!gdg->work_buf) {
364f31b46de06f Noralf Trønnes 2020-05-29 1125 ret = -ENOMEM;
364f31b46de06f Noralf Trønnes 2020-05-29 1126 goto error_release;
364f31b46de06f Noralf Trønnes 2020-05-29 1127 }
364f31b46de06f Noralf Trønnes 2020-05-29 1128
364f31b46de06f Noralf Trønnes 2020-05-29 1129 ret = gud_drm_gadget_get_properties(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1130 if (ret) {
364f31b46de06f Noralf Trønnes 2020-05-29 1131 pr_err("Failed to get properties\n");
364f31b46de06f Noralf Trønnes 2020-05-29 1132 goto error_release;
364f31b46de06f Noralf Trønnes 2020-05-29 1133 }
364f31b46de06f Noralf Trønnes 2020-05-29 1134
364f31b46de06f Noralf Trønnes 2020-05-29 1135 ret = gud_drm_gadget_get_connectors(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1136 if (ret) {
364f31b46de06f Noralf Trønnes 2020-05-29 1137 pr_err("Failed to get connectors\n");
364f31b46de06f Noralf Trønnes 2020-05-29 1138 goto error_release;
364f31b46de06f Noralf Trønnes 2020-05-29 1139 }
364f31b46de06f Noralf Trønnes 2020-05-29 1140
364f31b46de06f Noralf Trønnes 2020-05-29 1141 if (!drm_client_register(&gdg->client)) {
364f31b46de06f Noralf Trønnes 2020-05-29 1142 pr_err("DRM device is gone\n");
364f31b46de06f Noralf Trønnes 2020-05-29 1143 ret = -ENODEV;
364f31b46de06f Noralf Trønnes 2020-05-29 1144 goto error_release;
364f31b46de06f Noralf Trønnes 2020-05-29 1145 }
364f31b46de06f Noralf Trønnes 2020-05-29 1146
364f31b46de06f Noralf Trønnes 2020-05-29 1147 gud_drm_gadget_probe_connectors(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1148
364f31b46de06f Noralf Trønnes 2020-05-29 1149 return gdg;
364f31b46de06f Noralf Trønnes 2020-05-29 1150
364f31b46de06f Noralf Trønnes 2020-05-29 1151 error_release:
364f31b46de06f Noralf Trønnes 2020-05-29 1152 gud_drm_gadget_client_unregister(&gdg->client);
364f31b46de06f Noralf Trønnes 2020-05-29 1153 gud_drm_gadget_fini(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1154
364f31b46de06f Noralf Trønnes 2020-05-29 1155 return ERR_PTR(ret);
364f31b46de06f Noralf Trønnes 2020-05-29 1156 }
364f31b46de06f Noralf Trønnes 2020-05-29 1157 EXPORT_SYMBOL(gud_drm_gadget_init);
364f31b46de06f Noralf Trønnes 2020-05-29 1158
364f31b46de06f Noralf Trønnes 2020-05-29 1159 void gud_drm_gadget_fini(struct gud_drm_gadget *gdg)
364f31b46de06f Noralf Trønnes 2020-05-29 1160 {
364f31b46de06f Noralf Trønnes 2020-05-29 @1161 backlight_put(gdg->backlight);
364f31b46de06f Noralf Trønnes 2020-05-29 1162 gud_drm_gadget_put(gdg);
364f31b46de06f Noralf Trønnes 2020-05-29 1163 }
364f31b46de06f Noralf Trønnes 2020-05-29 1164 EXPORT_SYMBOL(gud_drm_gadget_fini);
364f31b46de06f Noralf Trønnes 2020-05-29 1165
364f31b46de06f Noralf Trønnes 2020-05-29 1166 MODULE_AUTHOR("Noralf Trønnes");
364f31b46de06f Noralf Trønnes 2020-05-29 1167 MODULE_LICENSE("GPL");
:::::: The code at line 1161 was first introduced by commit
:::::: 364f31b46de06f1ec6f1a5185f34aa385a7043ac drm/gud: Add functionality for the USB gadget side
:::::: TO: Noralf Trønnes <noralf(a)tronnes.org>
:::::: CC: Lubomir Rintel <lkundrak(a)v3.sk>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
[hch-misc:dma_alloc_pages 17/17] kernel/dma/mapping.c:512:9: error: implicit declaration of function 'dma_alloc_contiguous'
by kernel test robot
tree: git://git.infradead.org/users/hch/misc.git dma_alloc_pages
head: ebfa77e612f8650cb120011030b7a9e951ebee56
commit: ebfa77e612f8650cb120011030b7a9e951ebee56 [17/17] dma-mapping: replace DMA_ATTR_NON_CONSISTENT with dma_{alloc,free}_pages
config: h8300-randconfig-r006-20200817 (attached as .config)
compiler: h8300-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout ebfa77e612f8650cb120011030b7a9e951ebee56
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=h8300
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All error/warnings (new ones prefixed by >>):
kernel/dma/mapping.c: In function 'dma_simple_alloc_pages':
>> kernel/dma/mapping.c:512:9: error: implicit declaration of function 'dma_alloc_contiguous' [-Werror=implicit-function-declaration]
512 | page = dma_alloc_contiguous(dev, size, gfp | __GFP_ZERO);
| ^~~~~~~~~~~~~~~~~~~~
>> kernel/dma/mapping.c:512:7: warning: assignment to 'struct page *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
512 | page = dma_alloc_contiguous(dev, size, gfp | __GFP_ZERO);
| ^
>> kernel/dma/mapping.c:518:3: error: implicit declaration of function 'dma_free_contiguous'; did you mean 'set_zone_contiguous'? [-Werror=implicit-function-declaration]
518 | dma_free_contiguous(dev, page, size);
| ^~~~~~~~~~~~~~~~~~~
| set_zone_contiguous
cc1: some warnings being treated as errors
git remote add hch-misc git://git.infradead.org/users/hch/misc.git
git fetch --no-tags hch-misc dma_alloc_pages
git checkout ebfa77e612f8650cb120011030b7a9e951ebee56
vim +/dma_alloc_contiguous +512 kernel/dma/mapping.c
506
507 static void *dma_simple_alloc_pages(struct device *dev, size_t size,
508 dma_addr_t *dma_handle, gfp_t gfp)
509 {
510 struct page *page;
511
> 512 page = dma_alloc_contiguous(dev, size, gfp | __GFP_ZERO);
513 if (!page)
514 return NULL;
515 *dma_handle = dma_map_page_attrs(dev, page, 0, size, DMA_BIDIRECTIONAL,
516 DMA_ATTR_SKIP_CPU_SYNC);
517 if (dma_mapping_error(dev, *dma_handle)) {
> 518 dma_free_contiguous(dev, page, size);
519 return NULL;
520 }
521
522 return page_address(page);
523 }
524
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month
[efi:urgent 6/7] arch/x86/platform/efi/efi_32.c:53:20: sparse: sparse: incorrect type in assignment (different address spaces)
by kernel test robot
tree: https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git urgent
head: 477ecfc4260135c7a37f18e7648f0b135dcd352a
commit: b6c3e5b587677c0c7cf4b21eb6e89e77a18f4482 [6/7] efi/x86: Move 32-bit code into efi_32.c
config: i386-randconfig-s001-20200817 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.2-180-g49f7e13a-dirty
git checkout b6c3e5b587677c0c7cf4b21eb6e89e77a18f4482
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
sparse warnings: (new ones prefixed by >>)
>> arch/x86/platform/efi/efi_32.c:53:20: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected void *[assigned] va @@ got void [noderef] __iomem * @@
>> arch/x86/platform/efi/efi_32.c:53:20: sparse: expected void *[assigned] va
>> arch/x86/platform/efi/efi_32.c:53:20: sparse: got void [noderef] __iomem *
# https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git/commit/?id=b6...
git remote add efi https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
git fetch --no-tags efi urgent
git checkout b6c3e5b587677c0c7cf4b21eb6e89e77a18f4482
vim +53 arch/x86/platform/efi/efi_32.c
35
36 void __init efi_map_region(efi_memory_desc_t *md)
37 {
38 u64 start_pfn, end_pfn, end;
39 unsigned long size;
40 void *va;
41
42 start_pfn = PFN_DOWN(md->phys_addr);
43 size = md->num_pages << PAGE_SHIFT;
44 end = md->phys_addr + size;
45 end_pfn = PFN_UP(end);
46
47 if (pfn_range_is_mapped(start_pfn, end_pfn)) {
48 va = __va(md->phys_addr);
49
50 if (!(md->attribute & EFI_MEMORY_WB))
51 set_memory_uc((unsigned long)va, md->num_pages);
52 } else {
> 53 va = efi_ioremap(md->phys_addr, size,
54 md->type, md->attribute);
55 }
56
57 md->virt_addr = (unsigned long)va;
58 if (!va)
59 pr_err("ioremap of 0x%llX failed!\n", md->phys_addr);
60 }
61
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
2 years, 1 month