Message ID | 20220113201920.3201760-4-laurent@vivier.eu |
---|---|
State | Superseded |
Headers | show |
Series | m68k: Add Virtual M68k Machine | expand |
Hi Laurent, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on geert-m68k/for-next] [also build test WARNING on linux/master v5.16] [cannot apply to tip/timers/core linus/master next-20220113] [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/Laurent-Vivier/m68k-Add-Virtual-M68k-Machine/20220114-042103 base: https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git for-next config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20220114/202201141238.HZZyqTBE-lkp@intel.com/config) compiler: s390-linux-gcc (GCC) 11.2.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 # https://github.com/0day-ci/linux/commit/7e887e6ec0d7193083a2f0020007688db2318c76 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Laurent-Vivier/m68k-Add-Virtual-M68k-Machine/20220114-042103 git checkout 7e887e6ec0d7193083a2f0020007688db2318c76 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=s390 SHELL=/bin/bash drivers/clocksource/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): drivers/clocksource/timer-goldfish.c: In function 'goldfish_timer_init': drivers/clocksource/timer-goldfish.c:94:20: error: implicit declaration of function 'kzalloc'; did you mean 'vzalloc'? [-Werror=implicit-function-declaration] 94 | timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); | ^~~~~~~ | vzalloc >> drivers/clocksource/timer-goldfish.c:94:18: warning: assignment to 'struct goldfish_timer *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 94 | timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); | ^ cc1: some warnings being treated as errors Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for RTC_CLASS Depends on !S390 Selected by - GOLDFISH_TIMER && GENERIC_CLOCKEVENTS WARNING: unmet direct dependencies detected for RTC_DRV_GOLDFISH Depends on RTC_CLASS && HAS_IOMEM Selected by - GOLDFISH_TIMER && GENERIC_CLOCKEVENTS vim +94 drivers/clocksource/timer-goldfish.c 88 89 void __init goldfish_timer_init(int irq, void __iomem *base) 90 { 91 struct goldfish_timer *timerdrv; 92 int ret; 93 > 94 timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Laurent, Thank you for the patch! Yet something to improve: [auto build test ERROR on geert-m68k/for-next] [also build test ERROR on linux/master v5.16] [cannot apply to tip/timers/core linus/master next-20220114] [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/Laurent-Vivier/m68k-Add-Virtual-M68k-Machine/20220114-042103 base: https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git for-next config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20220114/202201141640.iSJ8IkCj-lkp@intel.com/config) compiler: s390-linux-gcc (GCC) 11.2.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 # https://github.com/0day-ci/linux/commit/7e887e6ec0d7193083a2f0020007688db2318c76 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Laurent-Vivier/m68k-Add-Virtual-M68k-Machine/20220114-042103 git checkout 7e887e6ec0d7193083a2f0020007688db2318c76 # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=s390 SHELL=/bin/bash drivers/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): drivers/clocksource/timer-goldfish.c: In function 'goldfish_timer_init': >> drivers/clocksource/timer-goldfish.c:94:20: error: implicit declaration of function 'kzalloc'; did you mean 'vzalloc'? [-Werror=implicit-function-declaration] 94 | timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); | ^~~~~~~ | vzalloc drivers/clocksource/timer-goldfish.c:94:18: warning: assignment to 'struct goldfish_timer *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 94 | timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); | ^ cc1: some warnings being treated as errors Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for RTC_CLASS Depends on !S390 Selected by - GOLDFISH_TIMER && GENERIC_CLOCKEVENTS WARNING: unmet direct dependencies detected for RTC_DRV_GOLDFISH Depends on RTC_CLASS && HAS_IOMEM Selected by - GOLDFISH_TIMER && GENERIC_CLOCKEVENTS vim +94 drivers/clocksource/timer-goldfish.c 88 89 void __init goldfish_timer_init(int irq, void __iomem *base) 90 { 91 struct goldfish_timer *timerdrv; 92 int ret; 93 > 94 timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On Thu, Jan 13, 2022 at 9:19 PM Laurent Vivier <laurent@vivier.eu> wrote: > > Add a clocksource based on the goldfish-rtc device. > > Signed-off-by: Laurent Vivier <laurent@vivier.eu> > --- > drivers/clocksource/Kconfig | 7 ++ > drivers/clocksource/Makefile | 1 + > drivers/clocksource/timer-goldfish.c | 130 +++++++++++++++++++++++++++ > include/clocksource/timer-goldfish.h | 12 +++ > 4 files changed, 150 insertions(+) > create mode 100644 drivers/clocksource/timer-goldfish.c > create mode 100644 include/clocksource/timer-goldfish.h > > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig > index f65e31bab9ae..6ca9bb78407d 100644 > --- a/drivers/clocksource/Kconfig > +++ b/drivers/clocksource/Kconfig > @@ -711,4 +711,11 @@ config MICROCHIP_PIT64B > modes and high resolution. It is used as a clocksource > and a clockevent. > > +config GOLDFISH_TIMER > + bool "Clocksource using goldfish-rtc" > + select RTC_CLASS > + select RTC_DRV_GOLDFISH This should probably be depends on M68K || COMPILE_TEST depends on RTC_DRV_GOLDFISH A driver should never 'select' another user-selectable subsystem > +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) > +{ > + struct goldfish_timer *timerdrv = ced_to_gf(evt); > + void __iomem *base = timerdrv->base; > + > + __raw_writel(0, base + TIMER_ALARM_HIGH); > + __raw_writel(0, base + TIMER_ALARM_LOW); > + __raw_writel(1, base + TIMER_IRQ_ENABLED); As mentioned elsewhere, the __raw_* accessors are not portable, please use readl()/writel() here, or possibly ioread32_be()/iowrite32_be() for the big-endian variant. > +EXPORT_SYMBOL_GPL(goldfish_timer_init); No need to export this if the only callers are in the kernel. Arnd
Le 14/01/2022 à 11:46, Arnd Bergmann a écrit : > On Thu, Jan 13, 2022 at 9:19 PM Laurent Vivier <laurent@vivier.eu> wrote: >> >> Add a clocksource based on the goldfish-rtc device. >> >> Signed-off-by: Laurent Vivier <laurent@vivier.eu> >> --- >> drivers/clocksource/Kconfig | 7 ++ >> drivers/clocksource/Makefile | 1 + >> drivers/clocksource/timer-goldfish.c | 130 +++++++++++++++++++++++++++ >> include/clocksource/timer-goldfish.h | 12 +++ >> 4 files changed, 150 insertions(+) >> create mode 100644 drivers/clocksource/timer-goldfish.c >> create mode 100644 include/clocksource/timer-goldfish.h >> >> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig >> index f65e31bab9ae..6ca9bb78407d 100644 >> --- a/drivers/clocksource/Kconfig >> +++ b/drivers/clocksource/Kconfig >> @@ -711,4 +711,11 @@ config MICROCHIP_PIT64B >> modes and high resolution. It is used as a clocksource >> and a clockevent. >> >> +config GOLDFISH_TIMER >> + bool "Clocksource using goldfish-rtc" >> + select RTC_CLASS >> + select RTC_DRV_GOLDFISH > > This should probably be > > depends on M68K || COMPILE_TEST > depends on RTC_DRV_GOLDFISH > > A driver should never 'select' another user-selectable subsystem ok > >> +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) >> +{ >> + struct goldfish_timer *timerdrv = ced_to_gf(evt); >> + void __iomem *base = timerdrv->base; >> + >> + __raw_writel(0, base + TIMER_ALARM_HIGH); >> + __raw_writel(0, base + TIMER_ALARM_LOW); >> + __raw_writel(1, base + TIMER_IRQ_ENABLED); > > As mentioned elsewhere, the __raw_* accessors are not portable, please > use readl()/writel() here, or possibly ioread32_be()/iowrite32_be() for > the big-endian variant. We can't use readl()/writel() here because it's supposed to read from a little endian device, and goldfish endianness depends on the endianness of the machine. For goldfish, readl()/writel() works fine on little-endian machine but not on big-endian machine. On m68k, you have: #define readl(addr) in_le32(addr) #define writel(val,addr) out_le32((addr),(val)) and with goldfish it's wrong as the device is not little-endian, it is big-endian like the machine. same comment with ioread32_be()/iowrite32_be(): it will work on big-endian machine not on little-endian. We need an accessor that doesn't byteswap the value, that accesses it natively, and in all other parts of the kernel __raw_writel() and __raw_readl() are used. Thanks, Laurent
Hi Laurent, On Fri, Jan 14, 2022 at 12:03 PM Laurent Vivier <laurent@vivier.eu> wrote: > Le 14/01/2022 à 11:46, Arnd Bergmann a écrit : > > On Thu, Jan 13, 2022 at 9:19 PM Laurent Vivier <laurent@vivier.eu> wrote: > >> +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) > >> +{ > >> + struct goldfish_timer *timerdrv = ced_to_gf(evt); > >> + void __iomem *base = timerdrv->base; > >> + > >> + __raw_writel(0, base + TIMER_ALARM_HIGH); > >> + __raw_writel(0, base + TIMER_ALARM_LOW); > >> + __raw_writel(1, base + TIMER_IRQ_ENABLED); > > > > As mentioned elsewhere, the __raw_* accessors are not portable, please > > use readl()/writel() here, or possibly ioread32_be()/iowrite32_be() for > > the big-endian variant. > > We can't use readl()/writel() here because it's supposed to read from a little endian device, and > goldfish endianness depends on the endianness of the machine. > > For goldfish, readl()/writel() works fine on little-endian machine but not on big-endian machine. > > On m68k, you have: > > #define readl(addr) in_le32(addr) > #define writel(val,addr) out_le32((addr),(val)) > > and with goldfish it's wrong as the device is not little-endian, it is big-endian like the machine. > > same comment with ioread32_be()/iowrite32_be(): it will work on big-endian machine not on little-endian. > > We need an accessor that doesn't byteswap the value, that accesses it natively, and in all other > parts of the kernel __raw_writel() and __raw_readl() are used. Hence Arnd's suggestion to define custom accessors in the Goldfish RTC driver, that map to {read,write}l() on little-endian, and to io{read,write}32_be() on big-endian. BTW, I'd go for io{read,write}32() on little endian instead, for symmetry. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Le 14/01/2022 à 12:12, Geert Uytterhoeven a écrit : > Hi Laurent, > > On Fri, Jan 14, 2022 at 12:03 PM Laurent Vivier <laurent@vivier.eu> wrote: >> Le 14/01/2022 à 11:46, Arnd Bergmann a écrit : >>> On Thu, Jan 13, 2022 at 9:19 PM Laurent Vivier <laurent@vivier.eu> wrote: >>>> +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) >>>> +{ >>>> + struct goldfish_timer *timerdrv = ced_to_gf(evt); >>>> + void __iomem *base = timerdrv->base; >>>> + >>>> + __raw_writel(0, base + TIMER_ALARM_HIGH); >>>> + __raw_writel(0, base + TIMER_ALARM_LOW); >>>> + __raw_writel(1, base + TIMER_IRQ_ENABLED); >>> >>> As mentioned elsewhere, the __raw_* accessors are not portable, please >>> use readl()/writel() here, or possibly ioread32_be()/iowrite32_be() for >>> the big-endian variant. >> >> We can't use readl()/writel() here because it's supposed to read from a little endian device, and >> goldfish endianness depends on the endianness of the machine. >> >> For goldfish, readl()/writel() works fine on little-endian machine but not on big-endian machine. >> >> On m68k, you have: >> >> #define readl(addr) in_le32(addr) >> #define writel(val,addr) out_le32((addr),(val)) >> >> and with goldfish it's wrong as the device is not little-endian, it is big-endian like the machine. >> >> same comment with ioread32_be()/iowrite32_be(): it will work on big-endian machine not on little-endian. >> >> We need an accessor that doesn't byteswap the value, that accesses it natively, and in all other >> parts of the kernel __raw_writel() and __raw_readl() are used. > > Hence Arnd's suggestion to define custom accessors in the Goldfish > RTC driver, that map to {read,write}l() on little-endian, and to > io{read,write}32_be() on big-endian. > > BTW, I'd go for io{read,write}32() on little endian instead, for > symmetry. You mean something like that: #ifdef CONFIG_CPU_BIG_ENDIAN #define raw_ioread32 ioread32be #define raw_iowrite32 iowrite32be #else #define raw_ioread32 ioread32 #define raw_iowrite32 iowrite32 #endif and then use raw_ioread32()/raw_iowrite32() rather than readl()/writel()? Thanks, Laurent
Hi Laurent, On Fri, Jan 14, 2022 at 12:31 PM Laurent Vivier <laurent@vivier.eu> wrote: > Le 14/01/2022 à 12:12, Geert Uytterhoeven a écrit : > > On Fri, Jan 14, 2022 at 12:03 PM Laurent Vivier <laurent@vivier.eu> wrote: > >> Le 14/01/2022 à 11:46, Arnd Bergmann a écrit : > >>> On Thu, Jan 13, 2022 at 9:19 PM Laurent Vivier <laurent@vivier.eu> wrote: > >>>> +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) > >>>> +{ > >>>> + struct goldfish_timer *timerdrv = ced_to_gf(evt); > >>>> + void __iomem *base = timerdrv->base; > >>>> + > >>>> + __raw_writel(0, base + TIMER_ALARM_HIGH); > >>>> + __raw_writel(0, base + TIMER_ALARM_LOW); > >>>> + __raw_writel(1, base + TIMER_IRQ_ENABLED); > >>> > >>> As mentioned elsewhere, the __raw_* accessors are not portable, please > >>> use readl()/writel() here, or possibly ioread32_be()/iowrite32_be() for > >>> the big-endian variant. > >> > >> We can't use readl()/writel() here because it's supposed to read from a little endian device, and > >> goldfish endianness depends on the endianness of the machine. > >> > >> For goldfish, readl()/writel() works fine on little-endian machine but not on big-endian machine. > >> > >> On m68k, you have: > >> > >> #define readl(addr) in_le32(addr) > >> #define writel(val,addr) out_le32((addr),(val)) > >> > >> and with goldfish it's wrong as the device is not little-endian, it is big-endian like the machine. > >> > >> same comment with ioread32_be()/iowrite32_be(): it will work on big-endian machine not on little-endian. > >> > >> We need an accessor that doesn't byteswap the value, that accesses it natively, and in all other > >> parts of the kernel __raw_writel() and __raw_readl() are used. > > > > Hence Arnd's suggestion to define custom accessors in the Goldfish > > RTC driver, that map to {read,write}l() on little-endian, and to > > io{read,write}32_be() on big-endian. > > > > BTW, I'd go for io{read,write}32() on little endian instead, for > > symmetry. > > You mean something like that: > > #ifdef CONFIG_CPU_BIG_ENDIAN > #define raw_ioread32 ioread32be > #define raw_iowrite32 iowrite32be > #else > #define raw_ioread32 ioread32 > #define raw_iowrite32 iowrite32 > #endif > > and then use raw_ioread32()/raw_iowrite32() rather than readl()/writel()? Exactly. You may want to use names that have less chance of conflicting in the future, e.g. goldfish_{read,write}(). Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f65e31bab9ae..6ca9bb78407d 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -711,4 +711,11 @@ config MICROCHIP_PIT64B modes and high resolution. It is used as a clocksource and a clockevent. +config GOLDFISH_TIMER + bool "Clocksource using goldfish-rtc" + select RTC_CLASS + select RTC_DRV_GOLDFISH + help + Support for the timer/counter of goldfish-rtc + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index c17ee32a7151..e624a1a27027 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -88,3 +88,4 @@ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o obj-$(CONFIG_HYPERV_TIMER) += hyperv_timer.o obj-$(CONFIG_MICROCHIP_PIT64B) += timer-microchip-pit64b.o +obj-$(CONFIG_GOLDFISH_TIMER) += timer-goldfish.o diff --git a/drivers/clocksource/timer-goldfish.c b/drivers/clocksource/timer-goldfish.c new file mode 100644 index 000000000000..b1553c3c9456 --- /dev/null +++ b/drivers/clocksource/timer-goldfish.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/clocksource.h> +#include <linux/clockchips.h> +#include <linux/module.h> +#include <clocksource/timer-goldfish.h> + +#define TIMER_TIME_LOW 0x00 /* get low bits of current time */ + /* and update TIMER_TIME_HIGH */ +#define TIMER_TIME_HIGH 0x04 /* get high bits of time at last */ + /* TIMER_TIME_LOW read */ +#define TIMER_ALARM_LOW 0x08 /* set low bits of alarm and */ + /* activate it */ +#define TIMER_ALARM_HIGH 0x0c /* set high bits of next alarm */ +#define TIMER_IRQ_ENABLED 0x10 +#define TIMER_CLEAR_ALARM 0x14 +#define TIMER_ALARM_STATUS 0x18 +#define TIMER_CLEAR_INTERRUPT 0x1c + +struct goldfish_timer { + struct clock_event_device ced; + struct resource res; + void __iomem *base; + int irq; +}; + +static struct goldfish_timer *ced_to_gf(struct clock_event_device *ced) +{ + return container_of(ced, struct goldfish_timer, ced); +} + +static int goldfish_timer_set_oneshot(struct clock_event_device *evt) +{ + struct goldfish_timer *timerdrv = ced_to_gf(evt); + void __iomem *base = timerdrv->base; + + __raw_writel(0, base + TIMER_ALARM_HIGH); + __raw_writel(0, base + TIMER_ALARM_LOW); + __raw_writel(1, base + TIMER_IRQ_ENABLED); + + return 0; +} + +static int goldfish_timer_shutdown(struct clock_event_device *evt) +{ + struct goldfish_timer *timerdrv = ced_to_gf(evt); + void __iomem *base = timerdrv->base; + + __raw_writel(0, base + TIMER_IRQ_ENABLED); + + return 0; +} + +static int goldfish_timer_next_event(unsigned long delta, + struct clock_event_device *evt) +{ + struct goldfish_timer *timerdrv = ced_to_gf(evt); + void __iomem *base = timerdrv->base; + u64 now; + + __raw_writel(1, base + TIMER_CLEAR_INTERRUPT); + + /* + * time_low: get low bits of current time and update time_high + * time_high: get high bits of time at last time_low read + */ + now = __raw_readl(base + TIMER_TIME_LOW); + now += (u64)__raw_readl(base + TIMER_TIME_HIGH) << 32; + + now += delta; + + __raw_writel(upper_32_bits(now), base + TIMER_ALARM_HIGH); + __raw_writel(lower_32_bits(now), base + TIMER_ALARM_LOW); + + return 0; +} + +static irqreturn_t golfish_timer_tick(int irq, void *dev_id) +{ + struct clock_event_device *evt = dev_id; + + evt->event_handler(evt); + + return IRQ_HANDLED; +} + +void __init goldfish_timer_init(int irq, void __iomem *base) +{ + struct goldfish_timer *timerdrv; + int ret; + + timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); + if (!timerdrv) + return; + + timerdrv->base = base; + timerdrv->irq = irq; + + timerdrv->ced = (struct clock_event_device){ + .name = "goldfish_timer", + .features = CLOCK_EVT_FEAT_ONESHOT, + .set_state_shutdown = goldfish_timer_shutdown, + .set_state_oneshot = goldfish_timer_set_oneshot, + .set_next_event = goldfish_timer_next_event, + .shift = 32, + }; + timerdrv->res = (struct resource){ + .name = "goldfish_timer", + .start = (unsigned long)base, + .end = (unsigned long)base + 0xfff, + }; + + if (request_resource(&iomem_resource, &timerdrv->res)) { + pr_err("Cannot allocate goldfish-timer resource\n"); + return; + } + + ret = request_irq(timerdrv->irq, golfish_timer_tick, IRQF_TIMER, + "goldfish_timer", &timerdrv->ced); + if (ret) { + pr_err("Couldn't register goldfish-timer interrupt\n"); + return; + } + + clockevents_config_and_register(&timerdrv->ced, NSEC_PER_SEC, + 1, 0xffffffff); +} +EXPORT_SYMBOL_GPL(goldfish_timer_init); diff --git a/include/clocksource/timer-goldfish.h b/include/clocksource/timer-goldfish.h new file mode 100644 index 000000000000..12bcd08f90af --- /dev/null +++ b/include/clocksource/timer-goldfish.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * goldfish-timer clocksource + */ + +#ifndef _CLOCKSOURCE_GOLDFISH_TIMER_H +#define _CLOCKSOURCE_GOLDFISH_TIMER_H + +extern void goldfish_timer_init(int irq, void __iomem *base); + +#endif /* _CLOCKSOURCE_GOLDFISH_TIMER_H */ +
Add a clocksource based on the goldfish-rtc device. Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- drivers/clocksource/Kconfig | 7 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-goldfish.c | 130 +++++++++++++++++++++++++++ include/clocksource/timer-goldfish.h | 12 +++ 4 files changed, 150 insertions(+) create mode 100644 drivers/clocksource/timer-goldfish.c create mode 100644 include/clocksource/timer-goldfish.h