* [PATCH 0/6] Use MFD framework for SGI IOC3 drivers
@ 2019-04-08 14:20 Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 1/6] MIPS: SGI-IP27: remove ioc3 ethernet init Thomas Bogendoerfer
` (4 more replies)
0 siblings, 5 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 14:20 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
SGI IOC3 ASIC includes support for ethernet, PS2 keyboard/mouse,
NIC (number in a can), GPIO and a byte bus. By attaching a
SuperIO chip to it, it also supports serial lines and a parallel
port. The chip is used on a variety of SGI systems with different
configurations. This patchset moves code out of the network driver,
which doesn't belong there, into its new place a MFD driver and
specific platform drivers for the different subfunctions.
Thomas Bogendoerfer (6):
MIPS: SGI-IP27: remove ioc3 ethernet init
MIPS: SGI-IP27: remove setup of RTC platform device
mfd: ioc3: Add driver for SGI IOC3 chip
MIPS: SGI-IP27: fix readb/writeb addressing
tty: serial: Add 8250-core base IOC3 driver
Input: add IOC3 serio driver
arch/mips/include/asm/mach-ip27/mangle-port.h | 2 +-
arch/mips/include/asm/sn/ioc3.h | 350 ++---
arch/mips/sgi-ip27/ip27-console.c | 5 +-
arch/mips/sgi-ip27/ip27-init.c | 13 -
arch/mips/sgi-ip27/ip27-timer.c | 20 -
drivers/input/serio/Kconfig | 12 +
drivers/input/serio/Makefile | 1 +
drivers/input/serio/ioc3kbd.c | 183 +++
drivers/mfd/Kconfig | 13 +
drivers/mfd/Makefile | 1 +
drivers/mfd/ioc3.c | 802 +++++++++++
drivers/net/ethernet/sgi/Kconfig | 4 +-
drivers/net/ethernet/sgi/ioc3-eth.c | 1869 +++++++++----------------
drivers/rtc/rtc-m48t35.c | 11 +
drivers/tty/serial/8250/8250_ioc3.c | 98 ++
drivers/tty/serial/8250/Kconfig | 11 +
drivers/tty/serial/8250/Makefile | 1 +
include/linux/platform_data/ioc3eth.h | 15 +
18 files changed, 1974 insertions(+), 1437 deletions(-)
create mode 100644 drivers/input/serio/ioc3kbd.c
create mode 100644 drivers/mfd/ioc3.c
create mode 100644 drivers/tty/serial/8250/8250_ioc3.c
create mode 100644 include/linux/platform_data/ioc3eth.h
--
2.13.7
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 1/6] MIPS: SGI-IP27: remove ioc3 ethernet init
2019-04-08 14:20 [PATCH 0/6] Use MFD framework for SGI IOC3 drivers Thomas Bogendoerfer
@ 2019-04-08 14:20 ` Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device Thomas Bogendoerfer
` (3 subsequent siblings)
4 siblings, 0 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 14:20 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
Removed not needed disabling of ethernet interrupts in IP27 platform code.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
arch/mips/sgi-ip27/ip27-init.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 066b33f50bcc..59d5375c9021 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -130,17 +130,6 @@ cnodeid_t get_compact_nodeid(void)
return NASID_TO_COMPACT_NODEID(get_nasid());
}
-static inline void ioc3_eth_init(void)
-{
- struct ioc3 *ioc3;
- nasid_t nid;
-
- nid = get_nasid();
- ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
-
- ioc3->eier = 0;
-}
-
extern void ip27_reboot_setup(void);
void __init plat_mem_setup(void)
@@ -182,8 +171,6 @@ void __init plat_mem_setup(void)
panic("Kernel compiled for N mode.");
#endif
- ioc3_eth_init();
-
ioport_resource.start = 0;
ioport_resource.end = ~0UL;
set_io_port_base(IO_BASE);
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device
2019-04-08 14:20 [PATCH 0/6] Use MFD framework for SGI IOC3 drivers Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 1/6] MIPS: SGI-IP27: remove ioc3 ethernet init Thomas Bogendoerfer
@ 2019-04-08 14:20 ` Thomas Bogendoerfer
2019-04-08 17:05 ` David Miller
2019-04-08 14:20 ` [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing Thomas Bogendoerfer
` (2 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 14:20 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
RTC platform device will be setup by new IOC3 MFD driver, therefore
remove it from IP27 platform code.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
arch/mips/sgi-ip27/ip27-timer.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 9b4b9ac621a3..5631e93ea350 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -188,23 +188,3 @@ void hub_rtc_init(cnodeid_t cnode)
LOCAL_HUB_S(PI_RT_PEND_B, 0);
}
}
-
-static int __init sgi_ip27_rtc_devinit(void)
-{
- struct resource res;
-
- memset(&res, 0, sizeof(res));
- res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base +
- IOC3_BYTEBUS_DEV0);
- res.end = res.start + 32767;
- res.flags = IORESOURCE_MEM;
-
- return IS_ERR(platform_device_register_simple("rtc-m48t35", -1,
- &res, 1));
-}
-
-/*
- * kludge make this a device_initcall after ioc3 resource conflicts
- * are resolved
- */
-late_initcall(sgi_ip27_rtc_devinit);
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing
2019-04-08 14:20 [PATCH 0/6] Use MFD framework for SGI IOC3 drivers Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 1/6] MIPS: SGI-IP27: remove ioc3 ethernet init Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device Thomas Bogendoerfer
@ 2019-04-08 14:20 ` Thomas Bogendoerfer
2019-04-08 14:58 ` Alexandre Belloni
2019-04-08 14:20 ` [PATCH 5/6] tty: serial: Add 8250-core base IOC3 driver Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 6/6] Input: add IOC3 serio driver Thomas Bogendoerfer
4 siblings, 1 reply; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 14:20 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
Our chosen byte swapping, which is what firmware already uses, is to
do readl/writel by normal lw/sw intructions (data invariance). This
also means we need to mangle addresses for u8 and u16 accesses. The
mangling for 16bit has been done aready, but 8bit one was missing.
Correcting this causes different addresses for accesses to the
SuperIO and local bus of the IOC3 chip. This is fixed by changing
byte order in ioc3 and m48rtc_rtc structs.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
arch/mips/include/asm/mach-ip27/mangle-port.h | 2 +-
arch/mips/include/asm/sn/ioc3.h | 198 +++++++++++++-------------
arch/mips/sgi-ip27/ip27-console.c | 5 +-
drivers/rtc/rtc-m48t35.c | 11 ++
4 files changed, 112 insertions(+), 104 deletions(-)
diff --git a/arch/mips/include/asm/mach-ip27/mangle-port.h b/arch/mips/include/asm/mach-ip27/mangle-port.h
index f6e4912ea062..7771ae0f3971 100644
--- a/arch/mips/include/asm/mach-ip27/mangle-port.h
+++ b/arch/mips/include/asm/mach-ip27/mangle-port.h
@@ -8,7 +8,7 @@
#ifndef __ASM_MACH_IP27_MANGLE_PORT_H
#define __ASM_MACH_IP27_MANGLE_PORT_H
-#define __swizzle_addr_b(port) (port)
+#define __swizzle_addr_b(port) ((port) ^ 3)
#define __swizzle_addr_w(port) ((port) ^ 2)
#define __swizzle_addr_l(port) (port)
#define __swizzle_addr_q(port) (port)
diff --git a/arch/mips/include/asm/sn/ioc3.h b/arch/mips/include/asm/sn/ioc3.h
index 028d9d466ddf..f7a0c9a8a31a 100644
--- a/arch/mips/include/asm/sn/ioc3.h
+++ b/arch/mips/include/asm/sn/ioc3.h
@@ -9,35 +9,35 @@
/* serial port register map */
struct ioc3_serialregs {
- uint32_t sscr;
- uint32_t stpir;
- uint32_t stcir;
- uint32_t srpir;
- uint32_t srcir;
- uint32_t srtr;
- uint32_t shadow;
+ u32 sscr;
+ u32 stpir;
+ u32 stcir;
+ u32 srpir;
+ u32 srcir;
+ u32 srtr;
+ u32 shadow;
};
/* SUPERIO uart register map */
struct ioc3_uartregs {
+ u8 iu_lcr;
union {
- char rbr; /* read only, DLAB == 0 */
- char thr; /* write only, DLAB == 0 */
- char dll; /* DLAB == 1 */
- } u1;
+ u8 iir; /* read only */
+ u8 fcr; /* write only */
+ };
union {
- char ier; /* DLAB == 0 */
- char dlm; /* DLAB == 1 */
- } u2;
+ u8 ier; /* DLAB == 0 */
+ u8 dlm; /* DLAB == 1 */
+ };
union {
- char iir; /* read only */
- char fcr; /* write only */
- } u3;
- char iu_lcr;
- char iu_mcr;
- char iu_lsr;
- char iu_msr;
- char iu_scr;
+ u8 rbr; /* read only, DLAB == 0 */
+ u8 thr; /* write only, DLAB == 0 */
+ u8 dll; /* DLAB == 1 */
+ } u1;
+ u8 iu_scr;
+ u8 iu_msr;
+ u8 iu_lsr;
+ u8 iu_mcr;
};
#define iu_rbr u1.rbr
@@ -49,122 +49,122 @@ struct ioc3_uartregs {
#define iu_fcr u3.fcr
struct ioc3_sioregs {
- char fill[0x141]; /* starts at 0x141 */
+ u8 fill[0x141]; /* starts at 0x141 */
- char uartc;
- char kbdcg;
+ u8 kbdcg;
+ u8 uartc;
- char fill0[0x150 - 0x142 - 1];
+ u8 fill0[0x151 - 0x142 - 1];
- char pp_data;
- char pp_dsr;
- char pp_dcr;
+ u8 pp_dcr;
+ u8 pp_dsr;
+ u8 pp_data;
- char fill1[0x158 - 0x152 - 1];
+ u8 fill1[0x159 - 0x153 - 1];
- char pp_fifa;
- char pp_cfgb;
- char pp_ecr;
+ u8 pp_ecr;
+ u8 pp_cfgb;
+ u8 pp_fifa;
- char fill2[0x168 - 0x15a - 1];
+ u8 fill2[0x16a - 0x15b - 1];
- char rtcad;
- char rtcdat;
+ u8 rtcdat;
+ u8 rtcad;
- char fill3[0x170 - 0x169 - 1];
+ u8 fill3[0x170 - 0x16b - 1];
struct ioc3_uartregs uartb; /* 0x20170 */
struct ioc3_uartregs uarta; /* 0x20178 */
};
struct ioc3_ethregs {
- uint32_t emcr; /* 0x000f0 */
- uint32_t eisr; /* 0x000f4 */
- uint32_t eier; /* 0x000f8 */
- uint32_t ercsr; /* 0x000fc */
- uint32_t erbr_h; /* 0x00100 */
- uint32_t erbr_l; /* 0x00104 */
- uint32_t erbar; /* 0x00108 */
- uint32_t ercir; /* 0x0010c */
- uint32_t erpir; /* 0x00110 */
- uint32_t ertr; /* 0x00114 */
- uint32_t etcsr; /* 0x00118 */
- uint32_t ersr; /* 0x0011c */
- uint32_t etcdc; /* 0x00120 */
- uint32_t ebir; /* 0x00124 */
- uint32_t etbr_h; /* 0x00128 */
- uint32_t etbr_l; /* 0x0012c */
- uint32_t etcir; /* 0x00130 */
- uint32_t etpir; /* 0x00134 */
- uint32_t emar_h; /* 0x00138 */
- uint32_t emar_l; /* 0x0013c */
- uint32_t ehar_h; /* 0x00140 */
- uint32_t ehar_l; /* 0x00144 */
- uint32_t micr; /* 0x00148 */
- uint32_t midr_r; /* 0x0014c */
- uint32_t midr_w; /* 0x00150 */
+ u32 emcr; /* 0x000f0 */
+ u32 eisr; /* 0x000f4 */
+ u32 eier; /* 0x000f8 */
+ u32 ercsr; /* 0x000fc */
+ u32 erbr_h; /* 0x00100 */
+ u32 erbr_l; /* 0x00104 */
+ u32 erbar; /* 0x00108 */
+ u32 ercir; /* 0x0010c */
+ u32 erpir; /* 0x00110 */
+ u32 ertr; /* 0x00114 */
+ u32 etcsr; /* 0x00118 */
+ u32 ersr; /* 0x0011c */
+ u32 etcdc; /* 0x00120 */
+ u32 ebir; /* 0x00124 */
+ u32 etbr_h; /* 0x00128 */
+ u32 etbr_l; /* 0x0012c */
+ u32 etcir; /* 0x00130 */
+ u32 etpir; /* 0x00134 */
+ u32 emar_h; /* 0x00138 */
+ u32 emar_l; /* 0x0013c */
+ u32 ehar_h; /* 0x00140 */
+ u32 ehar_l; /* 0x00144 */
+ u32 micr; /* 0x00148 */
+ u32 midr_r; /* 0x0014c */
+ u32 midr_w; /* 0x00150 */
};
struct ioc3_serioregs {
- uint32_t km_csr; /* 0x0009c */
- uint32_t k_rd; /* 0x000a0 */
- uint32_t m_rd; /* 0x000a4 */
- uint32_t k_wd; /* 0x000a8 */
- uint32_t m_wd; /* 0x000ac */
+ u32 km_csr; /* 0x0009c */
+ u32 k_rd; /* 0x000a0 */
+ u32 m_rd; /* 0x000a4 */
+ u32 k_wd; /* 0x000a8 */
+ u32 m_wd; /* 0x000ac */
};
/* Register layout of IOC3 in configuration space. */
struct ioc3 {
/* PCI Config Space registers */
- uint32_t pci_id; /* 0x00000 */
- uint32_t pci_scr; /* 0x00004 */
- uint32_t pci_rev; /* 0x00008 */
- uint32_t pci_lat; /* 0x0000c */
- uint32_t pci_addr; /* 0x00010 */
- uint32_t pci_err_addr_l; /* 0x00014 */
- uint32_t pci_err_addr_h; /* 0x00018 */
-
- uint32_t sio_ir; /* 0x0001c */
- uint32_t sio_ies; /* 0x00020 */
- uint32_t sio_iec; /* 0x00024 */
- uint32_t sio_cr; /* 0x00028 */
- uint32_t int_out; /* 0x0002c */
- uint32_t mcr; /* 0x00030 */
+ u32 pci_id; /* 0x00000 */
+ u32 pci_scr; /* 0x00004 */
+ u32 pci_rev; /* 0x00008 */
+ u32 pci_lat; /* 0x0000c */
+ u32 pci_addr; /* 0x00010 */
+ u32 pci_err_addr_l; /* 0x00014 */
+ u32 pci_err_addr_h; /* 0x00018 */
+
+ u32 sio_ir; /* 0x0001c */
+ u32 sio_ies; /* 0x00020 */
+ u32 sio_iec; /* 0x00024 */
+ u32 sio_cr; /* 0x00028 */
+ u32 int_out; /* 0x0002c */
+ u32 mcr; /* 0x00030 */
/* General Purpose I/O registers */
- uint32_t gpcr_s; /* 0x00034 */
- uint32_t gpcr_c; /* 0x00038 */
- uint32_t gpdr; /* 0x0003c */
- uint32_t gppr[16]; /* 0x00040 */
+ u32 gpcr_s; /* 0x00034 */
+ u32 gpcr_c; /* 0x00038 */
+ u32 gpdr; /* 0x0003c */
+ u32 gppr[16]; /* 0x00040 */
/* Parallel Port Registers */
- uint32_t ppbr_h_a; /* 0x00080 */
- uint32_t ppbr_l_a; /* 0x00084 */
- uint32_t ppcr_a; /* 0x00088 */
- uint32_t ppcr; /* 0x0008c */
- uint32_t ppbr_h_b; /* 0x00090 */
- uint32_t ppbr_l_b; /* 0x00094 */
- uint32_t ppcr_b; /* 0x00098 */
+ u32 ppbr_h_a; /* 0x00080 */
+ u32 ppbr_l_a; /* 0x00084 */
+ u32 ppcr_a; /* 0x00088 */
+ u32 ppcr; /* 0x0008c */
+ u32 ppbr_h_b; /* 0x00090 */
+ u32 ppbr_l_b; /* 0x00094 */
+ u32 ppcr_b; /* 0x00098 */
/* Keyboard and Mouse Registers */
struct ioc3_serioregs serio;
/* Serial Port Registers */
- uint32_t sbbr_h; /* 0x000b0 */
- uint32_t sbbr_l; /* 0x000b4 */
+ u32 sbbr_h; /* 0x000b0 */
+ u32 sbbr_l; /* 0x000b4 */
struct ioc3_serialregs port_a;
struct ioc3_serialregs port_b;
/* Ethernet Registers */
struct ioc3_ethregs eth;
- uint32_t pad1[(0x20000 - 0x00154) / 4];
+ u32 pad1[(0x20000 - 0x00154) / 4];
/* SuperIO Registers XXX */
struct ioc3_sioregs sregs; /* 0x20000 */
- uint32_t pad2[(0x40000 - 0x20180) / 4];
+ u32 pad2[(0x40000 - 0x20180) / 4];
/* SSRAM Diagnostic Access */
- uint32_t ssram[(0x80000 - 0x40000) / 4];
+ u32 ssram[(0x80000 - 0x40000) / 4];
/* Bytebus device offsets
0x80000 - Access to the generic devices selected with DEV0
@@ -597,8 +597,4 @@ struct ioc3_etxd {
#define MIDR_DATA_MASK 0x0000ffff
-#if defined(CONFIG_SGI_IP27) || defined(CONFIG_SGI_IP30)
-extern int bridge_alloc_irq(struct pci_dev *dev);
-#endif
-
#endif /* MIPS_SN_IOC3_H */
diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
index 6bdb48d41276..5886bee89d06 100644
--- a/arch/mips/sgi-ip27/ip27-console.c
+++ b/arch/mips/sgi-ip27/ip27-console.c
@@ -35,6 +35,7 @@ void prom_putchar(char c)
{
struct ioc3_uartregs *uart = console_uart();
- while ((uart->iu_lsr & 0x20) == 0);
- uart->iu_thr = c;
+ while ((readb(&uart->iu_lsr) & 0x20) == 0)
+ ;
+ writeb(c, &uart->iu_thr);
}
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index 0cf6507de3c7..05f0d91366af 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -24,6 +24,16 @@
struct m48t35_rtc {
u8 pad[0x7ff8]; /* starts at 0x7ff8 */
+#ifdef CONFIG_SGI_IP27
+ u8 hour;
+ u8 min;
+ u8 sec;
+ u8 control;
+ u8 year;
+ u8 month;
+ u8 date;
+ u8 day;
+#else
u8 control;
u8 sec;
u8 min;
@@ -32,6 +42,7 @@ struct m48t35_rtc {
u8 date;
u8 month;
u8 year;
+#endif
};
#define M48T35_RTC_SET 0x80
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/6] tty: serial: Add 8250-core base IOC3 driver
2019-04-08 14:20 [PATCH 0/6] Use MFD framework for SGI IOC3 drivers Thomas Bogendoerfer
` (2 preceding siblings ...)
2019-04-08 14:20 ` [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing Thomas Bogendoerfer
@ 2019-04-08 14:20 ` Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 6/6] Input: add IOC3 serio driver Thomas Bogendoerfer
4 siblings, 0 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 14:20 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
This patch adds 8250 IOC3 platform driver for serial ports connected via
a SuperIO chip to a SGI IOC3 chip.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/tty/serial/8250/8250_ioc3.c | 98 +++++++++++++++++++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 11 +++++
drivers/tty/serial/8250/Makefile | 1 +
3 files changed, 110 insertions(+)
create mode 100644 drivers/tty/serial/8250/8250_ioc3.c
diff --git a/drivers/tty/serial/8250/8250_ioc3.c b/drivers/tty/serial/8250/8250_ioc3.c
new file mode 100644
index 000000000000..4c405f1b9c67
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_ioc3.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SGI IOC3 8250 UART driver
+ *
+ * Copyright (C) 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
+ *
+ * based on code Copyright (C) 2005 Stanislaw Skowronek <skylark@unaligned.org>
+ * Copyright (C) 2014 Joshua Kinard <kumba@gentoo.org>
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "8250.h"
+
+#define IOC3_UARTCLK (22000000 / 3)
+
+struct ioc3_8250_data {
+ int line;
+};
+
+static unsigned int ioc3_serial_in(struct uart_port *p, int offset)
+{
+ return readb(p->membase + (offset ^ 3));
+}
+
+static void ioc3_serial_out(struct uart_port *p, int offset, int value)
+{
+ writeb(value, p->membase + (offset ^ 3));
+}
+
+static int serial8250_ioc3_probe(struct platform_device *pdev)
+{
+ struct ioc3_8250_data *data;
+ struct uart_8250_port up;
+ struct resource *r;
+ void __iomem *membase;
+ int irq, line;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENODEV;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ membase = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r));
+ if (!membase)
+ return -ENOMEM;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ irq = 0; /* no interrupt -> use polling */
+
+ /* Register serial ports with 8250.c */
+ memset(&up, 0, sizeof(struct uart_8250_port));
+ up.port.iotype = UPIO_MEM;
+ up.port.uartclk = IOC3_UARTCLK;
+ up.port.type = PORT_16550A;
+ up.port.irq = irq;
+ up.port.flags = (UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ);
+ up.port.dev = &pdev->dev;
+ up.port.membase = membase;
+ up.port.mapbase = r->start;
+ up.port.serial_in = ioc3_serial_in;
+ up.port.serial_out = ioc3_serial_out;
+ line = serial8250_register_8250_port(&up);
+ if (line < 0)
+ return line;
+
+ platform_set_drvdata(pdev, data);
+ return 0;
+}
+
+static int serial8250_ioc3_remove(struct platform_device *pdev)
+{
+ struct ioc3_8250_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+ return 0;
+}
+
+static struct platform_driver serial8250_ioc3_driver = {
+ .probe = serial8250_ioc3_probe,
+ .remove = serial8250_ioc3_remove,
+ .driver = {
+ .name = "ioc3-serial8250",
+ }
+};
+
+module_platform_driver(serial8250_ioc3_driver);
+
+MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
+MODULE_DESCRIPTION("SGI IOC3 8250 UART driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 15c2c5463835..9d24615aabfb 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -364,6 +364,17 @@ config SERIAL_8250_EM
port hardware found on the Emma Mobile line of processors.
If unsure, say N.
+config SERIAL_8250_IOC3
+ tristate "SGI IOC3 8250 UART support"
+ depends on SGI_MFD_IOC3 && SERIAL_8250
+ select SERIAL_8250_EXTENDED
+ select SERIAL_8250_SHARE_IRQ
+ help
+ Enable this if you have a SGI Origin or Octane machine. This module
+ provides basic serial support by directly driving the UART chip
+ behind the IOC3 device on those systems. Maximum baud speed is
+ 38400bps using this driver.
+
config SERIAL_8250_RT288X
bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
depends on SERIAL_8250
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 18751bc63a84..79f74b4d57e5 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
+obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o
obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 6/6] Input: add IOC3 serio driver
2019-04-08 14:20 [PATCH 0/6] Use MFD framework for SGI IOC3 drivers Thomas Bogendoerfer
` (3 preceding siblings ...)
2019-04-08 14:20 ` [PATCH 5/6] tty: serial: Add 8250-core base IOC3 driver Thomas Bogendoerfer
@ 2019-04-08 14:20 ` Thomas Bogendoerfer
2019-04-08 19:02 ` Dmitry Torokhov
4 siblings, 1 reply; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 14:20 UTC (permalink / raw)
To: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
This patch adds a platform driver for supporting keyboard and mouse
interface of SGI IOC3 chips.
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/input/serio/Kconfig | 12 +++
drivers/input/serio/Makefile | 1 +
drivers/input/serio/ioc3kbd.c | 183 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 196 insertions(+)
create mode 100644 drivers/input/serio/ioc3kbd.c
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index c9c7224d5ae0..ceb89d8b785d 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -164,6 +164,18 @@ config SERIO_MACEPS2
To compile this driver as a module, choose M here: the
module will be called maceps2.
+config SERIO_SGI_IOC3
+ tristate "SGI IOC3 PS/2 controller"
+ depends on SGI_MFD_IOC3
+ help
+ Say Y here if you have an SGI Onyx2, SGI Octane or IOC3 PCI card
+ and you want to attach and use a keyboard, mouse, or both.
+
+ Do not use on an SGI Origin 2000, as the IO6 board in those
+ systems lacks the necessary PS/2 ports. You will need to add
+ an IOC3 PCI card (CADduo) via a PCI Shoehorn XIO card or the
+ PCI Cardcage (shoebox) first.
+
config SERIO_LIBPS2
tristate "PS/2 driver library"
depends on SERIO_I8042 || SERIO_I8042=n
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 67950a5ccb3f..6d97bad7b844 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o
obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
obj-$(CONFIG_SERIO_PS2MULT) += ps2mult.o
obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
+obj-$(CONFIG_SERIO_SGI_IOC3) += ioc3kbd.o
obj-$(CONFIG_SERIO_LIBPS2) += libps2.o
obj-$(CONFIG_SERIO_RAW) += serio_raw.o
obj-$(CONFIG_SERIO_AMS_DELTA) += ams_delta_serio.o
diff --git a/drivers/input/serio/ioc3kbd.c b/drivers/input/serio/ioc3kbd.c
new file mode 100644
index 000000000000..8ff46a9f3d98
--- /dev/null
+++ b/drivers/input/serio/ioc3kbd.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SGI IOC3 PS/2 controller driver for linux
+ *
+ * Copyright (C) 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
+ *
+ * Based on code Copyright (C) 2005 Stanislaw Skowronek <skylark@unaligned.org>
+ * Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serio.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/sn/ioc3.h>
+
+struct ioc3kbd_data {
+ struct ioc3_serioregs __iomem *regs;
+ struct serio *kbd, *aux;
+};
+
+static int ioc3kbd_write(struct serio *dev, u8 val)
+{
+ struct ioc3kbd_data *d = (struct ioc3kbd_data *)(dev->port_data);
+ unsigned long timeout = 0;
+ u32 mask;
+
+ mask = (dev == d->aux) ? KM_CSR_M_WRT_PEND : KM_CSR_K_WRT_PEND;
+ while ((readl(&d->regs->km_csr) & mask) && (timeout < 1000)) {
+ udelay(100);
+ timeout++;
+ }
+
+ if (dev == d->aux)
+ writel(((u32)val) & 0x000000ff, &d->regs->m_wd);
+ else
+ writel(((u32)val) & 0x000000ff, &d->regs->k_wd);
+
+ if (timeout >= 1000)
+ return -1;
+ return 0;
+}
+
+static irqreturn_t ioc3kbd_intr(int itq, void *dev_id)
+{
+ struct ioc3kbd_data *d = dev_id;
+ u32 data_k, data_m;
+
+ data_k = readl(&d->regs->k_rd);
+ data_m = readl(&d->regs->m_rd);
+
+ if (data_k & KM_RD_VALID_0)
+ serio_interrupt(d->kbd,
+ (data_k >> KM_RD_DATA_0_SHIFT) & 0xff, 0);
+ if (data_k & KM_RD_VALID_1)
+ serio_interrupt(d->kbd,
+ (data_k >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
+ if (data_k & KM_RD_VALID_2)
+ serio_interrupt(d->kbd,
+ (data_k >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
+ if (data_m & KM_RD_VALID_0)
+ serio_interrupt(d->aux,
+ (data_m >> KM_RD_DATA_0_SHIFT) & 0xff, 0);
+ if (data_m & KM_RD_VALID_1)
+ serio_interrupt(d->aux,
+ (data_m >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
+ if (data_m & KM_RD_VALID_2)
+ serio_interrupt(d->aux,
+ (data_m >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
+
+ return 0;
+}
+
+static int ioc3kbd_open(struct serio *dev)
+{
+ return 0;
+}
+
+static void ioc3kbd_close(struct serio *dev)
+{
+ /* Empty */
+}
+
+static struct ioc3kbd_data *ioc3kbd_alloc_port(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ioc3_serioregs __iomem *regs;
+ struct ioc3kbd_data *d;
+ struct serio *sk, *sa;
+ struct resource *mem;
+ int irq;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return NULL;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return NULL;
+
+ regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
+ if (!regs)
+ return NULL;
+
+ sk = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
+ if (!sk)
+ return NULL;
+
+ sa = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
+ if (!sa)
+ return NULL;
+
+ d = devm_kzalloc(dev, sizeof(struct ioc3kbd_data),
+ GFP_KERNEL);
+ if (!d)
+ return NULL;
+
+ if (request_irq(irq, ioc3kbd_intr, IRQF_SHARED, "ioc3-kbd", d))
+ return NULL;
+
+ sk->id.type = SERIO_8042;
+ sk->write = ioc3kbd_write;
+ sk->open = ioc3kbd_open;
+ sk->close = ioc3kbd_close;
+ snprintf(sk->name, sizeof(sk->name), "IOC3 keyboard %d", pdev->id);
+ snprintf(sk->phys, sizeof(sk->phys), "ioc3/serio%dkbd", pdev->id);
+ sk->port_data = d;
+ sk->dev.parent = &pdev->dev;
+
+ sa->id.type = SERIO_8042;
+ sa->write = ioc3kbd_write;
+ sa->open = ioc3kbd_open;
+ sa->close = ioc3kbd_close;
+ snprintf(sa->name, sizeof(sa->name), "IOC3 auxiliary %d", pdev->id);
+ snprintf(sa->phys, sizeof(sa->phys), "ioc3/serio%daux", pdev->id);
+ sa->port_data = d;
+ sa->dev.parent = dev;
+
+ d->regs = regs;
+ d->kbd = sk;
+ d->aux = sa;
+ return d;
+}
+
+static int ioc3kbd_probe(struct platform_device *pdev)
+{
+ struct ioc3kbd_data *d;
+
+ d = ioc3kbd_alloc_port(pdev);
+ if (!d)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, d);
+ serio_register_port(d->kbd);
+ serio_register_port(d->aux);
+
+ return 0;
+}
+
+static int ioc3kbd_remove(struct platform_device *pdev)
+{
+ struct ioc3kbd_data *d = platform_get_drvdata(pdev);
+
+ serio_unregister_port(d->kbd);
+ serio_unregister_port(d->aux);
+ return 0;
+}
+
+static struct platform_driver ioc3kbd_driver = {
+ .probe = ioc3kbd_probe,
+ .remove = ioc3kbd_remove,
+ .driver = {
+ .name = "ioc3-kbd",
+ },
+};
+module_platform_driver(ioc3kbd_driver);
+
+MODULE_AUTHOR("Stanislaw Skowronek <skylark@unaligned.org>");
+MODULE_DESCRIPTION("SGI IOC3 serio driver");
+MODULE_LICENSE("GPL");
--
2.13.7
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing
2019-04-08 14:20 ` [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing Thomas Bogendoerfer
@ 2019-04-08 14:58 ` Alexandre Belloni
2019-04-08 18:53 ` Thomas Bogendoerfer
0 siblings, 1 reply; 15+ messages in thread
From: Alexandre Belloni @ 2019-04-08 14:58 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Greg Kroah-Hartman,
Jiri Slaby, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
On 08/04/2019 16:20:56+0200, Thomas Bogendoerfer wrote:
> diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
> index 0cf6507de3c7..05f0d91366af 100644
> --- a/drivers/rtc/rtc-m48t35.c
> +++ b/drivers/rtc/rtc-m48t35.c
> @@ -24,6 +24,16 @@
>
> struct m48t35_rtc {
> u8 pad[0x7ff8]; /* starts at 0x7ff8 */
> +#ifdef CONFIG_SGI_IP27
> + u8 hour;
> + u8 min;
> + u8 sec;
> + u8 control;
> + u8 year;
> + u8 month;
> + u8 date;
> + u8 day;
> +#else
I'm not sure why the RTC driver has to know about that. Shouldn't your
accessors be fixing that?
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device
2019-04-08 14:20 ` [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device Thomas Bogendoerfer
@ 2019-04-08 17:05 ` David Miller
2019-04-08 18:48 ` Thomas Bogendoerfer
2019-04-08 18:58 ` Thomas Bogendoerfer
0 siblings, 2 replies; 15+ messages in thread
From: David Miller @ 2019-04-08 17:05 UTC (permalink / raw)
To: tbogendoerfer
Cc: ralf, paul.burton, jhogan, dmitry.torokhov, lee.jones, a.zummo,
alexandre.belloni, gregkh, jslaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
From: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Date: Mon, 8 Apr 2019 16:20:54 +0200
> RTC platform device will be setup by new IOC3 MFD driver, therefore
> remove it from IP27 platform code.
>
> Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
You cannot break the driver like this.
Your patch series must be fully bisectable, which means that after
this patch is applied things still must continue working properly.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device
2019-04-08 17:05 ` David Miller
@ 2019-04-08 18:48 ` Thomas Bogendoerfer
2019-04-08 18:58 ` Thomas Bogendoerfer
1 sibling, 0 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 18:48 UTC (permalink / raw)
To: David Miller
Cc: ralf, paul.burton, jhogan, dmitry.torokhov, lee.jones, a.zummo,
alexandre.belloni, gregkh, jslaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
On Mon, 08 Apr 2019 10:05:28 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:
> From: Thomas Bogendoerfer <tbogendoerfer@suse.de>
> Date: Mon, 8 Apr 2019 16:20:54 +0200
>
> > RTC platform device will be setup by new IOC3 MFD driver, therefore
> > remove it from IP27 platform code.
> >
> > Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
>
> You cannot break the driver like this.
>
> Your patch series must be fully bisectable, which means that after
> this patch is applied things still must continue working properly.
I see your point and the ethernet driver itself will work properly, but of
course IP27 will be working again after applying the whole series. One
way I can see to solve this to also add the addition of the serial driver
into it. Then we are on par with the current driver. Does this solve your
concern ?
Thomas.
--
SUSE Linux GmbH
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing
2019-04-08 14:58 ` Alexandre Belloni
@ 2019-04-08 18:53 ` Thomas Bogendoerfer
0 siblings, 0 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 18:53 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Ralf Baechle, Paul Burton, James Hogan, Dmitry Torokhov,
Lee Jones, David S. Miller, Alessandro Zummo, Greg Kroah-Hartman,
Jiri Slaby, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
On Mon, 8 Apr 2019 16:58:34 +0200
Alexandre Belloni <alexandre.belloni@bootlin.com> wrote:
> On 08/04/2019 16:20:56+0200, Thomas Bogendoerfer wrote:
> > diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
> > index 0cf6507de3c7..05f0d91366af 100644
> > --- a/drivers/rtc/rtc-m48t35.c
> > +++ b/drivers/rtc/rtc-m48t35.c
> > @@ -24,6 +24,16 @@
> >
> > struct m48t35_rtc {
> > u8 pad[0x7ff8]; /* starts at 0x7ff8 */
> > +#ifdef CONFIG_SGI_IP27
> > + u8 hour;
> > + u8 min;
> > + u8 sec;
> > + u8 control;
> > + u8 year;
> > + u8 month;
> > + u8 date;
> > + u8 day;
> > +#else
>
> I'm not sure why the RTC driver has to know about that. Shouldn't your
> accessors be fixing that?
no, because the hardware is weird. RTC is connected to IOC3 byte bus and IOC3 is
connected to PCI. With a correct readb for PCI bus access to RTC behind IOC3 is byte
swapped.
Thomas.
--
SUSE Linux GmbH
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device
2019-04-08 17:05 ` David Miller
2019-04-08 18:48 ` Thomas Bogendoerfer
@ 2019-04-08 18:58 ` Thomas Bogendoerfer
1 sibling, 0 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-08 18:58 UTC (permalink / raw)
To: David Miller
Cc: ralf, paul.burton, jhogan, dmitry.torokhov, lee.jones, a.zummo,
alexandre.belloni, gregkh, jslaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
On Mon, 08 Apr 2019 10:05:28 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:
> From: Thomas Bogendoerfer <tbogendoerfer@suse.de>
> Date: Mon, 8 Apr 2019 16:20:54 +0200
>
> > RTC platform device will be setup by new IOC3 MFD driver, therefore
> > remove it from IP27 platform code.
> >
> > Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
>
> You cannot break the driver like this.
>
> Your patch series must be fully bisectable, which means that after
> this patch is applied things still must continue working properly.
sorry didn't realize your are talking about RTC. I'll check, if there
is a chance to move after the MFD driver addition.
Thomas.
--
SUSE Linux GmbH
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] Input: add IOC3 serio driver
2019-04-08 14:20 ` [PATCH 6/6] Input: add IOC3 serio driver Thomas Bogendoerfer
@ 2019-04-08 19:02 ` Dmitry Torokhov
2019-04-08 19:08 ` Alexandre Belloni
2019-04-09 10:14 ` Thomas Bogendoerfer
0 siblings, 2 replies; 15+ messages in thread
From: Dmitry Torokhov @ 2019-04-08 19:02 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Ralf Baechle, Paul Burton, James Hogan, Lee Jones,
David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
Hi Thomas,
On Mon, Apr 08, 2019 at 04:20:58PM +0200, Thomas Bogendoerfer wrote:
> This patch adds a platform driver for supporting keyboard and mouse
> interface of SGI IOC3 chips.
>
> Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
> ---
> drivers/input/serio/Kconfig | 12 +++
> drivers/input/serio/Makefile | 1 +
> drivers/input/serio/ioc3kbd.c | 183 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 196 insertions(+)
> create mode 100644 drivers/input/serio/ioc3kbd.c
>
> diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
> index c9c7224d5ae0..ceb89d8b785d 100644
> --- a/drivers/input/serio/Kconfig
> +++ b/drivers/input/serio/Kconfig
> @@ -164,6 +164,18 @@ config SERIO_MACEPS2
> To compile this driver as a module, choose M here: the
> module will be called maceps2.
>
> +config SERIO_SGI_IOC3
> + tristate "SGI IOC3 PS/2 controller"
> + depends on SGI_MFD_IOC3
> + help
> + Say Y here if you have an SGI Onyx2, SGI Octane or IOC3 PCI card
> + and you want to attach and use a keyboard, mouse, or both.
> +
> + Do not use on an SGI Origin 2000, as the IO6 board in those
> + systems lacks the necessary PS/2 ports. You will need to add
> + an IOC3 PCI card (CADduo) via a PCI Shoehorn XIO card or the
> + PCI Cardcage (shoebox) first.
To compile this driver as a module...
> +
> config SERIO_LIBPS2
> tristate "PS/2 driver library"
> depends on SERIO_I8042 || SERIO_I8042=n
> diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
> index 67950a5ccb3f..6d97bad7b844 100644
> --- a/drivers/input/serio/Makefile
> +++ b/drivers/input/serio/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o
> obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
> obj-$(CONFIG_SERIO_PS2MULT) += ps2mult.o
> obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
> +obj-$(CONFIG_SERIO_SGI_IOC3) += ioc3kbd.o
> obj-$(CONFIG_SERIO_LIBPS2) += libps2.o
> obj-$(CONFIG_SERIO_RAW) += serio_raw.o
> obj-$(CONFIG_SERIO_AMS_DELTA) += ams_delta_serio.o
> diff --git a/drivers/input/serio/ioc3kbd.c b/drivers/input/serio/ioc3kbd.c
> new file mode 100644
> index 000000000000..8ff46a9f3d98
> --- /dev/null
> +++ b/drivers/input/serio/ioc3kbd.c
> @@ -0,0 +1,183 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * SGI IOC3 PS/2 controller driver for linux
> + *
> + * Copyright (C) 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
> + *
> + * Based on code Copyright (C) 2005 Stanislaw Skowronek <skylark@unaligned.org>
> + * Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/serio.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +
> +#include <asm/sn/ioc3.h>
> +
> +struct ioc3kbd_data {
> + struct ioc3_serioregs __iomem *regs;
> + struct serio *kbd, *aux;
> +};
> +
> +static int ioc3kbd_write(struct serio *dev, u8 val)
> +{
> + struct ioc3kbd_data *d = (struct ioc3kbd_data *)(dev->port_data);
serio->port_data is void pointer, no need to cast.
> + unsigned long timeout = 0;
> + u32 mask;
> +
> + mask = (dev == d->aux) ? KM_CSR_M_WRT_PEND : KM_CSR_K_WRT_PEND;
> + while ((readl(&d->regs->km_csr) & mask) && (timeout < 1000)) {
> + udelay(100);
> + timeout++;
> + }
> +
> + if (dev == d->aux)
> + writel(((u32)val) & 0x000000ff, &d->regs->m_wd);
> + else
> + writel(((u32)val) & 0x000000ff, &d->regs->k_wd);
Why do you need to mask the upper bits if you start with u8? Can you
just say:
writel(val, dev == d->aux ? &d->regs->m_wd, &d->regs->k_wd);
> +
> + if (timeout >= 1000)
> + return -1;
So you attempt to write even if controller indicates that it is busy?
> + return 0;
> +}
> +
> +static irqreturn_t ioc3kbd_intr(int itq, void *dev_id)
> +{
> + struct ioc3kbd_data *d = dev_id;
> + u32 data_k, data_m;
> +
> + data_k = readl(&d->regs->k_rd);
> + data_m = readl(&d->regs->m_rd);
> +
> + if (data_k & KM_RD_VALID_0)
> + serio_interrupt(d->kbd,
> + (data_k >> KM_RD_DATA_0_SHIFT) & 0xff, 0);
> + if (data_k & KM_RD_VALID_1)
> + serio_interrupt(d->kbd,
> + (data_k >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
> + if (data_k & KM_RD_VALID_2)
> + serio_interrupt(d->kbd,
> + (data_k >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
> + if (data_m & KM_RD_VALID_0)
> + serio_interrupt(d->aux,
> + (data_m >> KM_RD_DATA_0_SHIFT) & 0xff, 0);
> + if (data_m & KM_RD_VALID_1)
> + serio_interrupt(d->aux,
> + (data_m >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
> + if (data_m & KM_RD_VALID_2)
> + serio_interrupt(d->aux,
> + (data_m >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
> +
> + return 0;
> +}
> +
> +static int ioc3kbd_open(struct serio *dev)
> +{
> + return 0;
> +}
> +
> +static void ioc3kbd_close(struct serio *dev)
> +{
> + /* Empty */
> +}
You do not need empty stubs.
> +
> +static struct ioc3kbd_data *ioc3kbd_alloc_port(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct ioc3_serioregs __iomem *regs;
> + struct ioc3kbd_data *d;
> + struct serio *sk, *sa;
> + struct resource *mem;
> + int irq;
> +
> + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!mem)
> + return NULL;
> +
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0)
> + return NULL;
> +
> + regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
> + if (!regs)
> + return NULL;
> +
> + sk = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
> + if (!sk)
> + return NULL;
> +
> + sa = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
> + if (!sa)
> + return NULL;
serio ports are refcounted, they must not be allocated with devm_* API
as their lifetime may extend past the remove() time.
> +
> + d = devm_kzalloc(dev, sizeof(struct ioc3kbd_data),
> + GFP_KERNEL);
> + if (!d)
> + return NULL;
> +
> + if (request_irq(irq, ioc3kbd_intr, IRQF_SHARED, "ioc3-kbd", d))
> + return NULL;
This is unfortunate that you lose error code. You also fail to handle
-EPROPE_DEFER from request_irq().
> +
> + sk->id.type = SERIO_8042;
> + sk->write = ioc3kbd_write;
> + sk->open = ioc3kbd_open;
> + sk->close = ioc3kbd_close;
> + snprintf(sk->name, sizeof(sk->name), "IOC3 keyboard %d", pdev->id);
> + snprintf(sk->phys, sizeof(sk->phys), "ioc3/serio%dkbd", pdev->id);
> + sk->port_data = d;
> + sk->dev.parent = &pdev->dev;
> +
> + sa->id.type = SERIO_8042;
> + sa->write = ioc3kbd_write;
> + sa->open = ioc3kbd_open;
> + sa->close = ioc3kbd_close;
> + snprintf(sa->name, sizeof(sa->name), "IOC3 auxiliary %d", pdev->id);
> + snprintf(sa->phys, sizeof(sa->phys), "ioc3/serio%daux", pdev->id);
> + sa->port_data = d;
> + sa->dev.parent = dev;
> +
> + d->regs = regs;
> + d->kbd = sk;
> + d->aux = sa;
> + return d;
> +}
> +
> +static int ioc3kbd_probe(struct platform_device *pdev)
> +{
> + struct ioc3kbd_data *d;
> +
> + d = ioc3kbd_alloc_port(pdev);
> + if (!d)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, d);
> + serio_register_port(d->kbd);
> + serio_register_port(d->aux);
> +
> + return 0;
> +}
> +
> +static int ioc3kbd_remove(struct platform_device *pdev)
> +{
> + struct ioc3kbd_data *d = platform_get_drvdata(pdev);
> +
> + serio_unregister_port(d->kbd);
> + serio_unregister_port(d->aux);
> + return 0;
> +}
> +
> +static struct platform_driver ioc3kbd_driver = {
> + .probe = ioc3kbd_probe,
> + .remove = ioc3kbd_remove,
> + .driver = {
> + .name = "ioc3-kbd",
> + },
> +};
> +module_platform_driver(ioc3kbd_driver);
> +
> +MODULE_AUTHOR("Stanislaw Skowronek <skylark@unaligned.org>");
> +MODULE_DESCRIPTION("SGI IOC3 serio driver");
> +MODULE_LICENSE("GPL");
"GPL v2" to match SPDX header?
> --
> 2.13.7
>
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] Input: add IOC3 serio driver
2019-04-08 19:02 ` Dmitry Torokhov
@ 2019-04-08 19:08 ` Alexandre Belloni
2019-04-08 22:32 ` Dmitry Torokhov
2019-04-09 10:14 ` Thomas Bogendoerfer
1 sibling, 1 reply; 15+ messages in thread
From: Alexandre Belloni @ 2019-04-08 19:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Thomas Bogendoerfer, Ralf Baechle, Paul Burton, James Hogan,
Lee Jones, David S. Miller, Alessandro Zummo, Greg Kroah-Hartman,
Jiri Slaby, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
On 08/04/2019 12:02:18-0700, Dmitry Torokhov wrote:
> > +MODULE_AUTHOR("Stanislaw Skowronek <skylark@unaligned.org>");
> > +MODULE_DESCRIPTION("SGI IOC3 serio driver");
> > +MODULE_LICENSE("GPL");
>
> "GPL v2" to match SPDX header?
>
I've been told this is not true:
https://lore.kernel.org/linux-rtc/371999940784dbd281669122c3027805ab0ecfd9.camel@perches.com/
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] Input: add IOC3 serio driver
2019-04-08 19:08 ` Alexandre Belloni
@ 2019-04-08 22:32 ` Dmitry Torokhov
0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Torokhov @ 2019-04-08 22:32 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Thomas Bogendoerfer, Ralf Baechle, Paul Burton, James Hogan,
Lee Jones, David S. Miller, Alessandro Zummo, Greg Kroah-Hartman,
Jiri Slaby, linux-mips, linux-kernel, linux-input, netdev,
linux-rtc, linux-serial
On Mon, Apr 08, 2019 at 09:08:42PM +0200, Alexandre Belloni wrote:
> On 08/04/2019 12:02:18-0700, Dmitry Torokhov wrote:
> > > +MODULE_AUTHOR("Stanislaw Skowronek <skylark@unaligned.org>");
> > > +MODULE_DESCRIPTION("SGI IOC3 serio driver");
> > > +MODULE_LICENSE("GPL");
> >
> > "GPL v2" to match SPDX header?
> >
>
> I've been told this is not true:
>
> https://lore.kernel.org/linux-rtc/371999940784dbd281669122c3027805ab0ecfd9.camel@perches.com/
Ah, great, nevermind then.
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 6/6] Input: add IOC3 serio driver
2019-04-08 19:02 ` Dmitry Torokhov
2019-04-08 19:08 ` Alexandre Belloni
@ 2019-04-09 10:14 ` Thomas Bogendoerfer
1 sibling, 0 replies; 15+ messages in thread
From: Thomas Bogendoerfer @ 2019-04-09 10:14 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Ralf Baechle, Paul Burton, James Hogan, Lee Jones,
David S. Miller, Alessandro Zummo, Alexandre Belloni,
Greg Kroah-Hartman, Jiri Slaby, linux-mips, linux-kernel,
linux-input, netdev, linux-rtc, linux-serial
On Mon, 8 Apr 2019 12:02:18 -0700
Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> On Mon, Apr 08, 2019 at 04:20:58PM +0200, Thomas Bogendoerfer wrote:
> > This patch adds a platform driver for supporting keyboard and mouse
> > interface of SGI IOC3 chips.
> [...]
Thank you for your feedback, I've changed the code accordingly and will
send a v2 version after testing it.
Thomas.
--
SUSE Linux GmbH
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah
HRB 21284 (AG Nürnberg)
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2019-04-09 10:15 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-08 14:20 [PATCH 0/6] Use MFD framework for SGI IOC3 drivers Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 1/6] MIPS: SGI-IP27: remove ioc3 ethernet init Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 2/6] MIPS: SGI-IP27: remove setup of RTC platform device Thomas Bogendoerfer
2019-04-08 17:05 ` David Miller
2019-04-08 18:48 ` Thomas Bogendoerfer
2019-04-08 18:58 ` Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 4/6] MIPS: SGI-IP27: fix readb/writeb addressing Thomas Bogendoerfer
2019-04-08 14:58 ` Alexandre Belloni
2019-04-08 18:53 ` Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 5/6] tty: serial: Add 8250-core base IOC3 driver Thomas Bogendoerfer
2019-04-08 14:20 ` [PATCH 6/6] Input: add IOC3 serio driver Thomas Bogendoerfer
2019-04-08 19:02 ` Dmitry Torokhov
2019-04-08 19:08 ` Alexandre Belloni
2019-04-08 22:32 ` Dmitry Torokhov
2019-04-09 10:14 ` Thomas Bogendoerfer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).