Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LoongArch: Add cpufreq driver and ls2k500sfb driver support #143

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/loongarch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ config ARCH_SUSPEND_POSSIBLE
config ARCH_HIBERNATION_POSSIBLE
def_bool y

source "drivers/cpufreq/Kconfig"
source "kernel/power/Kconfig"
source "drivers/acpi/Kconfig"

Expand Down
5 changes: 5 additions & 0 deletions arch/loongarch/configs/deepin_loongarch_desktop_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ CONFIG_ACPI_TAD=m
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_PCI_SLOT=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_LOONGSON3_ACPI_CPUFREQ=y
CONFIG_ACPI_HOTPLUG_MEMORY=y
CONFIG_ACPI_HED=y
CONFIG_ACPI_CUSTOM_METHOD=y
Expand Down Expand Up @@ -3623,6 +3627,7 @@ CONFIG_FB_ASILIANT=y
CONFIG_FB_IMSTT=y
CONFIG_FB_UVESA=m
CONFIG_FB_EFI=y
CONFIG_FB_LS2K500=m
CONFIG_FB_OPENCORES=m
CONFIG_FB_S1D13XXX=m
CONFIG_FB_RIVA=m
Expand Down
7 changes: 6 additions & 1 deletion arch/loongarch/configs/loongson3_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ CONFIG_DMI=y
CONFIG_EFI=y
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
CONFIG_NR_CPUS=64
CONFIG_NR_CPUS=256
CONFIG_NUMA=y
CONFIG_CPU_HAS_FPU=y
CONFIG_CPU_HAS_LSX=y
Expand All @@ -61,6 +61,10 @@ CONFIG_ACPI_DOCK=y
CONFIG_ACPI_IPMI=m
CONFIG_ACPI_HOTPLUG_CPU=y
CONFIG_ACPI_PCI_SLOT=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_LOONGSON3_ACPI_CPUFREQ=y
CONFIG_ACPI_HOTPLUG_MEMORY=y
CONFIG_EFI_ZBOOT=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
Expand Down Expand Up @@ -670,6 +674,7 @@ CONFIG_DRM_LOONGSON=y
CONFIG_FB=y
CONFIG_FB_EFI=y
CONFIG_FB_RADEON=y
CONFIG_FB_LS2K500=m
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=m
# CONFIG_VGA_CONSOLE is not set
Expand Down
13 changes: 12 additions & 1 deletion arch/loongarch/include/asm/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ static inline void disable_lasx(void);
static inline void save_lasx(struct task_struct *t);
static inline void restore_lasx(struct task_struct *t);

#ifdef CONFIG_LOONGSON3_ACPI_CPUFREQ
DECLARE_PER_CPU(unsigned long, lsx_count);
DECLARE_PER_CPU(unsigned long, lasx_count);
#endif
/*
* Mask the FCSR Cause bits according to the Enable bits, observing
* that Unimplemented is always enabled.
Expand Down Expand Up @@ -210,6 +214,9 @@ static inline void enable_lsx(void)
{
if (cpu_has_lsx)
csr_xchg32(CSR_EUEN_LSXEN, CSR_EUEN_LSXEN, LOONGARCH_CSR_EUEN);
#ifdef CONFIG_LOONGSON3_ACPI_CPUFREQ
opsiff marked this conversation as resolved.
Show resolved Hide resolved
per_cpu(lsx_count, raw_smp_processor_id())++;
#endif
}

static inline void disable_lsx(void)
Expand Down Expand Up @@ -256,8 +263,12 @@ static inline void restore_lsx_upper(struct task_struct *t) {}
static inline void enable_lasx(void)
{

if (cpu_has_lasx)
if (cpu_has_lasx) {
csr_xchg32(CSR_EUEN_LASXEN, CSR_EUEN_LASXEN, LOONGARCH_CSR_EUEN);
#ifdef CONFIG_LOONGSON3_ACPI_CPUFREQ
per_cpu(lasx_count, raw_smp_processor_id())++;
#endif
}
}

static inline void disable_lasx(void)
Expand Down
4 changes: 4 additions & 0 deletions drivers/char/ipmi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ ifdef CONFIG_PARISC
ipmi_si-y += ipmi_si_parisc.o
endif

ifdef CONFIG_LOONGARCH
ipmi_si-y += ipmi_si_ls2k500.o
endif

obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
obj-$(CONFIG_IPMI_SI) += ipmi_si.o
Expand Down
92 changes: 92 additions & 0 deletions drivers/char/ipmi/btlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __BTLOCK_H__
#define __BTLOCK_H__

#include <linux/delay.h>
#include <asm/timex.h>

union btlock {
char b[2];
unsigned int u;
};

/*
*wait delay us if lock failed.
*lock fail if another one get lock or both try get lock.
*c must compile b with byte access.
*/
static inline int btlock_lock(volatile union btlock *p, int n, unsigned char delay)
{
union btlock t, t1;
unsigned long flags;
unsigned long c0 = get_cycles(), c1;

if (n > 1)
return -1;
delay |= 0x80;
t1.u = 0;
t1.b[n] = delay;

while (1) {
local_irq_save(flags);
p->b[n] = delay;
t.u = p->u;
if (t.u == t1.u) {
wmb(); /* flush write out immediately */
local_irq_restore(flags);
return 0;
}
p->b[n] = 0;
t.u = p->u;
wmb(); /* flush write out immediately */
local_irq_restore(flags);
c1 = get_cycles();
if (c1 - c0 > *mscycles * 1000)
return -1;
ndelay(((t.b[1 - n] & 0x7f) + (c1 & 1)) * 100);
}
return 0;
}

static inline int btlock_trylock(volatile union btlock *p, int n, unsigned char delay)
{
union btlock t, t1;
unsigned long flags;

if (n > 1)
return -1;
delay |= 0x80;
t1.u = 0;
t1.b[n] = delay;

local_irq_save(flags);
p->b[n] = delay;
t.u = p->u;
if (t.u == t1.u) {
wmb(); /* flush write out immediately */
local_irq_restore(flags);
return 0;
}
p->b[n] = 0;
t.u = p->u;
wmb(); /* flush write out immediately */
local_irq_restore(flags);
ndelay(((t.b[1 - n] & 0x7f) + (get_cycles() & 1)) * 100);
return -1;
}

static inline int btlock_unlock(volatile union btlock *p, int n)
{
p->b[n] = 0;
wmb(); /* flush write out immediately */
return p->u;
}

static inline int btlock_islocked(volatile union btlock *p, int n)
{
union btlock t;

t.u = p->u;
return t.b[n] && !t.b[1 - n];
}
#endif
11 changes: 11 additions & 0 deletions drivers/char/ipmi/ipmi_si.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ struct si_sm_io {
unsigned int regshift;
enum ipmi_addr_space addr_space;
unsigned long addr_data;
#ifdef CONFIG_LOONGARCH
void *addr_source_data;
#endif
enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */
union ipmi_smi_info_union addr_info;

Expand Down Expand Up @@ -101,6 +104,14 @@ static inline void ipmi_si_parisc_init(void) { }
static inline void ipmi_si_parisc_shutdown(void) { }
#endif

#ifdef CONFIG_LOONGARCH
int ipmi_si_ls2k500_init(void);
void ipmi_si_ls2k500_shutdown(void);
#else
static inline void ipmi_si_ls2k500_init(void) { }
static inline void ipmi_si_ls2k500_shutdown(void) { }
#endif

int ipmi_si_port_setup(struct si_sm_io *io);
int ipmi_si_mem_setup(struct si_sm_io *io);

Expand Down
4 changes: 4 additions & 0 deletions drivers/char/ipmi/ipmi_si_intf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2104,6 +2104,8 @@ static int __init init_ipmi_si(void)

ipmi_si_platform_init();

ipmi_si_ls2k500_init();

ipmi_si_pci_init();

ipmi_si_parisc_init();
Expand Down Expand Up @@ -2289,6 +2291,8 @@ static void cleanup_ipmi_si(void)

ipmi_si_parisc_shutdown();

ipmi_si_ls2k500_shutdown();

ipmi_si_platform_shutdown();

mutex_lock(&smi_infos_lock);
Expand Down
Loading