mao0504 发表于 2021-3-31 19:52:34

如何修改一个被占用的管脚,将其修改为普通gpio

评估板的F11_VOUT1_D0信号被用作了屏线的vd0_b0, 我们新设计的板子把这个管脚用作普通的GPIO去控制一个芯片,设备树里面没有找到F11_VOUT1_D0管脚的信息,GPIO8 0,地址0x4A0035dc等信息,

我在设备树里添加了新的节点,代码如下。
写了一个新的驱动,通过insmod安装,demoApp设置这个GPIO的高低变化,可以安装,应用的时候会报错,错误内容见后面的表格;
如果管脚设置为led7 ,CTRL_CORE_PAD_MCASP2_AXR2,GPIO6_8,同样的方法、流程就没有问题,可以控制led7的闪烁。


请问我还有做什么吗?






mygpio56 {
                pinctrl-names = "default";
                pinctrl-0 = <&mygpio56_user_gpio>;
                status = "okay";
                  compatible = "gpio567";
                  mygpio568 {
                               label = "mygpio569";
                               gpios = <&gpio8 0 GPIO_ACTIVE_LOW>;
                  
                            };

               };

mygpio56_user_gpio: mygpio56_user_gpio {
                pinctrl-single,pins = <              
                       DRA7XX_CORE_IOPAD(0x35dc, MUX_MODE14 | PIN_OUTPUT_PULLUP) /* gpio8-0 spi */
                >;
        };报错内容:

------------[ cut here ]------------
WARNING: CPU: 0 PID: 1330 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x25c/0x36c
44000000.ocp:L3 Custom Error: MASTER MPU TARGET L4_PER1_P3 (Read): Data Access in User mode during Functional access
Modules linked in: mygpio567(O) sha512_generic sha512_arm sha256_generic sha1_generic sha1_arm_neon sha1_arm md5 cbc xfrm_user xfrm4_tunnel ipcomp xfrm_ipcomp esp4 ah4 af_key xfrm_algo rfcomm bc_example(O) wlan btusb btrtl btbcm btintel xhci_plat_hcd pru_rproc pruss_intc xhci_hcd rpmsg_proto pruss bluetooth dwc3 udc_core rpmsg_rpc snd_soc_**_card snd_soc_**_card_utils pwm_fan snd_soc_omap_hdmi_audio pvrsrvkm(O) omap_aes_driver c_can_platform c_can omap_sham pruss_soc_bus can_dev omap_wdt ahci_platform libahci_platform libahci libata scsi_mod ti_vip ti_vpe ti_sc ti_csc ti_vpdma dwc3_omap extcon_core w1_therm ti_cal gpio_pisosr rtc_rx8010 ov5640_mipi omap_des ov5640 snd_soc_wm8960 omap_hdq wire spidev des_generic crypto_engine omap_remoteproc virtio_rpmsg_bus rpmsg_core remoteproc sch_fq_codel xr_usb_serial_common usbcore usb_common uio_module_drv(O) uio gdbserverproxy(O) cryptodev(O) cmemk(O)
CPU: 0 PID: 1330 Comm: hello Tainted: G      D WO    4.9.41 #29
Hardware name: Generic DRA72X (Flattened Device Tree)
Backtrace:
[<c020b2d8>] (dump_backtrace) from [<c020b594>] (show_stack+0x18/0x1c)
r7:00000009 r6:60070193 r5:00000000 r4:c10229d0
[<c020b57c>] (show_stack) from [<c04ace60>] (dump_stack+0x8c/0xa0)
[<c04acdd4>] (dump_stack) from [<c022e4b8>] (__warn+0xec/0x104)
r7:00000009 r6:c0bcd6e0 r5:00000000 r4:ee413b40
[<c022e3cc>] (__warn) from [<c022e510>] (warn_slowpath_fmt+0x40/0x48)
r9:00000006 r8:ef1dd2d0 r7:c0bcd54c r6:00000002 r5:c0bcd60c r4:c0bcd6b0
[<c022e4d4>] (warn_slowpath_fmt) from [<c04dcd10>] (l3_interrupt_handler+0x25c/0x36c)
r3:ef1dd140 r2:c0bcd6b0
r4:80080003
[<c04dcab4>] (l3_interrupt_handler) from [<c027fd20>] (__handle_irq_event_percpu+0xb4/0x138)
r10:c101a4af r9:ef1d1200 r8:00000017 r7:ee413c64 r6:00000000 r5:ef1d1200
r4:ef1dd640
[<c027fc6c>] (__handle_irq_event_percpu) from [<c027fdc8>] (handle_irq_event_percpu+0x24/0x60)
r10:bf545360 r9:ee412000 r8:ef006000 r7:00000000 r6:c1008c34 r5:ef1d1200
r4:ef1d1200
[<c027fda4>] (handle_irq_event_percpu) from [<c027fe44>] (handle_irq_event+0x40/0x64)
r5:ef1d1260 r4:ef1d1200
[<c027fe04>] (handle_irq_event) from [<c02834f0>] (handle_fasteoi_irq+0xc0/0x190)
r7:00000000 r6:c1008c34 r5:ef1d1260 r4:ef1d1200
[<c0283430>] (handle_fasteoi_irq) from [<c027ef48>] (generic_handle_irq+0x2c/0x3c)
r7:00000000 r6:00000000 r5:00000017 r4:c0e5cde0
[<c027ef1c>] (generic_handle_irq) from [<c027f4d0>] (__handle_domain_irq+0x64/0xbc)
[<c027f46c>] (__handle_domain_irq) from [<c02014a0>] (gic_handle_irq+0x40/0x7c)
r9:ee412000 r8:fa213000 r7:fa212000 r6:ee413d20 r5:fa21200c r4:c1003424
[<c0201460>] (gic_handle_irq) from [<c020c138>] (__irq_svc+0x58/0x8c)
Exception stack(0xee413d20 to 0xee413d68)
3d20: 00000000 fa053000 00000001 bf5459c0 bf545770 c103408c 00000038 c1034074
3d40: ee1a9b40 ed31d360 bf545360 ee413d7c ee413c30 ee413d70 c02c0f18 bf545054
3d60: 60070013 ffffffff
r9:ee412000 r8:ee1a9b40 r7:ee413d54 r6:ffffffff r5:60070013 r4:bf545054
[<bf545020>] (mygpio_open ) from [<c05921bc>] (misc_open+0x15c/0x174)
[<c0592060>] (misc_open) from [<c0333fc0>] (chrdev_open+0xac/0x190)
r10:ee1a9b40 r9:ee413ea8 r8:ef342300 r7:ee1a9b40 r6:ed31d360 r5:ef342300
r4:c0a3ec80 r3:c0592060
[<c0333f14>] (chrdev_open) from [<c032d164>] (do_dentry_open.constprop.3+0x1ec/0x314)
r8:ee413f5c r7:c0333f14 r6:ee1a9b48 r5:ed31d360 r4:ee1a9b40
[<c032cf78>] (do_dentry_open.constprop.3) from [<c032e0a4>] (vfs_open+0x48/0x78)
r9:ee413ea8 r8:ee413f5c r7:eec023b8 r6:00000002 r5:ee1a9b40 r4:ee413ea8
[<c032e05c>] (vfs_open) from [<c033d1f4>] (path_openat+0x344/0xefc)
r5:00000000 r4:00000000
[<c033ceb0>] (path_openat) from [<c033f134>] (do_filp_open+0x6c/0xd0)
r10:00000000 r9:ee412000 r8:c0207d84 r7:00000001 r6:ee413f5c r5:ee413ea8
r4:00000003
[<c033f0c8>] (do_filp_open) from [<c032e458>] (do_sys_open+0x11c/0x1cc)
r7:fffff000 r6:ed384000 r5:ffffff9c r4:00000003
[<c032e33c>] (do_sys_open) from [<c032e528>] (SyS_open+0x20/0x24)
r9:ee412000 r8:c0207d84 r7:00000005 r6:00000000 r5:00000000 r4:be9d3b38
[<c032e508>] (SyS_open) from [<c0207be0>] (ret_fast_syscall+0x0/0x34)
---[ end trace 7e2b11ee0c31fa61 ]---
Unhandled fault: asynchronous external abort (0x1211) at 0x00000000
pgd = ee070680
*pgd=9fa38003, *pmd=00000000
systemd: systemd-journald.service: Failed with result 'core-dump'.
systemd: systemd-journald.service: Service has no hold-off time, scheduling restart.
systemd: Stopped Flush Journal to Persistent Storage.
systemd: Stopping Flush Journal to Persistent Storage...
systemd: Stopped Journal Service.
systemd: Starting Journal Service...
systemd-journald: File /run/log/journal/b9d28430c5bb428b8c75daa70d99e56a/system.journal corrupted or uncleanly shut down, renaming and replacing.
驱动源码:
#include <linux/slab.h>

#include <linux/device.h>

#include <linux/miscdevice.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <linux/fb.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <generated/autoconf.h>

#include <linux/platform_device.h>

#include <linux/fs.h>

#include <linux/ioctl.h>

#include <linux/types.h>

#include <linux/spinlock.h>

#include <linux/cdev.h>

#include <linux/of.h>

#include <asm/uaccess.h>

#include <asm/io.h>

#include <asm/atomic.h>



//#include "mt-plat/mtgpio.h"

#include <linux/types.h>

//#include <mt-plat/mt_gpio.h>

//#include <mt-plat/mt_gpio_core.h>

//#include <mach/gpio_const.h>



/* 生命函数定义 */

static int mygpio_probe(struct platform_device *pdev);

static int mygpio_remove(struct platform_device *pdev);





static const struct of_device_id mygpio_of_match[] = {

        { .compatible = "gpio567", },

        {},

};



static struct platform_driver mygpio_driver = {

        .remove = mygpio_remove,

        .probe = mygpio_probe,

        .driver = {

                        .name = "myGPIO",

                        .owner = THIS_MODULE,

                        .of_match_table = mygpio_of_match,

        },

};





#define GPIO_MUX_ADDR               0x4A0035dc

#define GPIO6_BASE_ADDR             0x48053000

#define GPIO_PIN_INDEX            0



#define GPIO_OE_OFFSET            0x134

#define GPIO_CLRDATAOUT_OFFSET      0x190

#define GPIO_SETDATAOUT_OFFSET      0x194

u32 reg_vir_addr;

static void config_gpio_muxmode(void)

{

    u32 reg_vir;

    printk("my_dev_muxmode\n");

   reg_vir = (u32)ioremap_nocache(GPIO_MUX_ADDR, 0x20);

   if (!reg_vir) {

        printk(": ctrl register remapping failed");                       

    }

    //__raw_writel(0xE, reg_vir +0);

    *(unsigned int *)(reg_vir)= 0x0e;//gpio



    iounmap((void *)reg_vir);

//



}



static int mygpio_open(struct inode *inode, struct file *file)

{

        printk("MyGPIO OPen. \r\n");

        (*( unsigned int *)(reg_vir_addr + GPIO_CLRDATAOUT_OFFSET)) |= 1 << GPIO_PIN_INDEX;

      (*( unsigned int *)(reg_vir_addr + GPIO_OE_OFFSET)) &= ~(1<<GPIO_PIN_INDEX);

      (*( unsigned int *)(reg_vir_addr + GPIO_SETDATAOUT_OFFSET)) |= 1 << GPIO_PIN_INDEX;

        return 0;

}



static ssize_t my_dev_write(struct file *file,const char __user *buf,size_t count,loff_t *offset)

{

#if 0

        int ret;

        ret = copy_from_user(&val,buf,count);

        if(ret<0)

        {

                printk("ret=%d\n",ret);

                return ret;

        }

        printk("my_dev_read\n");

       

        return 0;

#endif

        int ret,val;

        char temp;

        char status=0;

        memset(temp,0,16);



        ret=copy_from_user(temp,buf,count);

        if(ret<0)

        {

                printk("ret=%d\n",ret);

                status=-EFAULT;

                goto err;

        }

        val=**_strtoul(temp,NULL,0);

        if(val >= 1)

      {

            *( unsigned int *)(reg_vir_addr + GPIO_SETDATAOUT_OFFSET) |= 1 << GPIO_PIN_INDEX;

                //gpio_set_value(gpio_led_pin,1);

      }

        else

      {

             *( unsigned int *)(reg_vir_addr + GPIO_CLRDATAOUT_OFFSET)|= 1 << GPIO_PIN_INDEX;

                //gpio_set_value(gpio_led_pin,0);       

         }



        if(!status)

                status = count;

err:

        return status;

}



static int mygpio_release(struct inode *inode, struct file *file)

{

        printk("MyGPIO Release. \r\n");

       

        return 0;

}



static long mygpio_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

        printk("MyGPIO Ioctl. \r\n");

       

        printk("MyGPIO cmd=%d \r\n", cmd);

       

        return 0;

}



static const struct file_operations mygpio_fops = {

/* .owner = THIS_MODULE, */

        .open = mygpio_open,

      .write        =my_dev_write,

        .release = mygpio_release,

        .unlocked_ioctl = mygpio_unlocked_ioctl,

};





static struct miscdevice mygpio_device = {

        .minor = MISC_DYNAMIC_MINOR,                //动态设备号

        .name = "myGPIO",

        .fops = &mygpio_fops,

};







/* My GPIO probe */

static int mygpio_probe(struct platform_device *pdev)

{//

        int ret = 0;

      unsigned int outvalue;

       

        printk("MyGPIO Probe. \r\n");

       

        ret = misc_register(&mygpio_device);

        if (ret != 0 )

                printk("myGPIO: mygpio_device register failed\n");

       

         struct device_node *dn;

         //1.通过节点名字查找指定的节点驱动程序里面调用of_get_address,提示没有?

         dn = of_find_node_by_name(NULL,"mygpio56");

         if(dn==NULL)

         {

            printk("of_find_node_by_name err \r\n");

         }

         else

         {

                  //of_find_node_by_name :mygpio56 /mygpio56 <NULL> mygpio568compatible

         //   printk("of_find_node_by_name :%s %s %s%s %s %s\r\n",dn->name,dn->full_name,dn->type,dn->child->name,dn->properties->name, dn->properties->next->name);



                of_property_read_u32_array(dn->child,dn->child->properties->next->name,outvalue,3);

                //读取属性中 u8、 u16、 u32 和 u64 类型的数组数据,比如大多数的 reg 属性都是数组数据



               printk("%s {\n",dn->name);

               printk("      %s = \" %s \" ;\n",dn->properties->name,dn->properties->value);

               printk("      %s = \" %s \" ;\n",dn->properties->next->name,dn->properties->next->value);

               printk("         %s {\n",dn->child->name);

               printk("         %s = \" %s \" ;\n",dn->child->properties->name,dn->child->properties->value);         

               printk("         %s = < %x %x %x > ;\n",dn->child->properties->next->name,outvalue,outvalue,outvalue);

               printk("};\n};\n");

         }

   ///    u64 size; unsigned int flags;

       //unsigned int *addr;

      //   addr = of_get_address(dn->child, 0, size, flags);

         //of_translate_address(dn->child, const __be32 *in_addr);

         //2. 通过 device_type 属性查找指定的节点,节点对应的 type 字符串,也就是 device_type 属性值。

         //struct device_node *of_find_node_by_type(struct device_node *from, const char *type)

      //3. 根据 device_type 和 compatible 这两个属性查找指定的节点struct device_node *of_find_compatible_node(struct device_node *from,const char *type,const char *compatible)

      //4 通过 of_device_id 匹配表来查找指定的节点struct device_node *of_find_matching_node_and_match(struct device_node *from,const struct of_device_id *matches,const struct of_device_id **match)matches: of_device_id 匹配表,也就是在此匹配表里面查找节点。match: 找到的匹配的 of_device_id。

        return ret;

}





static int mygpio_remove(struct platform_device *pdev)

{

        int err;

       

        printk("MyGPIO remove. \r\n");



       misc_deregister(&mygpio_device);

       

        return err;

}



static int __init my_gpio_init(void)

{

        int ret = 0;

      printk("my_gpio_init. \r\n");

        printk("Register MyGPIO platform_driverinit. \r\n");



      reg_vir_addr = (u32)ioremap_nocache(GPIO6_BASE_ADDR, 0x800);

           if (!reg_vir_addr) {

                printk(": ctrl addr remapping failed");                       

          }



      config_gpio_muxmode();



        ret = platform_driver_register(&mygpio_driver);

        if(ret != 0 )

                printk("unable to register MyGPIO driver.\n");

       

        return ret;

}



/*---------------------------------------------------------------------------*/

static void __exit my_gpio_exit(void)

{

      printk("my_gpio_exit. \r\n");

      iounmap((void *)reg_vir_addr);



        platform_driver_unregister(&mygpio_driver);

}



subsys_initcall(my_gpio_init);

/*module_init(my_gpio_init);*/

module_exit(my_gpio_exit);



MODULE_AUTHOR("zue");

MODULE_DESCRIPTION("MY General Purpose Driver (GPIO)");

MODULE_LICENSE("GPL v2");

/*

insmod newled

my_gpio_init.

MyGPIO Probe.compatible = "gpio567"; 匹配才执行

//

rmmod newled

my_gpio_exit.

MyGPIO remove.



app open-->open

    write-->write

    close--->release





*/

mao0504 发表于 2021-4-1 09:50:27

&gpio8 {
      ti,no-reset-on-init;
};
这种操作不起作用呢,如果起作用,GPIO8对应的是屏显示,屏应该不显示内容才对
页: [1]
查看完整版本: 如何修改一个被占用的管脚,将其修改为普通gpio