Hi Anup, Thank you for the patch! Yet something to improve: [auto build test ERROR on robh/for-next] [also build test ERROR on linus/master v5.8-rc3 next-20200629] [cannot apply to tip/timers/core] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Anup-Patel/Dedicated-CLINT-timer-driver/20200628-002253 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next config: riscv-randconfig-r036-20200629 (attached as .config) compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project a28d38a6bca1726d56c9b373f4c7dc5264fc7716) 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 riscv cross compiling tool for clang build # apt-get install binutils-riscv64-linux-gnu # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:556:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return inb(addr); ^~~~~~~~~ arch/riscv/include/asm/io.h:54:76: note: expanded from macro 'inb' #define inb(c) ({ u8 __v; __io_pbr(); __v = readb_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:93:48: note: expanded from macro 'readb_cpu' #define readb_cpu(c) ({ u8 __r = __raw_readb(c); __r; }) ^ In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:564:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return inw(addr); ^~~~~~~~~ arch/riscv/include/asm/io.h:55:76: note: expanded from macro 'inw' #define inw(c) ({ u16 __v; __io_pbr(); __v = readw_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:94:76: note: expanded from macro 'readw_cpu' #define readw_cpu(c) ({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; }) ^ include/uapi/linux/byteorder/little_endian.h:36:51: note: expanded from macro '__le16_to_cpu' #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) ^ In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:572:9: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return inl(addr); ^~~~~~~~~ arch/riscv/include/asm/io.h:56:76: note: expanded from macro 'inl' #define inl(c) ({ u32 __v; __io_pbr(); __v = readl_cpu((void*)(PCI_IOBASE + (c))); __io_par(__v); __v; }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:95:76: note: expanded from macro 'readl_cpu' #define readl_cpu(c) ({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; }) ^ include/uapi/linux/byteorder/little_endian.h:34:51: note: expanded from macro '__le32_to_cpu' #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) ^ In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:580:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] outb(value, addr); ^~~~~~~~~~~~~~~~~ arch/riscv/include/asm/io.h:58:68: note: expanded from macro 'outb' #define outb(v,c) ({ __io_pbw(); writeb_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:97:52: note: expanded from macro 'writeb_cpu' #define writeb_cpu(v, c) ((void)__raw_writeb((v), (c))) ^ In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:588:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] outw(value, addr); ^~~~~~~~~~~~~~~~~ arch/riscv/include/asm/io.h:59:68: note: expanded from macro 'outw' #define outw(v,c) ({ __io_pbw(); writew_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:98:76: note: expanded from macro 'writew_cpu' #define writew_cpu(v, c) ((void)__raw_writew((__force u16)cpu_to_le16(v), (c))) ^ In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:596:2: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] outl(value, addr); ^~~~~~~~~~~~~~~~~ arch/riscv/include/asm/io.h:60:68: note: expanded from macro 'outl' #define outl(v,c) ({ __io_pbw(); writel_cpu((v),(void*)(PCI_IOBASE + (c))); __io_paw(); }) ~~~~~~~~~~ ^ arch/riscv/include/asm/mmio.h:99:76: note: expanded from macro 'writel_cpu' #define writel_cpu(v, c) ((void)__raw_writel((__force u32)cpu_to_le32(v), (c))) ^ In file included from drivers/clocksource/timer-clint.c:11: In file included from include/linux/clocksource.h:21: In file included from arch/riscv/include/asm/io.h:148: include/asm-generic/io.h:1017:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port; ~~~~~~~~~~ ^ >> drivers/clocksource/timer-clint.c:47:29: error: variable has incomplete type 'struct riscv_ipi_ops' static struct riscv_ipi_ops clint_ipi_ops = { ^ drivers/clocksource/timer-clint.c:47:15: note: forward declaration of 'struct riscv_ipi_ops' static struct riscv_ipi_ops clint_ipi_ops = { ^ >> drivers/clocksource/timer-clint.c:222:2: error: implicit declaration of function 'riscv_set_ipi_ops' [-Werror,-Wimplicit-function-declaration] riscv_set_ipi_ops(&clint_ipi_ops); ^ 7 warnings and 2 errors generated. vim +47 drivers/clocksource/timer-clint.c 46 > 47 static struct riscv_ipi_ops clint_ipi_ops = { 48 .ipi_inject = clint_send_ipi, 49 .ipi_clear = clint_clear_ipi, 50 }; 51 52 #ifdef CONFIG_64BIT 53 #define clint_get_cycles() readq_relaxed(clint_timer_val) 54 #else 55 #define clint_get_cycles() readl_relaxed(clint_timer_val) 56 #define clint_get_cycles_hi() readl_relaxed(((u32 *)clint_timer_val) + 1) 57 #endif 58 59 #ifdef CONFIG_64BIT 60 static u64 clint_get_cycles64(void) 61 { 62 return clint_get_cycles(); 63 } 64 #else /* CONFIG_64BIT */ 65 static u64 clint_get_cycles64(void) 66 { 67 u32 hi, lo; 68 69 do { 70 hi = clint_get_cycles_hi(); 71 lo = clint_get_cycles(); 72 } while (hi != clint_get_cycles_hi()); 73 74 return ((u64)hi << 32) | lo; 75 } 76 #endif /* CONFIG_64BIT */ 77 78 static int clint_clock_next_event(unsigned long delta, 79 struct clock_event_device *ce) 80 { 81 void __iomem *r = clint_timer_cmp + 82 cpuid_to_hartid_map(smp_processor_id()); 83 84 csr_set(CSR_IE, IE_TIE); 85 writeq_relaxed(clint_get_cycles64() + delta, r); 86 return 0; 87 } 88 89 static DEFINE_PER_CPU(struct clock_event_device, clint_clock_event) = { 90 .name = "clint_clockevent", 91 .features = CLOCK_EVT_FEAT_ONESHOT, 92 .rating = 100, 93 .set_next_event = clint_clock_next_event, 94 }; 95 96 static u64 clint_rdtime(struct clocksource *cs) 97 { 98 return readq_relaxed(clint_timer_val); 99 } 100 101 static u64 notrace clint_sched_clock(void) 102 { 103 return readq_relaxed(clint_timer_val); 104 } 105 106 static struct clocksource clint_clocksource = { 107 .name = "clint_clocksource", 108 .rating = 300, 109 .mask = CLOCKSOURCE_MASK(64), 110 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 111 .read = clint_rdtime, 112 }; 113 114 static int clint_timer_starting_cpu(unsigned int cpu) 115 { 116 struct clock_event_device *ce = per_cpu_ptr(&clint_clock_event, cpu); 117 118 ce->cpumask = cpumask_of(cpu); 119 clockevents_config_and_register(ce, clint_timer_freq, 200, ULONG_MAX); 120 121 enable_percpu_irq(clint_timer_irq, 122 irq_get_trigger_type(clint_timer_irq)); 123 return 0; 124 } 125 126 static int clint_timer_dying_cpu(unsigned int cpu) 127 { 128 disable_percpu_irq(clint_timer_irq); 129 return 0; 130 } 131 132 static irqreturn_t clint_timer_interrupt(int irq, void *dev_id) 133 { 134 struct clock_event_device *evdev = this_cpu_ptr(&clint_clock_event); 135 136 csr_clear(CSR_IE, IE_TIE); 137 evdev->event_handler(evdev); 138 139 return IRQ_HANDLED; 140 } 141 142 static int __init clint_timer_init_dt(struct device_node *np) 143 { 144 int rc; 145 u32 i, nr_irqs; 146 void __iomem *base; 147 struct of_phandle_args oirq; 148 149 /* 150 * Ensure that CLINT device interrupts are either RV_IRQ_TIMER or 151 * RV_IRQ_SOFT. If it's anything else then we ignore the device. 152 */ 153 nr_irqs = of_irq_count(np); 154 for (i = 0; i < nr_irqs; i++) { 155 if (of_irq_parse_one(np, i, &oirq)) { 156 pr_err("%pOFP: failed to parse irq %d.\n", np, i); 157 continue; 158 } 159 160 if ((oirq.args_count != 1) || 161 (oirq.args[0] != RV_IRQ_TIMER && 162 oirq.args[0] != RV_IRQ_SOFT)) { 163 pr_err("%pOFP: invalid irq %d (hwirq %d)\n", 164 np, i, oirq.args[0]); 165 return -ENODEV; 166 } 167 168 /* Find parent irq domain and map timer irq */ 169 if (!clint_timer_irq && 170 oirq.args[0] == RV_IRQ_TIMER && 171 irq_find_host(oirq.np)) 172 clint_timer_irq = irq_of_parse_and_map(np, i); 173 } 174 175 /* If CLINT timer irq not found then fail */ 176 if (!clint_timer_irq) { 177 pr_err("%pOFP: timer irq not found\n", np); 178 return -ENODEV; 179 } 180 181 base = of_iomap(np, 0); 182 if (!base) { 183 pr_err("%pOFP: could not map registers\n", np); 184 return -ENODEV; 185 } 186 187 clint_ipi_base = base + CLINT_IPI_OFF; 188 clint_timer_cmp = base + CLINT_TIMER_CMP_OFF; 189 clint_timer_val = base + CLINT_TIMER_VAL_OFF; 190 clint_timer_freq = riscv_timebase; 191 192 pr_info("%pOFP: timer running@%ld Hz\n", np, clint_timer_freq); 193 194 rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq); 195 if (rc) { 196 iounmap(base); 197 pr_err("%pOFP: clocksource register failed [%d]\n", np, rc); 198 return rc; 199 } 200 201 sched_clock_register(clint_sched_clock, 64, clint_timer_freq); 202 203 rc = request_percpu_irq(clint_timer_irq, clint_timer_interrupt, 204 "clint-timer", &clint_clock_event); 205 if (rc) { 206 iounmap(base); 207 pr_err("registering percpu irq failed [%d]\n", rc); 208 return rc; 209 } 210 211 rc = cpuhp_setup_state(CPUHP_AP_CLINT_TIMER_STARTING, 212 "clockevents/clint/timer:starting", 213 clint_timer_starting_cpu, 214 clint_timer_dying_cpu); 215 if (rc) { 216 free_irq(clint_timer_irq, &clint_clock_event); 217 iounmap(base); 218 pr_err("%pOFP: cpuhp setup state failed [%d]\n", np, rc); 219 return rc; 220 } 221 > 222 riscv_set_ipi_ops(&clint_ipi_ops); 223 clint_clear_ipi(); 224 225 return 0; 226 } 227 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org