[Openipmi-developer] [PATCH v2] ipmi: kcs_bmc: fix IRQ exception if the channel is not open
When kcs_bmc_handle_event calls kcs_force_abort function to handle the not open (no user running) KCS channel transaction, the returned status value -ENODEV causes the low level IRQ handler indicating that the irq was not for him by returning IRQ_NONE. After some time, this IRQ will be treated to be spurious one, and the exception dump happens. irq 30: nobody cared (try booting with the "irqpoll" option) CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.10.15-npcm750 #1 Hardware name: NPCMX50 Chip family [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x8c/0xa0) [] (dump_stack) from [] (__report_bad_irq+0x3c/0xdc) [] (__report_bad_irq) from [] (note_interrupt+0x29c/0x2ec) [] (note_interrupt) from [] (handle_irq_event_percpu+0x5c/0x68) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x48/0x6c) [] (handle_irq_event) from [] (handle_fasteoi_irq+0xc8/0x198) [] (handle_fasteoi_irq) from [] (__handle_domain_irq+0x90/0xe8) [] (__handle_domain_irq) from [] (gic_handle_irq+0x58/0x9c) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) Exception stack(0xc0a01de8 to 0xc0a01e30) 1de0: 2080 c0a6fbc0 c096d294 1e00: 0001 dc406400 f03ff100 0082 c0a01e94 c0a6fbc0 c0a01e38 1e20: 00200102 c01015bc 6113 [] (__irq_svc) from [] (__do_softirq+0xbc/0x358) [] (__do_softirq) from [] (irq_exit+0xb8/0xec) [] (irq_exit) from [] (__handle_domain_irq+0x94/0xe8) [] (__handle_domain_irq) from [] (gic_handle_irq+0x58/0x9c) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) Exception stack(0xc0a01ef8 to 0xc0a01f40) 1ee0: 03ae 1f00: dcc0f338 c0111060 c0a0 c0a0cc44 c0a0cbe4 c0a1c22b c07bc218 0001 1f20: dcffca40 c0a01f54 c0a01f58 c0a01f48 c0103524 c0103528 6013 [] (__irq_svc) from [] (arch_cpu_idle+0x48/0x4c) [] (arch_cpu_idle) from [] (default_idle_call+0x30/0x3c) [] (default_idle_call) from [] (do_idle+0xc8/0x134) [] (do_idle) from [] (cpu_startup_entry+0x28/0x2c) [] (cpu_startup_entry) from [] (rest_init+0x84/0x88) [] (rest_init) from [] (start_kernel+0x388/0x394) [] (start_kernel) from [<807c>] (0x807c) handlers: [] npcm7xx_kcs_irq Disabling IRQ #30 It needs to change the returned status from -ENODEV to 0. The -ENODEV was originally used to tell the low level IRQ handler that no user was running, but not consider the IRQ handling desgin. And multiple KCS channels share one IRQ handler, it needs to check the IBF flag before doing force abort. If the IBF is set, after handling, return 0 to low level IRQ handler to indicate that the IRQ is handled. Signed-off-by: Haiyue Wang --- v1 -> v2: - Change the commit message to be more understandable. --- drivers/char/ipmi/kcs_bmc.c | 31 ++- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index fbfc05e..bb882ab1 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -210,34 +210,23 @@ static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc) int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) { unsigned long flags; - int ret = 0; + int ret = -ENODATA; u8 status; spin_lock_irqsave(_bmc->lock, flags); - if (!kcs_bmc->running) { - kcs_force_abort(kcs_bmc); - ret = -ENODEV; - goto out_unlock; - } - - status = read_status(kcs_bmc) & (KCS_STATUS_IBF | KCS_STATUS_CMD_DAT); - - switch (status) { - case KCS_STATUS_IBF | KCS_STATUS_CMD_DAT: - kcs_bmc_handle_cmd(kcs_bmc); - break; - - case KCS_STATUS_IBF: - kcs_bmc_handle_data(kcs_bmc); - break; + status = read_status(kcs_bmc); + if (status & KCS_STATUS_IBF) { + if (!kcs_bmc->running) + kcs_force_abort(kcs_bmc); + else if (status & KCS_STATUS_CMD_DAT) + kcs_bmc_handle_cmd(kcs_bmc); + else + kcs_bmc_handle_data(kcs_bmc); - default: - ret = -ENODATA; - break; + ret = 0; } -out_unlock: spin_unlock_irqrestore(_bmc->lock, flags); return ret; -- 2.7.4 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Openipmi-developer mailing list Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer
[Openipmi-developer] [PATCH ] ipmi: kcs_bmc: fix IRQ exception if the channel is not open
The original core KCS IRQ handling function 'kcs_bmc_handle_event' had a wrong logical desgin, it should force abort the KCS transaction only if the IBF flag is set, because multiple KCS channels share the same handle function; and it should return 0, which indicates that event of current channel is handled. An negative value -ENODATA will cause the IRQ handler of BMC KCS controller return IRQ_NONE, then IRQ moudle will treat this IRQ 'nobody cared', it will trigger IRQ exception. irq 30: nobody cared (try booting with the "irqpoll" option) CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.10.15-npcm750 #1 Hardware name: NPCMX50 Chip family [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x8c/0xa0) [] (dump_stack) from [] (__report_bad_irq+0x3c/0xdc) [] (__report_bad_irq) from [] (note_interrupt+0x29c/0x2ec) [] (note_interrupt) from [] (handle_irq_event_percpu+0x5c/0x68) [] (handle_irq_event_percpu) from [] (handle_irq_event+0x48/0x6c) [] (handle_irq_event) from [] (handle_fasteoi_irq+0xc8/0x198) [] (handle_fasteoi_irq) from [] (__handle_domain_irq+0x90/0xe8) [] (__handle_domain_irq) from [] (gic_handle_irq+0x58/0x9c) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) Exception stack(0xc0a01de8 to 0xc0a01e30) 1de0: 2080 c0a6fbc0 c096d294 1e00: 0001 dc406400 f03ff100 0082 c0a01e94 c0a6fbc0 c0a01e38 1e20: 00200102 c01015bc 6113 [] (__irq_svc) from [] (__do_softirq+0xbc/0x358) [] (__do_softirq) from [] (irq_exit+0xb8/0xec) [] (irq_exit) from [] (__handle_domain_irq+0x94/0xe8) [] (__handle_domain_irq) from [] (gic_handle_irq+0x58/0x9c) [] (gic_handle_irq) from [] (__irq_svc+0x6c/0x90) Exception stack(0xc0a01ef8 to 0xc0a01f40) 1ee0: 03ae 1f00: dcc0f338 c0111060 c0a0 c0a0cc44 c0a0cbe4 c0a1c22b c07bc218 0001 1f20: dcffca40 c0a01f54 c0a01f58 c0a01f48 c0103524 c0103528 6013 [] (__irq_svc) from [] (arch_cpu_idle+0x48/0x4c) [] (arch_cpu_idle) from [] (default_idle_call+0x30/0x3c) [] (default_idle_call) from [] (do_idle+0xc8/0x134) [] (do_idle) from [] (cpu_startup_entry+0x28/0x2c) [] (cpu_startup_entry) from [] (rest_init+0x84/0x88) [] (rest_init) from [] (start_kernel+0x388/0x394) [] (start_kernel) from [<807c>] (0x807c) handlers: [] npcm7xx_kcs_irq Disabling IRQ #30 Signed-off-by: Haiyue Wang --- Hi Corey, This patch looks introducing BIG modification, it should be easily understandable, and makes code clean & fix an error design, which is introduced by misunderstanding the IRQ return value. BR, Haiyue --- drivers/char/ipmi/kcs_bmc.c | 31 ++- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index fbfc05e..bb882ab1 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -210,34 +210,23 @@ static void kcs_bmc_handle_cmd(struct kcs_bmc *kcs_bmc) int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) { unsigned long flags; - int ret = 0; + int ret = -ENODATA; u8 status; spin_lock_irqsave(_bmc->lock, flags); - if (!kcs_bmc->running) { - kcs_force_abort(kcs_bmc); - ret = -ENODEV; - goto out_unlock; - } - - status = read_status(kcs_bmc) & (KCS_STATUS_IBF | KCS_STATUS_CMD_DAT); - - switch (status) { - case KCS_STATUS_IBF | KCS_STATUS_CMD_DAT: - kcs_bmc_handle_cmd(kcs_bmc); - break; - - case KCS_STATUS_IBF: - kcs_bmc_handle_data(kcs_bmc); - break; + status = read_status(kcs_bmc); + if (status & KCS_STATUS_IBF) { + if (!kcs_bmc->running) + kcs_force_abort(kcs_bmc); + else if (status & KCS_STATUS_CMD_DAT) + kcs_bmc_handle_cmd(kcs_bmc); + else + kcs_bmc_handle_data(kcs_bmc); - default: - ret = -ENODATA; - break; + ret = 0; } -out_unlock: spin_unlock_irqrestore(_bmc->lock, flags); return ret; -- 2.7.4 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Openipmi-developer mailing list Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer
[Openipmi-developer] [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: optimize the data buffers allocation
Allocate a continuous memory block for the three KCS data buffers with related index assignment. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- drivers/char/ipmi/kcs_bmc.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index fbfc05e..dc19c0d 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -435,6 +435,7 @@ static const struct file_operations kcs_bmc_fops = { struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel) { struct kcs_bmc *kcs_bmc; + void *buf; kcs_bmc = devm_kzalloc(dev, sizeof(*kcs_bmc) + sizeof_priv, GFP_KERNEL); if (!kcs_bmc) @@ -448,11 +449,12 @@ struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv, u32 channel) mutex_init(_bmc->mutex); init_waitqueue_head(_bmc->queue); - kcs_bmc->data_in = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); - kcs_bmc->data_out = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); - kcs_bmc->kbuffer = devm_kmalloc(dev, KCS_MSG_BUFSIZ, GFP_KERNEL); - if (!kcs_bmc->data_in || !kcs_bmc->data_out || !kcs_bmc->kbuffer) + buf = devm_kmalloc_array(dev, 3, KCS_MSG_BUFSIZ, GFP_KERNEL); + if (!buf) return NULL; + kcs_bmc->data_in = buf; + kcs_bmc->data_out = buf + KCS_MSG_BUFSIZ; + kcs_bmc->kbuffer = buf + KCS_MSG_BUFSIZ * 2; kcs_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; kcs_bmc->miscdev.name = dev_name(dev); -- 2.7.4 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Openipmi-developer mailing list Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer
[Openipmi-developer] [PATCH ipmi/kcs_bmc v2] ipmi: kcs_bmc: make the code be more clean
--- v1 -> v2: Add 'SPDX-License-Identifier' style for header files modification. --- 1. Add the missed key word '__user' for read / write. 2. Remove the prefix 'file' of 'file_to_kcs_bmc', no need this duplicated word as its parameter has 'struct file *filp'. 3. Change the 'unsigned int' to '__poll_t' to meet the new 'poll' definition. 4. Correct the 'SPDX-License-Identifier' style for header files. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- drivers/char/ipmi/kcs_bmc.c| 32 +--- drivers/char/ipmi/kcs_bmc.h| 6 -- drivers/char/ipmi/kcs_bmc_aspeed.c | 4 +++- include/uapi/linux/ipmi_bmc.h | 6 -- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index 6476bfb..fbfc05e 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2015-2018, Intel Corporation. +/* + * Copyright (c) 2015-2018, Intel Corporation. + */ #define pr_fmt(fmt) "kcs-bmc: " fmt @@ -242,14 +244,14 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) } EXPORT_SYMBOL(kcs_bmc_handle_event); -static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp) +static inline struct kcs_bmc *to_kcs_bmc(struct file *filp) { return container_of(filp->private_data, struct kcs_bmc, miscdev); } static int kcs_bmc_open(struct inode *inode, struct file *filp) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); int ret = 0; spin_lock_irq(_bmc->lock); @@ -262,25 +264,25 @@ static int kcs_bmc_open(struct inode *inode, struct file *filp) return ret; } -static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait) +static __poll_t kcs_bmc_poll(struct file *filp, poll_table *wait) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); - unsigned int mask = 0; + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + __poll_t mask = 0; poll_wait(filp, _bmc->queue, wait); spin_lock_irq(_bmc->lock); if (kcs_bmc->data_in_avail) - mask |= POLLIN; + mask |= EPOLLIN; spin_unlock_irq(_bmc->lock); return mask; } -static ssize_t kcs_bmc_read(struct file *filp, char *buf, - size_t count, loff_t *offset) +static ssize_t kcs_bmc_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); bool data_avail; size_t data_len; ssize_t ret; @@ -339,10 +341,10 @@ static ssize_t kcs_bmc_read(struct file *filp, char *buf, return ret; } -static ssize_t kcs_bmc_write(struct file *filp, const char *buf, -size_t count, loff_t *offset) +static ssize_t kcs_bmc_write(struct file *filp, const char __user *buf, +size_t count, loff_t *ppos) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); ssize_t ret; /* a minimum response size '3' : netfn + cmd + ccode */ @@ -378,7 +380,7 @@ static ssize_t kcs_bmc_write(struct file *filp, const char *buf, static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); long ret = 0; spin_lock_irq(_bmc->lock); @@ -410,7 +412,7 @@ static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, static int kcs_bmc_release(struct inode *inode, struct file *filp) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); spin_lock_irq(_bmc->lock); kcs_bmc->running = 0; diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h index c19501d..69d9a70 100644 --- a/drivers/char/ipmi/kcs_bmc.h +++ b/drivers/char/ipmi/kcs_bmc.h @@ -1,5 +1,7 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2015-2018, Intel Corporation. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015-2018, Intel Corporation. + */ #ifndef __KCS_BMC_H__ #define __KCS_BMC_H__ diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c index 0c4d1a3..dba6075 100644 --- a/drivers/char/ipmi/kcs_bmc_aspeed.c +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2015-2018, Intel Corporation. +/* + * Copyright (c) 2015-2018, Intel Corporation. + */ #define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt diff --git a/include/uapi/linux/ipmi_bmc.h b/include/uapi/linux/ipmi_bmc.h index 2f9f97e..d3efacd 100644 ---
[Openipmi-developer] [PATCH ipmi/kcs_bmc v4] ipmi: kcs_bmc: make the code be more clean
Modify the file read and write operation API's parameter declaration to meet the name convention. Rename the helper function by following the to_() name style. Update the poll API with the new type '__poll_t', this is new commit from linux-4.16-rc1. Correct the header file's comment style for 'SPDX-License-Identifier'. Correct the header file's macro defination end comment which is old file name. Remove the space between the comment words and colon by referring other modules. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- v3 -> v4: - Correct the header file's macro defination end comment which is old file name, I forgot to change it after changing the file name. - Remove the space between the comment words and colon by referring other modules. v2 -> v3: - Make the commit message be more understandable. v1 -> v2: - Add 'SPDX-License-Identifier' style for header files modification. --- drivers/char/ipmi/kcs_bmc.c| 32 +--- drivers/char/ipmi/kcs_bmc.h| 36 +++- drivers/char/ipmi/kcs_bmc_aspeed.c | 4 +++- include/uapi/linux/ipmi_bmc.h | 8 +--- 4 files changed, 44 insertions(+), 36 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index 6476bfb..fbfc05e 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2015-2018, Intel Corporation. +/* + * Copyright (c) 2015-2018, Intel Corporation. + */ #define pr_fmt(fmt) "kcs-bmc: " fmt @@ -242,14 +244,14 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) } EXPORT_SYMBOL(kcs_bmc_handle_event); -static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp) +static inline struct kcs_bmc *to_kcs_bmc(struct file *filp) { return container_of(filp->private_data, struct kcs_bmc, miscdev); } static int kcs_bmc_open(struct inode *inode, struct file *filp) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); int ret = 0; spin_lock_irq(_bmc->lock); @@ -262,25 +264,25 @@ static int kcs_bmc_open(struct inode *inode, struct file *filp) return ret; } -static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait) +static __poll_t kcs_bmc_poll(struct file *filp, poll_table *wait) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); - unsigned int mask = 0; + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + __poll_t mask = 0; poll_wait(filp, _bmc->queue, wait); spin_lock_irq(_bmc->lock); if (kcs_bmc->data_in_avail) - mask |= POLLIN; + mask |= EPOLLIN; spin_unlock_irq(_bmc->lock); return mask; } -static ssize_t kcs_bmc_read(struct file *filp, char *buf, - size_t count, loff_t *offset) +static ssize_t kcs_bmc_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); bool data_avail; size_t data_len; ssize_t ret; @@ -339,10 +341,10 @@ static ssize_t kcs_bmc_read(struct file *filp, char *buf, return ret; } -static ssize_t kcs_bmc_write(struct file *filp, const char *buf, -size_t count, loff_t *offset) +static ssize_t kcs_bmc_write(struct file *filp, const char __user *buf, +size_t count, loff_t *ppos) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); ssize_t ret; /* a minimum response size '3' : netfn + cmd + ccode */ @@ -378,7 +380,7 @@ static ssize_t kcs_bmc_write(struct file *filp, const char *buf, static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); long ret = 0; spin_lock_irq(_bmc->lock); @@ -410,7 +412,7 @@ static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, static int kcs_bmc_release(struct inode *inode, struct file *filp) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); spin_lock_irq(_bmc->lock); kcs_bmc->running = 0; diff --git a/drivers/char/ipmi/kcs_bmc.h b/drivers/char/ipmi/kcs_bmc.h index c19501d..eb9ea4c 100644 --- a/drivers/char/ipmi/kcs_bmc.h +++ b/drivers/char/ipmi/kcs_bmc.h @@ -1,31 +1,33 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2015-2018, Intel Corporation. +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015-2018, Intel Corporation. + */ #ifndef __KCS_BMC_H__ #define __KCS_BMC_H__ #i
[Openipmi-developer] [PATCH ipmi/kcs_bmc v1] ipmi: kcs_bmc: make the code be more clean
Hi Corey, I've changed some code style to meet with the whole Linux style. Please help to review. BR, Haiyue --- 1. Add the missed key word '__user' for read / write. 2. Remove the prefix 'file' of 'file_to_kcs_bmc', no need this duplicated word as its parameter has 'struct file *filp'. 3. Change the 'unsigned int' to '__poll_t' to meet the new 'poll' definition. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- drivers/char/ipmi/kcs_bmc.c | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c index 6476bfb..2fe55b0 100644 --- a/drivers/char/ipmi/kcs_bmc.c +++ b/drivers/char/ipmi/kcs_bmc.c @@ -242,14 +242,14 @@ int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc) } EXPORT_SYMBOL(kcs_bmc_handle_event); -static inline struct kcs_bmc *file_to_kcs_bmc(struct file *filp) +static inline struct kcs_bmc *to_kcs_bmc(struct file *filp) { return container_of(filp->private_data, struct kcs_bmc, miscdev); } static int kcs_bmc_open(struct inode *inode, struct file *filp) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); int ret = 0; spin_lock_irq(_bmc->lock); @@ -262,10 +262,10 @@ static int kcs_bmc_open(struct inode *inode, struct file *filp) return ret; } -static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait) +static __poll_t kcs_bmc_poll(struct file *filp, poll_table *wait) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); - unsigned int mask = 0; + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); + __poll_t mask = 0; poll_wait(filp, _bmc->queue, wait); @@ -277,10 +277,10 @@ static unsigned int kcs_bmc_poll(struct file *filp, poll_table *wait) return mask; } -static ssize_t kcs_bmc_read(struct file *filp, char *buf, - size_t count, loff_t *offset) +static ssize_t kcs_bmc_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); bool data_avail; size_t data_len; ssize_t ret; @@ -339,10 +339,10 @@ static ssize_t kcs_bmc_read(struct file *filp, char *buf, return ret; } -static ssize_t kcs_bmc_write(struct file *filp, const char *buf, -size_t count, loff_t *offset) +static ssize_t kcs_bmc_write(struct file *filp, const char __user *buf, +size_t count, loff_t *ppos) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); ssize_t ret; /* a minimum response size '3' : netfn + cmd + ccode */ @@ -378,7 +378,7 @@ static ssize_t kcs_bmc_write(struct file *filp, const char *buf, static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); long ret = 0; spin_lock_irq(_bmc->lock); @@ -410,7 +410,7 @@ static long kcs_bmc_ioctl(struct file *filp, unsigned int cmd, static int kcs_bmc_release(struct inode *inode, struct file *filp) { - struct kcs_bmc *kcs_bmc = file_to_kcs_bmc(filp); + struct kcs_bmc *kcs_bmc = to_kcs_bmc(filp); spin_lock_irq(_bmc->lock); kcs_bmc->running = 0; -- 2.7.4 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Openipmi-developer mailing list Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer
[Openipmi-developer] [PATCH arm/aspeed/ast2500 v5 2/2] ipmi: add an Aspeed KCS IPMI BMC driver
The KCS (Keyboard Controller Style) interface is used to perform in-band IPMI communication between a server host and its BMC (BaseBoard Management Controllers). This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are commonly used as BMCs and this driver implements the BMC side of the KCS interface. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt| 26 ++ drivers/char/ipmi/Kconfig | 12 + drivers/char/ipmi/Makefile | 1 + drivers/char/ipmi/kcs_bmc_aspeed.c | 319 + 4 files changed, 358 insertions(+) create mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt create mode 100644 drivers/char/ipmi/kcs_bmc_aspeed.c diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt new file mode 100644 index 000..613c34c --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt @@ -0,0 +1,26 @@ +* Aspeed KCS (Keyboard Controller Style) IPMI interface + +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs +(Baseboard Management Controllers) and the KCS interface can be +used to perform in-band IPMI communication with their host. + +Required properties: +- compatible : should be one of +"aspeed,ast2400-kcs-bmc" +"aspeed,ast2500-kcs-bmc" +- interrupts : interrupt generated by the controller +- kcs_chan : The LPC channel number in the controller +- kcs_addr : The host CPU IO map address + + +Example: + +kcs3: kcs3@0 { +compatible = "aspeed,ast2500-kcs-bmc"; +reg = <0x0 0x80>; +interrupts = <8>; +kcs_chan = <3>; +kcs_addr = <0xCA2>; +status = "okay"; +}; + diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index aa9bcb1..f72fe56 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -104,6 +104,18 @@ config IPMI_KCS_BMC Management Controllers) side for handling the IPMI request from host system software. +config ASPEED_KCS_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + select IPMI_KCS_BMC + select REGMAP_MMIO + tristate "Aspeed KCS IPMI BMC driver" + help + Provides a driver for the KCS (Keyboard Controller Style) IPMI + interface found on Aspeed SOCs (AST2400 and AST2500). + + The driver implements the BMC side of the KCS contorller, it + provides the access of KCS IO space for BMC side. + config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST depends on REGMAP && REGMAP_MMIO && MFD_SYSCON diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 2abccb3..21e9e87 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c new file mode 100644 index 000..0c4d1a3 --- /dev/null +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2018, Intel Corporation. + +#define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcs_bmc.h" + + +#define DEVICE_NAME "ast-kcs-bmc" + +#define KCS_CHANNEL_MAX 4 + +/* mapped to lpc-bmc@0 IO space */ +#define LPC_HICR00x000 +#define LPC_HICR0_LPC3E BIT(7) +#define LPC_HICR0_LPC2E BIT(6) +#define LPC_HICR0_LPC1E BIT(5) +#define LPC_HICR20x008 +#define LPC_HICR2_IBFIF3 BIT(3) +#define LPC_HICR2_IBFIF2 BIT(2) +#define LPC_HICR2_IBFIF1 BIT(1) +#define LPC_HICR40x010 +#define LPC_HICR4_LADR12AS BIT(7) +#define LPC_HICR4_KCSENBLBIT(2) +#define LPC_LADR3H 0x014 +#define LPC_LADR3L 0x018 +#define LPC_LADR12H 0x01C +#define LPC_LADR12L 0x020 +#define LPC_IDR1 0x024 +#define LPC_IDR2 0x028 +#define LPC_IDR3 0x02C +#define LPC_ODR1 0x030 +#define LPC_ODR2 0x034 +#define LPC_ODR3 0x038 +#define LPC_STR1 0x03C +#define LPC_STR2 0x040 +#define LPC_STR3 0x044 + +/* mapped to lpc-host@80 IO space */ +#define LPC_HICRB0x080 +#define LPC_HICRB_IBFIF4 BIT(1) +#define
[Openipmi-developer] [PATCH arm/aspeed/ast2500 v4 1/2] ipmi: add a KCS IPMI BMC driver
--- v3->v4 - Change to accept WRITE_START any time. v2->v3 - Update the KCS phase state machine. - Fix the race condition of read/write. v1->v2 - Divide the driver into two parts, one handles the BMC KCS IPMI 2.0 state; the other handles the BMC KCS controller such as AST2500 IO accessing. - Use the spin lock APIs to handle the device file operations and BMC chip IRQ inferface for accessing the same KCS BMC data structure. - Enhanced the phases handling of the KCS BMC. - Unified the IOCTL definition for IPMI BMC, it will be used by KCS and BT. Provides a device driver for the KCS (Keyboard Controller Style) IPMI interface which meets the requirement of the BMC (Baseboard Management Controllers) side for handling the IPMI request from host system software. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- drivers/char/ipmi/Kconfig | 8 + drivers/char/ipmi/Makefile| 1 + drivers/char/ipmi/kcs_bmc.c | 464 ++ drivers/char/ipmi/kcs_bmc.h | 106 ++ include/uapi/linux/ipmi_bmc.h | 14 ++ 5 files changed, 593 insertions(+) create mode 100644 drivers/char/ipmi/kcs_bmc.c create mode 100644 drivers/char/ipmi/kcs_bmc.h create mode 100644 include/uapi/linux/ipmi_bmc.h diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 3544abc..aa9bcb1 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -96,6 +96,14 @@ config IPMI_POWEROFF endif # IPMI_HANDLER +config IPMI_KCS_BMC + tristate 'IPMI KCS BMC Interface' + help + Provides a device driver for the KCS (Keyboard Controller Style) + IPMI interface which meets the requirement of the BMC (Baseboard + Management Controllers) side for handling the IPMI request from + host system software. + config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST depends on REGMAP && REGMAP_MMIO && MFD_SYSCON diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 33b899f..2abccb3 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -21,4 +21,5 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o +obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c new file mode 100644 index 000..d1751b4 --- /dev/null +++ b/drivers/char/ipmi/kcs_bmc.c @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2018, Intel Corporation. + +#define pr_fmt(fmt) "kcs-bmc: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcs_bmc.h" + +#define KCS_MSG_BUFSIZ1000 + +#define KCS_ZERO_DATA 0 + + +/* IPMI 2.0 - Table 9-1, KCS Interface Status Register Bits */ +#define KCS_STATUS_STATE(state) (state << 6) +#define KCS_STATUS_STATE_MASK GENMASK(7, 6) +#define KCS_STATUS_CMD_DAT BIT(3) +#define KCS_STATUS_SMS_ATN BIT(2) +#define KCS_STATUS_IBF BIT(1) +#define KCS_STATUS_OBF BIT(0) + +/* IPMI 2.0 - Table 9-2, KCS Interface State Bits */ +enum kcs_states { + IDLE_STATE = 0, + READ_STATE = 1, + WRITE_STATE = 2, + ERROR_STATE = 3, +}; + +/* IPMI 2.0 - Table 9-3, KCS Interface Control Codes */ +#define KCS_CMD_GET_STATUS_ABORT 0x60 +#define KCS_CMD_WRITE_START 0x61 +#define KCS_CMD_WRITE_END 0x62 +#define KCS_CMD_READ_BYTE 0x68 + +static inline u8 read_data(struct kcs_bmc *kcs_bmc) +{ + return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.idr); +} + +static inline void write_data(struct kcs_bmc *kcs_bmc, u8 data) +{ + kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.odr, data); +} + +static inline u8 read_status(struct kcs_bmc *kcs_bmc) +{ + return kcs_bmc->io_inputb(kcs_bmc, kcs_bmc->ioreg.str); +} + +static inline void write_status(struct kcs_bmc *kcs_bmc, u8 data) +{ + kcs_bmc->io_outputb(kcs_bmc, kcs_bmc->ioreg.str, data); +} + +static void update_status_bits(struct kcs_bmc *kcs_bmc, u8 mask, u8 val) +{ + u8 tmp = read_status(kcs_bmc); + + tmp &= ~mask; + tmp |= val & mask; + + write_status(kcs_bmc, tmp); +} + +static inline void set_state(struct kcs_bmc *kcs_bmc, u8 state) +{ + update_status_bits(kcs_bmc, KCS_STATUS_STATE_MASK, + KCS_STATUS_STATE(state)); +} + +static void kcs_force_abort(struct kcs_bmc *kcs_bmc) +{ + set_state(kcs_bmc, ERROR_STATE); + read_data(kcs_bmc); + write_data(kcs_bmc, KCS_ZERO_DATA); + + kcs_bmc->phase = KCS_PHASE_ERROR; + kcs_bmc->data_in_avail = false; + kcs_bmc->data_in_idx = 0; +} + +static void kcs_bmc_handle_data(struct kcs_bmc *k
[Openipmi-developer] [PATCH arm/aspeed/ast2500 v4 2/2] ipmi: add an Aspeed KCS IPMI BMC driver
The KCS (Keyboard Controller Style) interface is used to perform in-band IPMI communication between a server host and its BMC (BaseBoard Management Controllers). This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are commonly used as BMCs and this driver implements the BMC side of the KCS interface. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt| 26 ++ drivers/char/ipmi/Kconfig | 12 + drivers/char/ipmi/Makefile | 1 + drivers/char/ipmi/kcs_bmc_aspeed.c | 319 + 4 files changed, 358 insertions(+) create mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt create mode 100644 drivers/char/ipmi/kcs_bmc_aspeed.c diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt new file mode 100644 index 000..613c34c --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt @@ -0,0 +1,26 @@ +* Aspeed KCS (Keyboard Controller Style) IPMI interface + +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs +(Baseboard Management Controllers) and the KCS interface can be +used to perform in-band IPMI communication with their host. + +Required properties: +- compatible : should be one of +"aspeed,ast2400-kcs-bmc" +"aspeed,ast2500-kcs-bmc" +- interrupts : interrupt generated by the controller +- kcs_chan : The LPC channel number in the controller +- kcs_addr : The host CPU IO map address + + +Example: + +kcs3: kcs3@0 { +compatible = "aspeed,ast2500-kcs-bmc"; +reg = <0x0 0x80>; +interrupts = <8>; +kcs_chan = <3>; +kcs_addr = <0xCA2>; +status = "okay"; +}; + diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index aa9bcb1..770def0 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -104,6 +104,18 @@ config IPMI_KCS_BMC Management Controllers) side for handling the IPMI request from host system software. +config ASPEED_KCS_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + depends on IPMI_KCS_BMC + select REGMAP_MMIO + tristate "Aspeed KCS IPMI BMC driver" + help + Provides a driver for the KCS (Keyboard Controller Style) IPMI + interface found on Aspeed SOCs (AST2400 and AST2500). + + The driver implements the BMC side of the KCS contorller, it + provides the access of KCS IO space for BMC side. + config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST depends on REGMAP && REGMAP_MMIO && MFD_SYSCON diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 2abccb3..21e9e87 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c new file mode 100644 index 000..0c4d1a3 --- /dev/null +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2018, Intel Corporation. + +#define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcs_bmc.h" + + +#define DEVICE_NAME "ast-kcs-bmc" + +#define KCS_CHANNEL_MAX 4 + +/* mapped to lpc-bmc@0 IO space */ +#define LPC_HICR00x000 +#define LPC_HICR0_LPC3E BIT(7) +#define LPC_HICR0_LPC2E BIT(6) +#define LPC_HICR0_LPC1E BIT(5) +#define LPC_HICR20x008 +#define LPC_HICR2_IBFIF3 BIT(3) +#define LPC_HICR2_IBFIF2 BIT(2) +#define LPC_HICR2_IBFIF1 BIT(1) +#define LPC_HICR40x010 +#define LPC_HICR4_LADR12AS BIT(7) +#define LPC_HICR4_KCSENBLBIT(2) +#define LPC_LADR3H 0x014 +#define LPC_LADR3L 0x018 +#define LPC_LADR12H 0x01C +#define LPC_LADR12L 0x020 +#define LPC_IDR1 0x024 +#define LPC_IDR2 0x028 +#define LPC_IDR3 0x02C +#define LPC_ODR1 0x030 +#define LPC_ODR2 0x034 +#define LPC_ODR3 0x038 +#define LPC_STR1 0x03C +#define LPC_STR2 0x040 +#define LPC_STR3 0x044 + +/* mapped to lpc-host@80 IO space */ +#define LPC_HICRB0x080 +#define LPC_HICRB_IBFIF4 BIT(1)
[Openipmi-developer] [PATCH arm/aspeed/ast2500 v3 2/2] ipmi: add an Aspeed KCS IPMI BMC driver
The KCS (Keyboard Controller Style) interface is used to perform in-band IPMI communication between a server host and its BMC (BaseBoard Management Controllers). This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are commonly used as BMCs and this driver implements the BMC side of the KCS interface. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt| 26 ++ drivers/char/ipmi/Kconfig | 12 + drivers/char/ipmi/Makefile | 1 + drivers/char/ipmi/kcs_bmc_aspeed.c | 319 + 4 files changed, 358 insertions(+) create mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt create mode 100644 drivers/char/ipmi/kcs_bmc_aspeed.c diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt new file mode 100644 index 000..613c34c --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt @@ -0,0 +1,26 @@ +* Aspeed KCS (Keyboard Controller Style) IPMI interface + +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs +(Baseboard Management Controllers) and the KCS interface can be +used to perform in-band IPMI communication with their host. + +Required properties: +- compatible : should be one of +"aspeed,ast2400-kcs-bmc" +"aspeed,ast2500-kcs-bmc" +- interrupts : interrupt generated by the controller +- kcs_chan : The LPC channel number in the controller +- kcs_addr : The host CPU IO map address + + +Example: + +kcs3: kcs3@0 { +compatible = "aspeed,ast2500-kcs-bmc"; +reg = <0x0 0x80>; +interrupts = <8>; +kcs_chan = <3>; +kcs_addr = <0xCA2>; +status = "okay"; +}; + diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index aa9bcb1..770def0 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -104,6 +104,18 @@ config IPMI_KCS_BMC Management Controllers) side for handling the IPMI request from host system software. +config ASPEED_KCS_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + depends on IPMI_KCS_BMC + select REGMAP_MMIO + tristate "Aspeed KCS IPMI BMC driver" + help + Provides a driver for the KCS (Keyboard Controller Style) IPMI + interface found on Aspeed SOCs (AST2400 and AST2500). + + The driver implements the BMC side of the KCS contorller, it + provides the access of KCS IO space for BMC side. + config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST depends on REGMAP && REGMAP_MMIO && MFD_SYSCON diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 2abccb3..21e9e87 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c new file mode 100644 index 000..0c4d1a3 --- /dev/null +++ b/drivers/char/ipmi/kcs_bmc_aspeed.c @@ -0,0 +1,319 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2018, Intel Corporation. + +#define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcs_bmc.h" + + +#define DEVICE_NAME "ast-kcs-bmc" + +#define KCS_CHANNEL_MAX 4 + +/* mapped to lpc-bmc@0 IO space */ +#define LPC_HICR00x000 +#define LPC_HICR0_LPC3E BIT(7) +#define LPC_HICR0_LPC2E BIT(6) +#define LPC_HICR0_LPC1E BIT(5) +#define LPC_HICR20x008 +#define LPC_HICR2_IBFIF3 BIT(3) +#define LPC_HICR2_IBFIF2 BIT(2) +#define LPC_HICR2_IBFIF1 BIT(1) +#define LPC_HICR40x010 +#define LPC_HICR4_LADR12AS BIT(7) +#define LPC_HICR4_KCSENBLBIT(2) +#define LPC_LADR3H 0x014 +#define LPC_LADR3L 0x018 +#define LPC_LADR12H 0x01C +#define LPC_LADR12L 0x020 +#define LPC_IDR1 0x024 +#define LPC_IDR2 0x028 +#define LPC_IDR3 0x02C +#define LPC_ODR1 0x030 +#define LPC_ODR2 0x034 +#define LPC_ODR3 0x038 +#define LPC_STR1 0x03C +#define LPC_STR2 0x040 +#define LPC_STR3 0x044 + +/* mapped to lpc-host@80 IO space */ +#define LPC_HICRB0x080 +#define LPC_HICRB_IBFIF4 BIT(1)
[Openipmi-developer] [PATCH arm/aspeed/ast2500 v2] ipmi: add an Aspeed KCS IPMI BMC driver
The KCS (Keyboard Controller Style) interface is used to perform in-band IPMI communication between a server host and its BMC (BaseBoard Management Controllers). This driver exposes the KCS interface on ASpeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are commonly used as BMCs and this driver implements the BMC side of the KCS interface. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- v1->v2 - Divide the driver into two parts, one handles the BMC KCS IPMI 2.0 state; the other handles the BMC KCS controller such as AST2500 IO accessing. - Use the spin lock APIs to handle the device file operations and BMC chip IRQ inferface for accessing the same KCS BMC data structure. - Enhanced the phases handling of the KCS BMC. - Unified the IOCTL definition for IPMI BMC, it will be used by KCS and BT. --- .../devicetree/bindings/ipmi/aspeed-kcs-bmc.txt| 26 ++ drivers/char/ipmi/Kconfig | 20 + drivers/char/ipmi/Makefile | 2 + drivers/char/ipmi/kcs_bmc.c| 430 + drivers/char/ipmi/kcs_bmc.h| 88 + drivers/char/ipmi/kcs_bmc_aspeed.c | 319 +++ include/uapi/linux/ipmi_bmc.h | 14 + 7 files changed, 899 insertions(+) create mode 100644 Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt create mode 100644 drivers/char/ipmi/kcs_bmc.c create mode 100644 drivers/char/ipmi/kcs_bmc.h create mode 100644 drivers/char/ipmi/kcs_bmc_aspeed.c create mode 100644 include/uapi/linux/ipmi_bmc.h diff --git a/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt new file mode 100644 index 000..613c34c --- /dev/null +++ b/Documentation/devicetree/bindings/ipmi/aspeed-kcs-bmc.txt @@ -0,0 +1,26 @@ +* Aspeed KCS (Keyboard Controller Style) IPMI interface + +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs +(Baseboard Management Controllers) and the KCS interface can be +used to perform in-band IPMI communication with their host. + +Required properties: +- compatible : should be one of +"aspeed,ast2400-kcs-bmc" +"aspeed,ast2500-kcs-bmc" +- interrupts : interrupt generated by the controller +- kcs_chan : The LPC channel number in the controller +- kcs_addr : The host CPU IO map address + + +Example: + +kcs3: kcs3@0 { +compatible = "aspeed,ast2500-kcs-bmc"; +reg = <0x0 0x80>; +interrupts = <8>; +kcs_chan = <3>; +kcs_addr = <0xCA2>; +status = "okay"; +}; + diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 3544abc..770def0 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -96,6 +96,26 @@ config IPMI_POWEROFF endif # IPMI_HANDLER +config IPMI_KCS_BMC + tristate 'IPMI KCS BMC Interface' + help + Provides a device driver for the KCS (Keyboard Controller Style) + IPMI interface which meets the requirement of the BMC (Baseboard + Management Controllers) side for handling the IPMI request from + host system software. + +config ASPEED_KCS_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST + depends on IPMI_KCS_BMC + select REGMAP_MMIO + tristate "Aspeed KCS IPMI BMC driver" + help + Provides a driver for the KCS (Keyboard Controller Style) IPMI + interface found on Aspeed SOCs (AST2400 and AST2500). + + The driver implements the BMC side of the KCS contorller, it + provides the access of KCS IO space for BMC side. + config ASPEED_BT_IPMI_BMC depends on ARCH_ASPEED || COMPILE_TEST depends on REGMAP && REGMAP_MMIO && MFD_SYSCON diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 33b899f..10c591a 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -21,4 +21,6 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o +obj-$(CONFIG_IPMI_KCS_BMC) += kcs_bmc.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o \ No newline at end of file diff --git a/drivers/char/ipmi/kcs_bmc.c b/drivers/char/ipmi/kcs_bmc.c new file mode 100644 index 000..4ef3c0b --- /dev/null +++ b/drivers/char/ipmi/kcs_bmc.c @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2018, Intel Corporation. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcs_bmc.h" + +#define KCS_MSG_BUFSIZ1024 + +#define KCS_ZERO_DATA 0 + + +/* IPMI 2.0 - Table 9-1, KCS Interface Status Register Bits */ +#define KCS_STATUS_STATE(state) (state
Re: [Openipmi-developer] [PATCH linux ipmi for BMC] ipmi: add an Aspeed KCS IPMI BMC driver
I can help to maintain this code. :-) This basic KCS code is running successfully about two years on our boards, which uses AST2500 and linux-3.18. For openbmc project, I kept the KCS function and ported it with linux-4.10 new API like bt-bmc.c. It works well in our board with openbmc project. - haiyue -Original Message- From: Corey Minyard [mailto:tcminy...@gmail.com] On Behalf Of Corey Minyard Sent: Friday, December 15, 2017 21:06 To: Haiyue Wang <haiyue.w...@linux.intel.com>; openipmi-developer@lists.sourceforge.net; linux-ker...@vger.kernel.org; 'Cédric Le Goater' <c...@kaod.org>; 'Jeremy Kerr' <j...@ozlabs.org>; 'Joel Stanley' <j...@jms.id.au>; 'Andrew Jeffery' <and...@aj.id.au> Subject: Re: [PATCH linux ipmi for BMC] ipmi: add an Aspeed KCS IPMI BMC driver On 12/14/2017 09:07 PM, Haiyue Wang wrote: > Thanks Corey, yes, I ran through checkpatch. Fix most of warnings and > errors. I thought 2 and 3 would be acceptable, will fix it in new patch,and > together with fix for comments from all of you. And how to fix item 1 ? > > 1. WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? > #115: > new file mode 100644 Are you planning to be maintainer of this code? Does it fall to others in the openbmc project? I technically maintain the files in that directory, but I can't really maintain these files. This comment is asking you to think about that issue. -corey > 2. WARNING: Prefer using '"%s...", __func__' to using 'kcs_inb', this > function's name, in a string > #289: FILE: drivers/char/ipmi/kcs-bmc.c:170: > + WARN(rc != 0, "kcs_inb failed: %d\n", rc); > > 3. WARNING: Prefer using '"%s...", __func__' to using 'kcs_outb', this > function's name, in a string > #299: FILE: drivers/char/ipmi/kcs-bmc.c:180: > + WARN(rc != 0, "kcs_outb failed: %d\n", rc); > > total: 0 errors, 3 warnings, 836 lines checked > > > -Original Message- > From: Corey Minyard [mailto:tcminy...@gmail.com] On Behalf Of Corey > Minyard > Sent: Friday, December 15, 2017 10:31 > To: Haiyue Wang <haiyue.w...@linux.intel.com>; > openipmi-developer@lists.sourceforge.net; > linux-ker...@vger.kernel.org; Cédric Le Goater <c...@kaod.org>; Jeremy > Kerr <j...@ozlabs.org>; Joel Stanley <j...@jms.id.au>; Andrew Jeffery > <and...@aj.id.au> > Subject: Re: [PATCH linux ipmi for BMC] ipmi: add an Aspeed KCS IPMI > BMC driver > > On 12/14/2017 08:03 PM, Haiyue Wang wrote: >> [based torvalds/linux.git] >> >> This patch adds a simple device driver to expose the KCS interface on >> Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs >> are commonly used as BMCs (BaseBoard Management Controllers) and this >> driver implements the BMC side of the KCS interface. >> >> The KCS (Keyboard Controller Style) interface is used to perform >> in-band IPMI communication between a host and its BMC. >> >> The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4. > Did you run this through checkpatch? I saw a few things. > > I was hoping to see some of the openbmc people comment on this. > > -corey > >> Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> >> --- >>.../devicetree/bindings/mfd/aspeed-lpc.txt | 31 +- >>drivers/char/ipmi/Kconfig | 9 + >>drivers/char/ipmi/Makefile | 1 + >>drivers/char/ipmi/kcs-bmc.c| 759 >> + >>include/uapi/linux/kcs-bmc.h | 13 + >>5 files changed, 810 insertions(+), 3 deletions(-) >>create mode 100644 drivers/char/ipmi/kcs-bmc.c >>create mode 100644 include/uapi/linux/kcs-bmc.h >> >> diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt >> b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt >> index 514d82c..e682000 100644 >> --- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt >> +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt >> @@ -62,12 +62,24 @@ BMC Node >> >> >>- compatible: One of: >> -"aspeed,ast2400-lpc-bmc" >> -"aspeed,ast2500-lpc-bmc" >> +"aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon" >> +"aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon" >> >>- reg:contains the physical address and length values of the >>H8S/2168-compatible LPC controller memory region >> >> +BMC KCS Node >> +-
[Openipmi-developer] [PATCH linux dev-4.10 2/2] ipmi: add the KCS nodes into AST2500 device tree
Add kcs1, kcs2, kcs3 into mfd node 'lpc-bmc@0', and add kcs4 into mfd node 'lpc-host@80'. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- arch/arm/boot/dts/aspeed-g5.dtsi | 42 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index ba3607c..5d67f55 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -135,8 +135,39 @@ ranges = <0x0 0x1e789000 0x1000>; lpc_bmc: lpc-bmc@0 { - compatible = "aspeed,ast2500-lpc-bmc"; + compatible = "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"; reg = <0x0 0x80>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x80>; + + kcs1: kcs1@0 { + compatible = "aspeed,ast2500-kcs-bmc"; + reg = <0x0 0x80>; + interrupts = <8>; + kcs_chan = <1>; + kcs_addr = <0x0>; + status = "disabled"; + }; + + kcs2: kcs2@0 { + compatible = "aspeed,ast2500-kcs-bmc"; + reg = <0x0 0x80>; + interrupts = <8>; + kcs_chan = <2>; + kcs_addr = <0x0>; + status = "disabled"; + }; + + kcs3: kcs3@0 { + compatible = "aspeed,ast2500-kcs-bmc"; + reg = <0x0 0x80>; + interrupts = <8>; + kcs_chan = <3>; + kcs_addr = <0x0>; + status = "disabled"; + }; }; lpc_host: lpc-host@80 { @@ -148,9 +179,12 @@ #size-cells = <1>; ranges = <0x0 0x80 0x1e0>; - lpc_ctrl: lpc-ctrl@0 { - compatible = "aspeed,ast2500-lpc-ctrl"; - reg = <0x0 0x80>; + kcs4: kcs4@0 { + compatible = "aspeed,ast2500-kcs-bmc"; + reg = <0x0 0xa0>; + interrupts = <8>; + kcs_chan = <4>; + kcs_addr = <0x0>; status = "disabled"; }; -- 2.7.4 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Openipmi-developer mailing list Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer
[Openipmi-developer] [PATCH linux dev-4.10 1/2] ipmi: add an Aspeed KCS IPMI BMC driver
This patch adds a simple device driver to expose the KCS interface on Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are commonly used as BMCs (BaseBoard Management Controllers) and this driver implements the BMC side of the KCS interface. The KCS (Keyboard Controller Style) interface is used to perform in-band IPMI communication between a host and its BMC. The device name defaults to '/dev/ipmi-kcsX', X=1,2,3,4. Signed-off-by: Haiyue Wang <haiyue.w...@linux.intel.com> --- .../devicetree/bindings/mfd/aspeed-lpc.txt | 31 +- drivers/char/ipmi/Kconfig | 9 + drivers/char/ipmi/Makefile | 1 + drivers/char/ipmi/kcs-bmc.c| 759 + include/uapi/linux/kcs-bmc.h | 13 + 5 files changed, 810 insertions(+), 3 deletions(-) create mode 100644 drivers/char/ipmi/kcs-bmc.c create mode 100644 include/uapi/linux/kcs-bmc.h diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt index a97131a..ed4d796 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt @@ -62,12 +62,24 @@ BMC Node - compatible: One of: - "aspeed,ast2400-lpc-bmc" - "aspeed,ast2500-lpc-bmc" + "aspeed,ast2400-lpc-bmc", "simple-mfd", "syscon" + "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon" - reg: contains the physical address and length values of the H8S/2168-compatible LPC controller memory region +BMC KCS Node + + +- compatible: One of: + "aspeed,ast2400-kcs-bmc" + "aspeed,ast2500-kcs-bmc" + +- kcs_chan: The LPC channel number + +- kcs_addr: The host CPU IO map address + + Host Node - @@ -94,8 +106,21 @@ lpc: lpc@1e789000 { ranges = <0x0 0x1e789000 0x1000>; lpc_bmc: lpc-bmc@0 { - compatible = "aspeed,ast2500-lpc-bmc"; + compatible = "aspeed,ast2500-lpc-bmc", "simple-mfd", "syscon"; reg = <0x0 0x80>; + reg-io-width = <4>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x80>; + + kcs3: kcs3@0 { + compatible = "aspeed,ast2500-kcs-bmc"; + interrupts = <8>; + kcs_chan = <3>; + kcs_addr = <0xCA2>; + status = "okay"; + }; }; lpc_host: lpc-host@80 { diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 90f3edf..daa6dfc 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -85,3 +85,12 @@ config ASPEED_BT_IPMI_BMC Provides a driver for the BT (Block Transfer) IPMI interface found on Aspeed SOCs (AST2400 and AST2500). The driver implements the BMC side of the BT interface. + +config ASPEED_KCS_IPMI_BMC + depends on ARCH_ASPEED || COMPILE_TEST +depends on REGMAP && REGMAP_MMIO && MFD_SYSCON + tristate "KCS IPMI bmc driver" + help + Provides a driver for the KCS (Keyboard Controller Style) IPMI + interface found on Aspeed SOCs (AST2400 and AST2500). The driver + implements the BMC side of the KCS interface. \ No newline at end of file diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 0d98cd9..35272a7 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o +obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs-bmc.o \ No newline at end of file diff --git a/drivers/char/ipmi/kcs-bmc.c b/drivers/char/ipmi/kcs-bmc.c new file mode 100644 index 000..bcbd2d6 --- /dev/null +++ b/drivers/char/ipmi/kcs-bmc.c @@ -0,0 +1,759 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2015-2017, Intel Corporation. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KCS_MSG_BUFSIZ 1024 +#define KCS_CHANNEL_MAX 4 + +/* + * This is a BMC device used to communicate to the host + */ +#define DEVICE_NAME "ipmi-kcs-host" + + +/* Different Phases of the KCS Module */ +#define KCS_PHASE_IDLE 0x00 +#define KCS_PHASE_WRITE 0x01 +#define KCS_PHASE_WRITE_END 0x02 +#define KCS_PHASE_READ 0x03 +#define