Commit 86884051 authored by Dai Xin's avatar Dai Xin Committed by guzitao
Browse files

sw64: deliver a warm/cold reset to Root Complex with plugin JMicron 585 card

Sunway inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I5GFPA



--------------------------------

On SW64 platform, JMicron 585 SATA card directly connected to Root
Complex may raise DMA failure when reboot, so we force a warm/cold reset
to Root Complex to fix can not access JMicron 585 SATA card.

Signed-off-by: default avatarDai Xin <daixin@wxiat.com>
Reviewed-by: default avatarHe Sheng <hesheng@wxiat.com>
Signed-off-by: default avatarGu Zitao <guzitao@wxiat.com>
parent 9a61ddc4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -23,5 +23,6 @@ extern void (*pm_restart)(void);
extern void (*pm_halt)(void);
extern int i2c_set_adapter(void);
extern void cpld_write(uint8_t slave_addr, uint8_t reg, uint8_t data);
extern void fix_jm585_reset(void);

#endif /* _ASM_SW64_PLATFORM_H */
+21 −0
Original line number Diff line number Diff line
@@ -15,7 +15,27 @@

#include <acpi/reboot.h>
#include <asm/idle.h>
#include <asm/sw64io.h>

void fix_jm585_reset(void)
{
	struct pci_dev *pdev;
	struct pci_controller *hose;
	int val;

	pdev = pci_get_device(PCI_VENDOR_ID_JMICRON,
				0x0585, NULL);
	if (pdev) {
		hose = (struct pci_controller *)pdev->sysdata;
		val = read_rc_conf(hose->node, hose->index,
				RC_PORT_LINK_CTL);
		write_rc_conf(hose->node, hose->index,
				RC_PORT_LINK_CTL, val | 0x8);
		write_rc_conf(hose->node, hose->index,
		RC_PORT_LINK_CTL, val);
	}

}
static void default_halt(void)
{
	local_irq_disable();
@@ -42,6 +62,7 @@ static void default_restart(void)
	/* No point in taking interrupts anymore. */
	local_irq_disable();

	fix_jm585_reset();
#ifdef CONFIG_EFI
	if (efi_capsule_pending(NULL))
		efi_reboot(REBOOT_WARM, NULL);
+1 −15
Original line number Diff line number Diff line
@@ -42,22 +42,8 @@ void sw64_poweroff(void)

void sw64_restart(void)
{
	struct pci_dev *pdev;
	struct pci_controller *hose;
	int val;

	if (is_in_host()) {
		pdev = pci_get_device(PCI_VENDOR_ID_JMICRON,
					0x0585, NULL);
		if (pdev) {
			hose = (struct pci_controller *)pdev->sysdata;
			val = read_rc_conf(hose->node, hose->index,
					RC_PORT_LINK_CTL);
			write_rc_conf(hose->node, hose->index,
					RC_PORT_LINK_CTL, val | 0x8);
			write_rc_conf(hose->node, hose->index,
					RC_PORT_LINK_CTL, val);
		}
		fix_jm585_reset();
		cpld_write(0x64, 0x00, 0xc3);
	} else
		vt_mode_kill_arch(LINUX_REBOOT_CMD_RESTART);