【Note10】spi

文章目录


# Makefile
obj-m := gpiodrv.o
KERNELDIR ?= /home_a/yutao/alibmc/build/tmp/work/obmc_hq-fb-linux-gnueabi/linux-aspeed/4.1.51-r1/build #/usr/lib/modules/5.10.7/build

PWD ?= $(shell pwd)

all:
	make -C $(KERNELDIR) M=$(PWD) modules
	rm -f *.o *.symvers *.order *.mod.* *.ko.*
clean:
	make -C $(KERNELDIR) M=$(PWD) clean
	rm -f *.o *.ko *.symvers *.order *.mod.* *.ko.*
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define CREATE_TRACE_POINTS
#include 

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 


#include 
#include 
#include 
#include 

/*
GPIO Community定义 --5602M
#define PID_GPIOCOM0   0x6E
#define PID_GPIOCOM1   0x6D
#define PID_GPIOCOM2   0x6C
#define PID_GPIOCOM3   0x6B
#define PID_GPIOCOM4   0x6A
#define PID_GPIOCOM5   0x69
地址运算转换
#define PCH_PCR_ADDRESS(Pid, Offset)    (PCH_PCR_BASE_ADDRESS | (UINT32) (((Offset) & 0x0F0000) << 8) | ((UINT8)(Pid) << 16) | (UINT16) ((Offset) & 0xFFFF))
PCH_PCR_BASE_ADDRESS获取
可以用fixed地址
#define PCH_PCR_BASE_ADDRESS            0xFD000000     ///< SBREG MMIO base address
*/
/*  
GPIO Community定义  --5606
#define  PID_GPIOCOM0                           0xAF
#define  PID_GPIOCOM1                           0xAE
#define  PID_GPIOCOM2                           0xAD
#define  PID_GPIOCOM3                           0xAC
#define  PID_GPIOCOM4                           0xAB
#define  PID_GPIOCOM5                           0x11
地址运算转换
#define PCH_PCR_ADDRESS(Pid, Offset)    (PCH_PCR_BASE_ADDRESS | (UINT32) (((Offset) & 0x0F0000) << 8) | ((UINT8)(Pid) << 16) | (UINT16) ((Offset) & 0xFFFF))
PCH_PCR_ADDRESS获取
可以用fixed地址
#define PCH_PCR_BASE_ADDRESS            0xFD000000     ///< SBREG MMIO base address
*/
/*
enum umh_wait {

          UMH_NO_WAIT = -1,       // don't wait at all 

          UMH_WAIT_EXEC = 0,     // wait for the exec, but not the process 

          UMH_WAIT_PROC = 1,      // wait for the process to complete 

};
*/

#define NMI_ADDRESS  0xfd6d0000

#define NMI_READ    0x864

void __iomem *io_mem;


#define CMD_CRASH_DUMP          "/usr/local/bin/log.sh"
/*
//static int read_gpio_level(uint32_t pin_addr, uint32_t a_ucpins)
static int read_gpio_level_huaqin(void)
{
    uint32_t ret = 0;
    int value = -1;
    unsigned long io_base;

    io_base = (unsigned long) ioport_map(pin_addr, 1);
    if (!io_base) {
        printk(KERN_ERR "Failed to map GPIO %x to memory\n", pin_addr);
        return -1;
    }
    //iounmap(io_mem);
    // printk(KERN_INFO "read_gpio_level %d  - %d \n",ret,io_mem); 
    return ret;
}
*/
static struct workqueue_struct *g_mca_wq = NULL;
static struct work_struct g_mca_dwq;


static void read_log(struct work_struct *work)
{
    char cmd_path[] = CMD_CRASH_DUMP;
    char *cmd_argv[] = {cmd_path, NULL, NULL};
    char *cmd_envp[] = {NULL};

    printk(KERN_INFO "into read NMI\n");
    call_usermodehelper(cmd_path, cmd_argv, cmd_envp, UMH_WAIT_PROC);
}

static int Handling_functions(unsigned int cmd, struct pt_regs *regs)
{
    /*
    int value;
    value = ioread32(io_mem + NMI_READ);
    printk(KERN_INFO "Read NMI STATUS %x\n",value);
    */

    printk(KERN_INFO "Handing NMI\n");

    queue_work(g_mca_wq, &g_mca_dwq);

	// return NMI_HANDLED;
    return NMI_DONE;
}

static int register_nmi_handler_Processing(void)
{

    //register_nmi_handler(NMI_LOCAL,Handling_functions,0,"nmi_handler");

    register_nmi_handler(NMI_UNKNOWN,Handling_functions,0,"nmi_handler");
 
    return 0;
}

static int __init nmi_init_huaqin(void)
{

    int ret;

    io_mem = ioremap(NMI_ADDRESS,0x1000);
    if (!io_mem) {
            printk(KERN_ERR "Failed to map GPIO %p to memory\n", io_mem);
            return -1;
    }

    ret = register_nmi_handler_Processing();
    if (ret) {
        return ret;
    } 

    g_mca_wq = create_workqueue("Nmi workqueue");
    if (g_mca_wq == NULL) {
        printk(KERN_ERR "%s: error creating CPU error workqueue\n", __func__);
        return -1;
    }

    INIT_WORK(&g_mca_dwq, read_log);

    printk(KERN_INFO "loaded NMI_test successfully\n");

    return 0;
}

static void __exit nmi_exit_huaqin(void)
{
    //unregister_nmi_handler(NMI_LOCAL, "nmi_handler");

    unregister_nmi_handler(NMI_UNKNOWN, "nmi_handler");

    destroy_workqueue(g_mca_wq);

    iounmap(io_mem);

    printk(KERN_INFO "unloaded NMI_test successfully\n");
}

module_init(nmi_init_huaqin);
module_exit(nmi_exit_huaqin);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robin.Zhao");
MODULE_DESCRIPTION("NMI handler driver");

你可能感兴趣的:(Notes,linux,驱动开发)