Index: head/share/man/man4/Makefile =================================================================== --- head/share/man/man4/Makefile (revision 327198) +++ head/share/man/man4/Makefile (revision 327199) @@ -1,993 +1,994 @@ # @(#)Makefile 8.1 (Berkeley) 6/18/93 # $FreeBSD$ .include PACKAGE=runtime-manuals MAN= aac.4 \ aacraid.4 \ acpi.4 \ ${_acpi_asus.4} \ ${_acpi_asus_wmi.4} \ ${_acpi_dock.4} \ ${_acpi_fujitsu.4} \ ${_acpi_hp.4} \ ${_acpi_ibm.4} \ ${_acpi_panasonic.4} \ ${_acpi_rapidstart.4} \ ${_acpi_sony.4} \ acpi_thermal.4 \ ${_acpi_toshiba.4} \ acpi_video.4 \ ${_acpi_wmi.4} \ ada.4 \ adm6996fc.4 \ adv.4 \ adw.4 \ ae.4 \ ${_aesni.4} \ age.4 \ agp.4 \ aha.4 \ ahc.4 \ ahci.4 \ ahd.4 \ ${_aibs.4} \ aio.4 \ alc.4 \ ale.4 \ alpm.4 \ altera_atse.4 \ altera_avgen.4 \ altera_jtag_uart.4 \ altera_sdcard.4 \ altq.4 \ amdpm.4 \ ${_amdsbwd.4} \ ${_amdsmb.4} \ ${_amdsmn.4} \ ${_amdtemp.4} \ ${_bxe.4} \ amr.4 \ an.4 \ ${_aout.4} \ ${_apic.4} \ arcmsr.4 \ ${_armv8crypto.4} \ ${_asmc.4} \ ata.4 \ ath.4 \ ath_ahb.4 \ ath_hal.4 \ ath_pci.4 \ atkbd.4 \ atkbdc.4 \ atp.4 \ ${_atf_test_case.4} \ ${_atrtc.4} \ ${_attimer.4} \ audit.4 \ auditpipe.4 \ aue.4 \ + aw_gpio.4 \ aw_mmc.4 \ aw_rtc.4 \ axe.4 \ axge.4 \ bce.4 \ bcma.4 \ bfe.4 \ bge.4 \ ${_bhyve.4} \ bhnd.4 \ bhnd_chipc.4 \ bhnd_pmu.4 \ bhndb.4 \ bhndb_pci.4 \ bktr.4 \ blackhole.4 \ bnxt.4 \ bpf.4 \ bridge.4 \ bt.4 \ bwi.4 \ bwn.4 \ ${_bytgpio.4} \ capsicum.4 \ cardbus.4 \ carp.4 \ cas.4 \ cc_cdg.4 \ cc_chd.4 \ cc_cubic.4 \ cc_dctcp.4 \ cc_hd.4 \ cc_htcp.4 \ cc_newreno.4 \ cc_vegas.4 \ ${_ccd.4} \ ccr.4 \ cd.4 \ cdce.4 \ cfi.4 \ cfumass.4 \ ch.4 \ chromebook_platform.4 \ ciss.4 \ cloudabi.4 \ cm.4 \ cmx.4 \ ${_coretemp.4} \ ${_cpuctl.4} \ cpufreq.4 \ crypto.4 \ ctl.4 \ cue.4 \ cxgb.4 \ cxgbe.4 \ cxgbev.4 \ cy.4 \ cyapa.4 \ da.4 \ dc.4 \ dcons.4 \ dcons_crom.4 \ ddb.4 \ de.4 \ devctl.4 \ disc.4 \ divert.4 \ ${_dpms.4} \ dpt.4 \ ds1307.4 \ ds3231.4 \ ${_dtrace_provs} \ dummynet.4 \ ed.4 \ edsc.4 \ ehci.4 \ em.4 \ ena.4 \ enc.4 \ epair.4 \ esp.4 \ est.4 \ et.4 \ etherswitch.4 \ eventtimers.4 \ exca.4 \ e6060sw.4 \ fd.4 \ fdc.4 \ fdt.4 \ fdtbus.4 \ ffclock.4 \ filemon.4 \ firewire.4 \ fpa.4 \ full.4 \ fwe.4 \ fwip.4 \ fwohci.4 \ fxp.4 \ gbde.4 \ gdb.4 \ gem.4 \ geom.4 \ geom_fox.4 \ geom_linux_lvm.4 \ geom_map.4 \ geom_uzip.4 \ gif.4 \ gpio.4 \ gpioiic.4 \ gpioled.4 \ gre.4 \ h_ertt.4 \ hifn.4 \ hme.4 \ hpet.4 \ ${_hpt27xx.4} \ ${_hptiop.4} \ ${_hptmv.4} \ ${_hptnr.4} \ ${_hptrr.4} \ ${_hv_kvp.4} \ ${_hv_netvsc.4} \ ${_hv_storvsc.4} \ ${_hv_utils.4} \ ${_hv_vmbus.4} \ ${_hv_vss.4} \ hwpmc.4 \ ichsmb.4 \ ${_ichwd.4} \ icmp.4 \ icmp6.4 \ ida.4 \ if_ipsec.4 \ ifmib.4 \ ig4.4 \ igmp.4 \ iic.4 \ iicbb.4 \ iicbus.4 \ iicsmb.4 \ iir.4 \ inet.4 \ inet6.4 \ intpm.4 \ intro.4 \ ${_io.4} \ ${_ioat.4} \ ip.4 \ ip6.4 \ ipfirewall.4 \ ipheth.4 \ ${_ipmi.4} \ ips.4 \ ipsec.4 \ ipw.4 \ ipwfw.4 \ isci.4 \ isl.4 \ ismt.4 \ isp.4 \ ispfw.4 \ iwi.4 \ iwifw.4 \ iwm.4 \ iwmfw.4 \ iwn.4 \ iwnfw.4 \ ixgb.4 \ ixgbe.4 \ ixl.4 \ ixlv.4 \ jedec_ts.4 \ jme.4 \ joy.4 \ kbdmux.4 \ keyboard.4 \ kld.4 \ ksyms.4 \ ksz8995ma.4 \ ktr.4 \ kue.4 \ lagg.4 \ le.4 \ led.4 \ lge.4 \ ${_linux.4} \ liquidio.4 \ lm75.4 \ lmc.4 \ lo.4 \ lp.4 \ lpbb.4 \ lpt.4 \ mac.4 \ mac_biba.4 \ mac_bsdextended.4 \ mac_ifoff.4 \ mac_lomac.4 \ mac_mls.4 \ mac_none.4 \ mac_partition.4 \ mac_portacl.4 \ mac_seeotheruids.4 \ mac_stub.4 \ mac_test.4 \ malo.4 \ md.4 \ mdio.4 \ me.4 \ mem.4 \ meteor.4 \ mfi.4 \ miibus.4 \ mk48txx.4 \ mld.4 \ mlx.4 \ mlx4en.4 \ mlx5en.4 \ mly.4 \ mmc.4 \ mmcsd.4 \ mn.4 \ mod_cc.4 \ mos.4 \ mouse.4 \ mpr.4 \ mps.4 \ mpt.4 \ mrsas.4 \ msk.4 \ mtio.4 \ multicast.4 \ mvs.4 \ mwl.4 \ mwlfw.4 \ mxge.4 \ my.4 \ nand.4 \ nandsim.4 \ ncr.4 \ ncv.4 \ ${_ndis.4} \ net80211.4 \ netfpga10g_nf10bmac.4 \ netgraph.4 \ netintro.4 \ netmap.4 \ ${_nfe.4} \ ${_nfsmb.4} \ ng_async.4 \ ngatmbase.4 \ ng_atmllc.4 \ ng_bpf.4 \ ng_bridge.4 \ ng_bt3c.4 \ ng_btsocket.4 \ ng_car.4 \ ng_ccatm.4 \ ng_cisco.4 \ ng_deflate.4 \ ng_device.4 \ nge.4 \ ng_echo.4 \ ng_eiface.4 \ ng_etf.4 \ ng_ether.4 \ ng_ether_echo.4 \ ng_frame_relay.4 \ ng_gif.4 \ ng_gif_demux.4 \ ng_h4.4 \ ng_hci.4 \ ng_hole.4 \ ng_hub.4 \ ng_iface.4 \ ng_ipfw.4 \ ng_ip_input.4 \ ng_ksocket.4 \ ng_l2cap.4 \ ng_l2tp.4 \ ng_lmi.4 \ ng_mppc.4 \ ng_nat.4 \ ng_netflow.4 \ ng_one2many.4 \ ng_patch.4 \ ng_ppp.4 \ ng_pppoe.4 \ ng_pptpgre.4 \ ng_pred1.4 \ ng_rfc1490.4 \ ng_socket.4 \ ng_source.4 \ ng_split.4 \ ng_sppp.4 \ ng_sscfu.4 \ ng_sscop.4 \ ng_tag.4 \ ng_tcpmss.4 \ ng_tee.4 \ ng_tty.4 \ ng_ubt.4 \ ng_UI.4 \ ng_uni.4 \ ng_vjc.4 \ ng_vlan.4 \ nmdm.4 \ nsp.4 \ ${_ntb.4} \ ${_ntb_hw_intel.4} \ ${_ntb_hw_plx.4} \ ${_ntb_transport.4} \ ${_nda.4} \ ${_if_ntb.4} \ null.4 \ numa.4 \ ${_nvd.4} \ ${_nvme.4} \ ${_nvram.4} \ ${_nvram2env.4} \ ${_nxge.4} \ oce.4 \ ohci.4 \ orm.4 \ ow.4 \ ow_temp.4 \ owc.4 \ ${_padlock.4} \ pass.4 \ pccard.4 \ pccbb.4 \ pcf.4 \ pci.4 \ pcib.4 \ pcic.4 \ pcm.4 \ pcn.4 \ ${_pf.4} \ ${_pflog.4} \ ${_pfsync.4} \ pim.4 \ pms.4 \ polling.4 \ ppbus.4 \ ppc.4 \ ppi.4 \ procdesc.4 \ proto.4 \ psm.4 \ pst.4 \ pt.4 \ pts.4 \ pty.4 \ puc.4 \ ${_qlxge.4} \ ${_qlxgb.4} \ ${_qlxgbe.4} \ ${_qlnxe.4} \ ral.4 \ random.4 \ rc.4 \ rctl.4 \ re.4 \ rgephy.4 \ rights.4 \ rl.4 \ rndtest.4 \ route.4 \ rp.4 \ rtwn.4 \ rtwnfw.4 \ rtwn_pci.4 \ rue.4 \ sa.4 \ safe.4 \ sbp.4 \ sbp_targ.4 \ scc.4 \ sched_4bsd.4 \ sched_ule.4 \ screen.4 \ scsi.4 \ sctp.4 \ sdhci.4 \ sem.4 \ send.4 \ ses.4 \ sf.4 \ ${_sfxge.4} \ sge.4 \ siba.4 \ siftr.4 \ siis.4 \ simplebus.4 \ sio.4 \ sis.4 \ sk.4 \ smb.4 \ smbus.4 \ smp.4 \ smsc.4 \ sn.4 \ snd_ad1816.4 \ snd_als4000.4 \ snd_atiixp.4 \ snd_cmi.4 \ snd_cs4281.4 \ snd_csa.4 \ snd_ds1.4 \ snd_emu10k1.4 \ snd_emu10kx.4 \ snd_envy24.4 \ snd_envy24ht.4 \ snd_es137x.4 \ snd_ess.4 \ snd_fm801.4 \ snd_gusc.4 \ snd_hda.4 \ snd_hdspe.4 \ snd_ich.4 \ snd_maestro3.4 \ snd_maestro.4 \ snd_mss.4 \ snd_neomagic.4 \ snd_sbc.4 \ snd_solo.4 \ snd_spicds.4 \ snd_t4dwave.4 \ snd_uaudio.4 \ snd_via8233.4 \ snd_via82c686.4 \ snd_vibes.4 \ snp.4 \ ${_spkr.4} \ splash.4 \ sppp.4 \ ste.4 \ stf.4 \ stg.4 \ stge.4 \ sym.4 \ syncache.4 \ syncer.4 \ syscons.4 \ sysmouse.4 \ tap.4 \ targ.4 \ tcp.4 \ tdfx.4 \ terasic_mtl.4 \ termios.4 \ textdump.4 \ ti.4 \ timecounters.4 \ tl.4 \ ${_tpm.4} \ trm.4 \ tty.4 \ tun.4 \ twa.4 \ twe.4 \ tws.4 \ tx.4 \ txp.4 \ udp.4 \ udplite.4 \ ure.4 \ vale.4 \ vga.4 \ vge.4 \ viapm.4 \ ${_viawd.4} \ ${_virtio.4} \ ${_virtio_balloon.4} \ ${_virtio_blk.4} \ ${_virtio_console.4} \ ${_virtio_random.4} \ ${_virtio_scsi.4} \ vkbd.4 \ vlan.4 \ vxlan.4 \ ${_vmx.4} \ vpo.4 \ vr.4 \ vt.4 \ vte.4 \ ${_vtnet.4} \ ${_vxge.4} \ watchdog.4 \ wb.4 \ ${_wbwd.4} \ wi.4 \ witness.4 \ wlan.4 \ wlan_acl.4 \ wlan_amrr.4 \ wlan_ccmp.4 \ wlan_tkip.4 \ wlan_wep.4 \ wlan_xauth.4 \ wmt.4 \ ${_wpi.4} \ wsp.4 \ xe.4 \ ${_xen.4} \ xhci.4 \ xl.4 \ ${_xnb.4} \ xpt.4 \ zero.4 MLINKS= ae.4 if_ae.4 MLINKS+=age.4 if_age.4 MLINKS+=agp.4 agpgart.4 MLINKS+=alc.4 if_alc.4 MLINKS+=ale.4 if_ale.4 MLINKS+=altera_atse.4 atse.4 MLINKS+=altera_sdcard.4 altera_sdcardc.4 MLINKS+=altq.4 ALTQ.4 MLINKS+=ath.4 if_ath.4 MLINKS+=ath_pci.4 if_ath_pci.4 MLINKS+=an.4 if_an.4 MLINKS+=aue.4 if_aue.4 MLINKS+=axe.4 if_axe.4 MLINKS+=bce.4 if_bce.4 MLINKS+=bfe.4 if_bfe.4 MLINKS+=bge.4 if_bge.4 MLINKS+=bktr.4 brooktree.4 MLINKS+=bnxt.4 if_bnxt.4 MLINKS+=bridge.4 if_bridge.4 MLINKS+=bwi.4 if_bwi.4 MLINKS+=bwn.4 if_bwn.4 MLINKS+=${_bxe.4} ${_if_bxe.4} MLINKS+=cas.4 if_cas.4 MLINKS+=cdce.4 if_cdce.4 MLINKS+=cfi.4 cfid.4 MLINKS+=cloudabi.4 cloudabi32.4 \ cloudabi.4 cloudabi64.4 MLINKS+=crypto.4 cryptodev.4 MLINKS+=cue.4 if_cue.4 MLINKS+=cxgb.4 if_cxgb.4 MLINKS+=cxgbe.4 if_cxgbe.4 \ cxgbe.4 vcxgbe.4 \ cxgbe.4 if_vcxgbe.4 \ cxgbe.4 cxl.4 \ cxgbe.4 if_cxl.4 \ cxgbe.4 vcxl.4 \ cxgbe.4 if_vcxl.4 \ cxgbe.4 cc.4 \ cxgbe.4 if_cc.4 \ cxgbe.4 vcc.4 \ cxgbe.4 if_vcc.4 MLINKS+=cxgbev.4 if_cxgbev.4 \ cxgbev.4 cxlv.4 \ cxgbev.4 if_cxlv.4 \ cxgbev.4 ccv.4 \ cxgbev.4 if_ccv.4 MLINKS+=dc.4 if_dc.4 MLINKS+=de.4 if_de.4 MLINKS+=disc.4 if_disc.4 MLINKS+=ed.4 if_ed.4 MLINKS+=edsc.4 if_edsc.4 MLINKS+=em.4 if_em.4 MLINKS+=enc.4 if_enc.4 MLINKS+=epair.4 if_epair.4 MLINKS+=et.4 if_et.4 MLINKS+=fd.4 stderr.4 \ fd.4 stdin.4 \ fd.4 stdout.4 MLINKS+=fdt.4 FDT.4 MLINKS+=firewire.4 ieee1394.4 MLINKS+=fwe.4 if_fwe.4 MLINKS+=fwip.4 if_fwip.4 MLINKS+=fxp.4 if_fxp.4 MLINKS+=gem.4 if_gem.4 MLINKS+=geom.4 GEOM.4 MLINKS+=gif.4 if_gif.4 MLINKS+=gpio.4 gpiobus.4 MLINKS+=gre.4 if_gre.4 MLINKS+=hme.4 if_hme.4 MLINKS+=hpet.4 acpi_hpet.4 MLINKS+=${_hptrr.4} ${_rr232x.4} MLINKS+=${_attimer.4} ${_i8254.4} MLINKS+=ip.4 rawip.4 MLINKS+=ipfirewall.4 ipaccounting.4 \ ipfirewall.4 ipacct.4 \ ipfirewall.4 ipfw.4 MLINKS+=ipheth.4 if_ipheth.4 MLINKS+=ipw.4 if_ipw.4 MLINKS+=iwi.4 if_iwi.4 MLINKS+=iwm.4 if_iwm.4 MLINKS+=iwn.4 if_iwn.4 MLINKS+=ixgb.4 if_ixgb.4 MLINKS+=ixgbe.4 ix.4 MLINKS+=ixgbe.4 if_ix.4 MLINKS+=ixgbe.4 if_ixgbe.4 MLINKS+=ixl.4 if_ixl.4 MLINKS+=ixlv.4 if_ixlv.4 MLINKS+=jme.4 if_jme.4 MLINKS+=kue.4 if_kue.4 MLINKS+=lagg.4 trunk.4 MLINKS+=lagg.4 if_lagg.4 MLINKS+=le.4 if_le.4 MLINKS+=lge.4 if_lge.4 MLINKS+=lmc.4 if_lmc.4 MLINKS+=lo.4 loop.4 MLINKS+=lp.4 plip.4 MLINKS+=malo.4 if_malo.4 MLINKS+=md.4 vn.4 MLINKS+=mem.4 kmem.4 MLINKS+=mfi.4 mfi_linux.4 \ mfi.4 mfip.4 MLINKS+=mlx5en.4 mce.4 MLINKS+=mn.4 if_mn.4 MLINKS+=mos.4 if_mos.4 MLINKS+=msk.4 if_msk.4 MLINKS+=mwl.4 if_mwl.4 MLINKS+=mxge.4 if_mxge.4 MLINKS+=my.4 if_my.4 MLINKS+=${_ndis.4} ${_if_ndis.4} MLINKS+=netfpga10g_nf10bmac.4 if_nf10bmac.4 MLINKS+=netintro.4 net.4 \ netintro.4 networking.4 MLINKS+=${_nfe.4} ${_if_nfe.4} MLINKS+=nge.4 if_nge.4 MLINKS+=${_nxge.4} ${_if_nxge.4} MLINKS+=ow.4 onewire.4 MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 snd.4 \ pcm.4 sound.4 MLINKS+=pcn.4 if_pcn.4 MLINKS+=pms.4 pmspcv.4 MLINKS+=ral.4 if_ral.4 MLINKS+=re.4 if_re.4 MLINKS+=rl.4 if_rl.4 MLINKS+=rtwn_pci.4 if_rtwn_pci.4 MLINKS+=rue.4 if_rue.4 MLINKS+=scsi.4 CAM.4 \ scsi.4 cam.4 \ scsi.4 scbus.4 \ scsi.4 SCSI.4 MLINKS+=sf.4 if_sf.4 MLINKS+=sge.4 if_sge.4 MLINKS+=sis.4 if_sis.4 MLINKS+=sk.4 if_sk.4 MLINKS+=smp.4 SMP.4 MLINKS+=smsc.4 if_smsc.4 MLINKS+=sn.4 if_sn.4 MLINKS+=snd_envy24.4 snd_ak452x.4 MLINKS+=snd_sbc.4 snd_sb16.4 \ snd_sbc.4 snd_sb8.4 MLINKS+=${_spkr.4} ${_speaker.4} MLINKS+=splash.4 screensaver.4 MLINKS+=ste.4 if_ste.4 MLINKS+=stf.4 if_stf.4 MLINKS+=stge.4 if_stge.4 MLINKS+=syncache.4 syncookies.4 MLINKS+=syscons.4 sc.4 MLINKS+=tap.4 if_tap.4 MLINKS+=tdfx.4 tdfx_linux.4 MLINKS+=ti.4 if_ti.4 MLINKS+=tl.4 if_tl.4 MLINKS+=tun.4 if_tun.4 MLINKS+=tx.4 if_tx.4 MLINKS+=txp.4 if_txp.4 MLINKS+=ure.4 if_ure.4 MLINKS+=vge.4 if_vge.4 MLINKS+=vlan.4 if_vlan.4 MLINKS+=vxlan.4 if_vxlan.4 MLINKS+=${_vmx.4} ${_if_vmx.4} MLINKS+=vpo.4 imm.4 MLINKS+=vr.4 if_vr.4 MLINKS+=vte.4 if_vte.4 MLINKS+=${_vtnet.4} ${_if_vtnet.4} MLINKS+=${_vxge.4} ${_if_vxge.4} MLINKS+=watchdog.4 SW_WATCHDOG.4 MLINKS+=wb.4 if_wb.4 MLINKS+=wi.4 if_wi.4 MLINKS+=${_wpi.4} ${_if_wpi.4} MLINKS+=xe.4 if_xe.4 MLINKS+=xl.4 if_xl.4 .if ${MACHINE_CPUARCH} == "aarch64" _armv8crypto.4= armv8crypto.4 .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" _acpi_asus.4= acpi_asus.4 _acpi_asus_wmi.4= acpi_asus_wmi.4 _acpi_dock.4= acpi_dock.4 _acpi_fujitsu.4=acpi_fujitsu.4 _acpi_hp.4= acpi_hp.4 _acpi_ibm.4= acpi_ibm.4 _acpi_panasonic.4=acpi_panasonic.4 _acpi_rapidstart.4=acpi_rapidstart.4 _acpi_sony.4= acpi_sony.4 _acpi_toshiba.4=acpi_toshiba.4 _acpi_wmi.4= acpi_wmi.4 _aesni.4= aesni.4 _aout.4= aout.4 _apic.4= apic.4 _atrtc.4= atrtc.4 _attimer.4= attimer.4 _aibs.4= aibs.4 _amdsbwd.4= amdsbwd.4 _amdsmb.4= amdsmb.4 _amdsmn.4= amdsmn.4 _amdtemp.4= amdtemp.4 _asmc.4= asmc.4 _bxe.4= bxe.4 _bytgpio.4= bytgpio.4 _coretemp.4= coretemp.4 _cpuctl.4= cpuctl.4 _dpms.4= dpms.4 _hpt27xx.4= hpt27xx.4 _hptiop.4= hptiop.4 _hptmv.4= hptmv.4 _hptnr.4= hptnr.4 _hptrr.4= hptrr.4 _hv_kvp.4= hv_kvp.4 _hv_netvsc.4= hv_netvsc.4 _hv_storvsc.4= hv_storvsc.4 _hv_utils.4= hv_utils.4 _hv_vmbus.4= hv_vmbus.4 _hv_vss.4= hv_vss.4 _i8254.4= i8254.4 _ichwd.4= ichwd.4 _if_bxe.4= if_bxe.4 _if_ndis.4= if_ndis.4 _if_nfe.4= if_nfe.4 _if_nxge.4= if_nxge.4 _if_urtw.4= if_urtw.4 _if_vmx.4= if_vmx.4 _if_vtnet.4= if_vtnet.4 _if_vxge.4= if_vxge.4 _if_wpi.4= if_wpi.4 _ipmi.4= ipmi.4 _io.4= io.4 _linux.4= linux.4 _nda.4= nda.4 _ndis.4= ndis.4 _nfe.4= nfe.4 _nfsmb.4= nfsmb.4 _nvd.4= nvd.4 _nvme.4= nvme.4 _nvram.4= nvram.4 _nxge.4= nxge.4 _virtio.4= virtio.4 _virtio_balloon.4=virtio_balloon.4 _virtio_blk.4= virtio_blk.4 _virtio_console.4=virtio_console.4 _virtio_random.4= virtio_random.4 _virtio_scsi.4= virtio_scsi.4 _vmx.4= vmx.4 _vtnet.4= vtnet.4 _vxge.4= vxge.4 _padlock.4= padlock.4 _rr232x.4= rr232x.4 _speaker.4= speaker.4 _spkr.4= spkr.4 _tpm.4= tpm.4 _urtw.4= urtw.4 _viawd.4= viawd.4 _wbwd.4= wbwd.4 _wpi.4= wpi.4 _xen.4= xen.4 _xnb.4= xnb.4 .endif .if ${MACHINE_CPUARCH} == "amd64" _if_ntb.4= if_ntb.4 _ioat.4= ioat.4 _ntb.4= ntb.4 _ntb_hw_intel.4= ntb_hw_intel.4 _ntb_hw_plx.4= ntb_hw_plx.4 _ntb_transport.4=ntb_transport.4 _qlxge.4= qlxge.4 _qlxgb.4= qlxgb.4 _qlxgbe.4= qlxgbe.4 _qlnxe.4= qlnxe.4 _sfxge.4= sfxge.4 MLINKS+=qlxge.4 if_qlxge.4 MLINKS+=qlxgb.4 if_qlxgb.4 MLINKS+=qlxgbe.4 if_qlxgbe.4 MLINKS+=qlnxe.4 if_qlnxe.4 MLINKS+=sfxge.4 if_sfxge.4 .if ${MK_BHYVE} != "no" _bhyve.4= bhyve.4 .endif .endif .if ${MACHINE_CPUARCH} == "mips" _nvram2env.4= nvram2env.4 .endif .if exists(${.CURDIR}/man4.${MACHINE_CPUARCH}) SUBDIR= man4.${MACHINE_CPUARCH} .endif .if ${MK_BLUETOOTH} != "no" MAN+= ng_bluetooth.4 .endif .if ${MK_CCD} != "no" _ccd.4= ccd.4 .endif .if ${MK_CDDL} != "no" _dtrace_provs= dtrace_io.4 \ dtrace_ip.4 \ dtrace_lockstat.4 \ dtrace_proc.4 \ dtrace_sched.4 \ dtrace_tcp.4 \ dtrace_udp.4 .endif .if ${MK_ISCSI} != "no" MAN+= cfiscsi.4 MAN+= iscsi.4 MAN+= iscsi_initiator.4 MAN+= iser.4 .endif .if ${MK_OFED} != "no" MAN+= mlx4ib.4 MAN+= mlx5ib.4 .endif .if ${MK_TESTS} != "no" ATF= ${SRCTOP}/contrib/atf .PATH: ${ATF}/doc _atf_test_case.4= atf-test-case.4 .endif .if ${MK_PF} != "no" _pf.4= pf.4 _pflog.4= pflog.4 _pfsync.4= pfsync.4 .endif .if ${MK_USB} != "no" MAN+= \ otus.4 \ otusfw.4 \ rsu.4 \ rsufw.4 \ rtwn_usb.4 \ rum.4 \ run.4 \ runfw.4 \ u3g.4 \ uark.4 \ uart.4 \ uath.4 \ ubsa.4 \ ubsec.4 \ ubser.4 \ ubtbcmfw.4 \ uchcom.4 \ ucom.4 \ ucycom.4 \ udav.4 \ udbp.4 \ udl.4 \ uep.4 \ ufm.4 \ ufoma.4 \ uftdi.4 \ ugen.4 \ ugold.4 \ uhci.4 \ uhid.4 \ uhso.4 \ uipaq.4 \ ukbd.4 \ uled.4 \ ulpt.4 \ umass.4 \ umcs.4 \ umct.4 \ umodem.4 \ umoscom.4 \ ums.4 \ unix.4 \ upgt.4 \ uplcom.4 \ ural.4 \ urio.4 \ urndis.4 \ ${_urtw.4} \ usb.4 \ usb_quirk.4 \ usb_template.4 \ usfs.4 \ uslcom.4 \ uvisor.4 \ uvscom.4 \ zyd.4 MLINKS+=otus.4 if_otus.4 MLINKS+=rsu.4 if_rsu.4 MLINKS+=rtwn_usb.4 if_rtwn_usb.4 MLINKS+=rum.4 if_rum.4 MLINKS+=run.4 if_run.4 MLINKS+=u3g.4 u3gstub.4 MLINKS+=uath.4 if_uath.4 MLINKS+=udav.4 if_udav.4 MLINKS+=upgt.4 if_upgt.4 MLINKS+=ural.4 if_ural.4 MLINKS+=urndis.4 if_urndis.4 MLINKS+=${_urtw.4} ${_if_urtw.4} MLINKS+=zyd.4 if_zyd.4 .endif .include Index: head/share/man/man4/aw_gpio.4 =================================================================== --- head/share/man/man4/aw_gpio.4 (nonexistent) +++ head/share/man/man4/aw_gpio.4 (revision 327199) @@ -0,0 +1,102 @@ +.\"- +.\" Copyright (c) 2017 Emmanuel Vadot +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd Dec 25, 2017 +.Dt AW_GPIO 4 +.Os +.Sh NAME +.Nm aw_gpio +.Nd driver for the GPIO and pin muxing functionalities on Allwinner SoC +.Sh SYNOPSIS +.Cd "device gpio" +.Cd "options SOC_ALLWINNER_A10" +.Cd "options SOC_ALLWINNER_A13" +.Cd "options SOC_ALLWINNER_A20" +.Cd "options SOC_ALLWINNER_A31" +.Cd "options SOC_ALLWINNER_A31S" +.Cd "options SOC_ALLWINNER_A33" +.Cd "options SOC_ALLWINNER_A83T" +.Cd "options SOC_ALLWINNER_H2PLUS" +.Cd "options SOC_ALLWINNER_H3" +.Cd "options SOC_ALLWINNER_A64" +.Cd "options SOC_ALLWINNER_H5" +.Sh DESCRIPTION +The +.Nm +device driver provides support for the Allwinner pin muxing and GPIO on +Allwinner SoCs. +.Sh HARDWARE +The current version of the +.Nm +driver supports the GPIO/pinmuxing controller with one of the following +compatible strings : +.Pp +.Bl -bullet -compact +.It +allwinner,sun4i-a10-pinctrl +.It +allwinner,sun5i-a13-pinctrl +.It +allwinner,sun7i-a20-pinctrl +.It +allwinner,sun6i-a31-pinctrl +.It +allwinner,sun6i-a31s-pinctrl +.It +allwinner,sun6i-a31-r-pinctrl +.It +allwinner,sun6i-a33-pinctrl +.It +allwinner,sun8i-a83t-pinctrl +.It +allwinner,sun8i-a83t-r-pinctrl +.It +allwinner,sun8i-h3-pinctrl +.It +allwinner,sun50i-h5-pinctrl +.It +allwinner,sun8i-h3-r-pinctrl +.It +allwinner,sun50i-a64-pinctrl +.It +allwinner,sun50i-a64-r-pinctrl +.El +.Sh SEE ALSO +.Xr fdt 4 , +.Xr gpio 4 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Fx 10.0 . +.Sh AUTHORS +The +.Nm +device driver was originally written by +.An Ganbold Tsagaankhuu Aq Mt ganbold@freebsd.org . +This manual page was written by +.An Emmanuel Vadot Aq Mt manu@freebsd.org . Property changes on: head/share/man/man4/aw_gpio.4 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/arm/allwinner/a10_gpio.c =================================================================== --- head/sys/arm/allwinner/a10_gpio.c (revision 327198) +++ head/sys/arm/allwinner/a10_gpio.c (nonexistent) @@ -1,1027 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2013 Ganbold Tsagaankhuu - * Copyright (c) 2012 Oleksandr Tymoshenko - * Copyright (c) 2012 Luiz Otavio O Souza. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(__aarch64__) -#include "opt_soc.h" -#endif - -#include "gpio_if.h" - -#define A10_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ - GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) - -#define A10_GPIO_NONE 0 -#define A10_GPIO_PULLUP 1 -#define A10_GPIO_PULLDOWN 2 - -#define A10_GPIO_INPUT 0 -#define A10_GPIO_OUTPUT 1 - -#define AW_GPIO_DRV_MASK 0x3 -#define AW_GPIO_PUD_MASK 0x3 - -#define AW_PINCTRL 1 -#define AW_R_PINCTRL 2 - -/* Defined in a10_padconf.c */ -#ifdef SOC_ALLWINNER_A10 -extern const struct allwinner_padconf a10_padconf; -#endif - -/* Defined in a13_padconf.c */ -#ifdef SOC_ALLWINNER_A13 -extern const struct allwinner_padconf a13_padconf; -#endif - -/* Defined in a20_padconf.c */ -#ifdef SOC_ALLWINNER_A20 -extern const struct allwinner_padconf a20_padconf; -#endif - -/* Defined in a31_padconf.c */ -#ifdef SOC_ALLWINNER_A31 -extern const struct allwinner_padconf a31_padconf; -#endif - -/* Defined in a31s_padconf.c */ -#ifdef SOC_ALLWINNER_A31S -extern const struct allwinner_padconf a31s_padconf; -#endif - -#if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S) -extern const struct allwinner_padconf a31_r_padconf; -#endif - -/* Defined in a33_padconf.c */ -#ifdef SOC_ALLWINNER_A33 -extern const struct allwinner_padconf a33_padconf; -#endif - -/* Defined in h3_padconf.c */ -#if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) -extern const struct allwinner_padconf h3_padconf; -extern const struct allwinner_padconf h3_r_padconf; -#endif - -/* Defined in a83t_padconf.c */ -#ifdef SOC_ALLWINNER_A83T -extern const struct allwinner_padconf a83t_padconf; -extern const struct allwinner_padconf a83t_r_padconf; -#endif - -/* Defined in a64_padconf.c */ -#ifdef SOC_ALLWINNER_A64 -extern const struct allwinner_padconf a64_padconf; -extern const struct allwinner_padconf a64_r_padconf; -#endif - -static struct ofw_compat_data compat_data[] = { -#ifdef SOC_ALLWINNER_A10 - {"allwinner,sun4i-a10-pinctrl", (uintptr_t)&a10_padconf}, -#endif -#ifdef SOC_ALLWINNER_A13 - {"allwinner,sun5i-a13-pinctrl", (uintptr_t)&a13_padconf}, -#endif -#ifdef SOC_ALLWINNER_A20 - {"allwinner,sun7i-a20-pinctrl", (uintptr_t)&a20_padconf}, -#endif -#ifdef SOC_ALLWINNER_A31 - {"allwinner,sun6i-a31-pinctrl", (uintptr_t)&a31_padconf}, -#endif -#ifdef SOC_ALLWINNER_A31S - {"allwinner,sun6i-a31s-pinctrl", (uintptr_t)&a31s_padconf}, -#endif -#if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S) - {"allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&a31_r_padconf}, -#endif -#ifdef SOC_ALLWINNER_A33 - {"allwinner,sun6i-a33-pinctrl", (uintptr_t)&a33_padconf}, -#endif -#ifdef SOC_ALLWINNER_A83T - {"allwinner,sun8i-a83t-pinctrl", (uintptr_t)&a83t_padconf}, - {"allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&a83t_r_padconf}, -#endif -#if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) - {"allwinner,sun8i-h3-pinctrl", (uintptr_t)&h3_padconf}, - {"allwinner,sun50i-h5-pinctrl", (uintptr_t)&h3_padconf}, - {"allwinner,sun8i-h3-r-pinctrl", (uintptr_t)&h3_r_padconf}, -#endif -#ifdef SOC_ALLWINNER_A64 - {"allwinner,sun50i-a64-pinctrl", (uintptr_t)&a64_padconf}, - {"allwinner,sun50i-a64-r-pinctrl", (uintptr_t)&a64_r_padconf}, -#endif - {NULL, 0} -}; - -struct clk_list { - TAILQ_ENTRY(clk_list) next; - clk_t clk; -}; - -struct a10_gpio_softc { - device_t sc_dev; - device_t sc_busdev; - struct mtx sc_mtx; - struct resource * sc_mem_res; - struct resource * sc_irq_res; - bus_space_tag_t sc_bst; - bus_space_handle_t sc_bsh; - void * sc_intrhand; - const struct allwinner_padconf * padconf; - TAILQ_HEAD(, clk_list) clk_list; -}; - -#define A10_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) -#define A10_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx) -#define A10_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) - -#define A10_GPIO_GP_CFG(_bank, _idx) 0x00 + ((_bank) * 0x24) + ((_idx) << 2) -#define A10_GPIO_GP_DAT(_bank) 0x10 + ((_bank) * 0x24) -#define A10_GPIO_GP_DRV(_bank, _idx) 0x14 + ((_bank) * 0x24) + ((_idx) << 2) -#define A10_GPIO_GP_PUL(_bank, _idx) 0x1c + ((_bank) * 0x24) + ((_idx) << 2) - -#define A10_GPIO_GP_INT_CFG0 0x200 -#define A10_GPIO_GP_INT_CFG1 0x204 -#define A10_GPIO_GP_INT_CFG2 0x208 -#define A10_GPIO_GP_INT_CFG3 0x20c - -#define A10_GPIO_GP_INT_CTL 0x210 -#define A10_GPIO_GP_INT_STA 0x214 -#define A10_GPIO_GP_INT_DEB 0x218 - -static char *a10_gpio_parse_function(phandle_t node); -static const char **a10_gpio_parse_pins(phandle_t node, int *pins_nb); -static uint32_t a10_gpio_parse_bias(phandle_t node); -static int a10_gpio_parse_drive_strength(phandle_t node, uint32_t *drive); - -static int a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value); -static int a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); -static int a10_gpio_pin_get_locked(struct a10_gpio_softc *sc, uint32_t pin, unsigned int *value); -static int a10_gpio_pin_set_locked(struct a10_gpio_softc *sc, uint32_t pin, unsigned int value); - -#define A10_GPIO_WRITE(_sc, _off, _val) \ - bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) -#define A10_GPIO_READ(_sc, _off) \ - bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off) - -static uint32_t -a10_gpio_get_function(struct a10_gpio_softc *sc, uint32_t pin) -{ - uint32_t bank, func, offset; - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - if (pin > sc->padconf->npins) - return (0); - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - offset = ((pin & 0x07) << 2); - - func = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, pin >> 3)); - - return ((func >> offset) & 0x7); -} - -static int -a10_gpio_set_function(struct a10_gpio_softc *sc, uint32_t pin, uint32_t f) -{ - uint32_t bank, data, offset; - - /* Check if the function exists in the padconf data */ - if (sc->padconf->pins[pin].functions[f] == NULL) - return (EINVAL); - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - offset = ((pin & 0x07) << 2); - - data = A10_GPIO_READ(sc, A10_GPIO_GP_CFG(bank, pin >> 3)); - data &= ~(7 << offset); - data |= (f << offset); - A10_GPIO_WRITE(sc, A10_GPIO_GP_CFG(bank, pin >> 3), data); - - return (0); -} - -static uint32_t -a10_gpio_get_pud(struct a10_gpio_softc *sc, uint32_t pin) -{ - uint32_t bank, offset, val; - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - offset = ((pin & 0x0f) << 1); - - val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pin >> 4)); - - return ((val >> offset) & AW_GPIO_PUD_MASK); -} - -static void -a10_gpio_set_pud(struct a10_gpio_softc *sc, uint32_t pin, uint32_t state) -{ - uint32_t bank, offset, val; - - if (a10_gpio_get_pud(sc, pin) == state) - return; - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - offset = ((pin & 0x0f) << 1); - - val = A10_GPIO_READ(sc, A10_GPIO_GP_PUL(bank, pin >> 4)); - val &= ~(AW_GPIO_PUD_MASK << offset); - val |= (state << offset); - A10_GPIO_WRITE(sc, A10_GPIO_GP_PUL(bank, pin >> 4), val); -} - -static uint32_t -a10_gpio_get_drv(struct a10_gpio_softc *sc, uint32_t pin) -{ - uint32_t bank, offset, val; - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - offset = ((pin & 0x0f) << 1); - - val = A10_GPIO_READ(sc, A10_GPIO_GP_DRV(bank, pin >> 4)); - - return ((val >> offset) & AW_GPIO_DRV_MASK); -} - -static void -a10_gpio_set_drv(struct a10_gpio_softc *sc, uint32_t pin, uint32_t drive) -{ - uint32_t bank, offset, val; - - if (a10_gpio_get_drv(sc, pin) == drive) - return; - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - offset = ((pin & 0x0f) << 1); - - val = A10_GPIO_READ(sc, A10_GPIO_GP_DRV(bank, pin >> 4)); - val &= ~(AW_GPIO_DRV_MASK << offset); - val |= (drive << offset); - A10_GPIO_WRITE(sc, A10_GPIO_GP_DRV(bank, pin >> 4), val); -} - -static int -a10_gpio_pin_configure(struct a10_gpio_softc *sc, uint32_t pin, uint32_t flags) -{ - u_int val; - int err = 0; - - /* Must be called with lock held. */ - A10_GPIO_LOCK_ASSERT(sc); - - if (pin > sc->padconf->npins) - return (EINVAL); - - /* Manage input/output. */ - if (flags & GPIO_PIN_INPUT) { - err = a10_gpio_set_function(sc, pin, A10_GPIO_INPUT); - } else if ((flags & GPIO_PIN_OUTPUT) && - a10_gpio_get_function(sc, pin) != A10_GPIO_OUTPUT) { - if (flags & GPIO_PIN_PRESET_LOW) { - a10_gpio_pin_set_locked(sc, pin, 0); - } else if (flags & GPIO_PIN_PRESET_HIGH) { - a10_gpio_pin_set_locked(sc, pin, 1); - } else { - /* Read the pin and preset output to current state. */ - err = a10_gpio_set_function(sc, pin, A10_GPIO_INPUT); - if (err == 0) { - a10_gpio_pin_get_locked(sc, pin, &val); - a10_gpio_pin_set_locked(sc, pin, val); - } - } - if (err == 0) - err = a10_gpio_set_function(sc, pin, A10_GPIO_OUTPUT); - } - - if (err) - return (err); - - /* Manage Pull-up/pull-down. */ - if (flags & GPIO_PIN_PULLUP) - a10_gpio_set_pud(sc, pin, A10_GPIO_PULLUP); - else if (flags & GPIO_PIN_PULLDOWN) - a10_gpio_set_pud(sc, pin, A10_GPIO_PULLDOWN); - else - a10_gpio_set_pud(sc, pin, A10_GPIO_NONE); - - return (0); -} - -static device_t -a10_gpio_get_bus(device_t dev) -{ - struct a10_gpio_softc *sc; - - sc = device_get_softc(dev); - - return (sc->sc_busdev); -} - -static int -a10_gpio_pin_max(device_t dev, int *maxpin) -{ - struct a10_gpio_softc *sc; - - sc = device_get_softc(dev); - - *maxpin = sc->padconf->npins - 1; - return (0); -} - -static int -a10_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) -{ - struct a10_gpio_softc *sc; - - sc = device_get_softc(dev); - if (pin >= sc->padconf->npins) - return (EINVAL); - - *caps = A10_GPIO_DEFAULT_CAPS; - - return (0); -} - -static int -a10_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) -{ - struct a10_gpio_softc *sc; - uint32_t func; - uint32_t pud; - - sc = device_get_softc(dev); - if (pin >= sc->padconf->npins) - return (EINVAL); - - A10_GPIO_LOCK(sc); - func = a10_gpio_get_function(sc, pin); - switch (func) { - case A10_GPIO_INPUT: - *flags = GPIO_PIN_INPUT; - break; - case A10_GPIO_OUTPUT: - *flags = GPIO_PIN_OUTPUT; - break; - default: - *flags = 0; - break; - } - - pud = a10_gpio_get_pud(sc, pin); - switch (pud) { - case A10_GPIO_PULLDOWN: - *flags |= GPIO_PIN_PULLDOWN; - break; - case A10_GPIO_PULLUP: - *flags |= GPIO_PIN_PULLUP; - break; - default: - break; - } - - A10_GPIO_UNLOCK(sc); - - return (0); -} - -static int -a10_gpio_pin_getname(device_t dev, uint32_t pin, char *name) -{ - struct a10_gpio_softc *sc; - - sc = device_get_softc(dev); - if (pin >= sc->padconf->npins) - return (EINVAL); - - snprintf(name, GPIOMAXNAME - 1, "%s", - sc->padconf->pins[pin].name); - name[GPIOMAXNAME - 1] = '\0'; - - return (0); -} - -static int -a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) -{ - struct a10_gpio_softc *sc; - int err; - - sc = device_get_softc(dev); - if (pin > sc->padconf->npins) - return (EINVAL); - - A10_GPIO_LOCK(sc); - err = a10_gpio_pin_configure(sc, pin, flags); - A10_GPIO_UNLOCK(sc); - - return (err); -} - -static int -a10_gpio_pin_set_locked(struct a10_gpio_softc *sc, uint32_t pin, - unsigned int value) -{ - uint32_t bank, data; - - A10_GPIO_LOCK_ASSERT(sc); - - if (pin > sc->padconf->npins) - return (EINVAL); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - - data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); - if (value) - data |= (1 << pin); - else - data &= ~(1 << pin); - A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data); - - return (0); -} - -static int -a10_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) -{ - struct a10_gpio_softc *sc; - int ret; - - sc = device_get_softc(dev); - - A10_GPIO_LOCK(sc); - ret = a10_gpio_pin_set_locked(sc, pin, value); - A10_GPIO_UNLOCK(sc); - - return (ret); -} - -static int -a10_gpio_pin_get_locked(struct a10_gpio_softc *sc,uint32_t pin, - unsigned int *val) -{ - uint32_t bank, reg_data; - - A10_GPIO_LOCK_ASSERT(sc); - - if (pin > sc->padconf->npins) - return (EINVAL); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - - reg_data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); - *val = (reg_data & (1 << pin)) ? 1 : 0; - - return (0); -} - -static char * -a10_gpio_parse_function(phandle_t node) -{ - char *function; - - if (OF_getprop_alloc(node, "function", sizeof(*function), - (void **)&function) != -1) - return (function); - if (OF_getprop_alloc(node, "allwinner,function", sizeof(*function), - (void **)&function) != -1) - return (function); - - return (NULL); -} - -static const char ** -a10_gpio_parse_pins(phandle_t node, int *pins_nb) -{ - const char **pinlist; - - *pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist); - if (*pins_nb > 0) - return (pinlist); - - *pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins", - &pinlist); - if (*pins_nb > 0) - return (pinlist); - - return (NULL); -} - -static uint32_t -a10_gpio_parse_bias(phandle_t node) -{ - uint32_t bias; - - if (OF_getencprop(node, "pull", &bias, sizeof(bias)) != -1) - return (bias); - if (OF_getencprop(node, "allwinner,pull", &bias, sizeof(bias)) != -1) - return (bias); - if (OF_hasprop(node, "bias-disable")) - return (A10_GPIO_NONE); - if (OF_hasprop(node, "bias-pull-up")) - return (A10_GPIO_PULLUP); - if (OF_hasprop(node, "bias-pull-down")) - return (A10_GPIO_PULLDOWN); - - return (A10_GPIO_NONE); -} - -static int -a10_gpio_parse_drive_strength(phandle_t node, uint32_t *drive) -{ - uint32_t drive_str; - - if (OF_getencprop(node, "drive", drive, sizeof(*drive)) != -1) - return (0); - if (OF_getencprop(node, "allwinner,drive", drive, sizeof(*drive)) != -1) - return (0); - if (OF_getencprop(node, "drive-strength", &drive_str, - sizeof(drive_str)) != -1) { - *drive = (drive_str / 10) - 1; - return (0); - } - - return (1); -} - -static int -a10_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) -{ - struct a10_gpio_softc *sc; - int ret; - - sc = device_get_softc(dev); - - A10_GPIO_LOCK(sc); - ret = a10_gpio_pin_get_locked(sc, pin, val); - A10_GPIO_UNLOCK(sc); - - return (ret); -} - -static int -a10_gpio_pin_toggle(device_t dev, uint32_t pin) -{ - struct a10_gpio_softc *sc; - uint32_t bank, data; - - sc = device_get_softc(dev); - if (pin > sc->padconf->npins) - return (EINVAL); - - bank = sc->padconf->pins[pin].port; - pin = sc->padconf->pins[pin].pin; - - A10_GPIO_LOCK(sc); - data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); - if (data & (1 << pin)) - data &= ~(1 << pin); - else - data |= (1 << pin); - A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), data); - A10_GPIO_UNLOCK(sc); - - return (0); -} - -static int -a10_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, - uint32_t change_pins, uint32_t *orig_pins) -{ - struct a10_gpio_softc *sc; - uint32_t bank, data, pin; - - sc = device_get_softc(dev); - if (first_pin > sc->padconf->npins) - return (EINVAL); - - /* - * We require that first_pin refers to the first pin in a bank, because - * this API is not about convenience, it's for making a set of pins - * change simultaneously (required) with reasonably high performance - * (desired); we need to do a read-modify-write on a single register. - */ - bank = sc->padconf->pins[first_pin].port; - pin = sc->padconf->pins[first_pin].pin; - if (pin != 0) - return (EINVAL); - - A10_GPIO_LOCK(sc); - data = A10_GPIO_READ(sc, A10_GPIO_GP_DAT(bank)); - if ((clear_pins | change_pins) != 0) - A10_GPIO_WRITE(sc, A10_GPIO_GP_DAT(bank), - (data & ~clear_pins) ^ change_pins); - A10_GPIO_UNLOCK(sc); - - if (orig_pins != NULL) - *orig_pins = data; - - return (0); -} - -static int -a10_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, - uint32_t *pin_flags) -{ - struct a10_gpio_softc *sc; - uint32_t bank, pin; - int err; - - sc = device_get_softc(dev); - if (first_pin > sc->padconf->npins) - return (EINVAL); - - bank = sc->padconf->pins[first_pin].port; - if (sc->padconf->pins[first_pin].pin != 0) - return (EINVAL); - - /* - * The configuration for a bank of pins is scattered among several - * registers; we cannot g'tee to simultaneously change the state of all - * the pins in the flags array. So just loop through the array - * configuring each pin for now. If there was a strong need, it might - * be possible to support some limited simultaneous config, such as - * adjacent groups of 8 pins that line up the same as the config regs. - */ - for (err = 0, pin = first_pin; err == 0 && pin < num_pins; ++pin) { - if (pin_flags[pin] & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) - err = a10_gpio_pin_configure(sc, pin, pin_flags[pin]); - } - - return (err); -} - -static int -aw_find_pinnum_by_name(struct a10_gpio_softc *sc, const char *pinname) -{ - int i; - - for (i = 0; i < sc->padconf->npins; i++) - if (!strcmp(pinname, sc->padconf->pins[i].name)) - return i; - - return (-1); -} - -static int -aw_find_pin_func(struct a10_gpio_softc *sc, int pin, const char *func) -{ - int i; - - for (i = 0; i < AW_MAX_FUNC_BY_PIN; i++) - if (sc->padconf->pins[pin].functions[i] && - !strcmp(func, sc->padconf->pins[pin].functions[i])) - return (i); - - return (-1); -} - -static int -aw_fdt_configure_pins(device_t dev, phandle_t cfgxref) -{ - struct a10_gpio_softc *sc; - phandle_t node; - const char **pinlist = NULL; - char *pin_function = NULL; - uint32_t pin_drive, pin_pull; - int pins_nb, pin_num, pin_func, i, ret; - bool set_drive; - - sc = device_get_softc(dev); - node = OF_node_from_xref(cfgxref); - ret = 0; - set_drive = false; - - /* Getting all prop for configuring pins */ - pinlist = a10_gpio_parse_pins(node, &pins_nb); - if (pinlist == NULL) - return (ENOENT); - - pin_function = a10_gpio_parse_function(node); - if (pin_function == NULL) { - ret = ENOENT; - goto out; - } - - if (a10_gpio_parse_drive_strength(node, &pin_drive) == 0) - set_drive = true; - - pin_pull = a10_gpio_parse_bias(node); - - /* Configure each pin to the correct function, drive and pull */ - for (i = 0; i < pins_nb; i++) { - pin_num = aw_find_pinnum_by_name(sc, pinlist[i]); - if (pin_num == -1) { - ret = ENOENT; - goto out; - } - pin_func = aw_find_pin_func(sc, pin_num, pin_function); - if (pin_func == -1) { - ret = ENOENT; - goto out; - } - - A10_GPIO_LOCK(sc); - - if (a10_gpio_get_function(sc, pin_num) != pin_func) - a10_gpio_set_function(sc, pin_num, pin_func); - if (set_drive) - a10_gpio_set_drv(sc, pin_num, pin_drive); - if (pin_pull != A10_GPIO_NONE) - a10_gpio_set_pud(sc, pin_num, pin_pull); - - A10_GPIO_UNLOCK(sc); - } - - out: - OF_prop_free(pinlist); - OF_prop_free(pin_function); - return (ret); -} - -static int -a10_gpio_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) - return (ENXIO); - - device_set_desc(dev, "Allwinner GPIO/Pinmux controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -a10_gpio_attach(device_t dev) -{ - int rid, error; - phandle_t gpio; - struct a10_gpio_softc *sc; - struct clk_list *clkp, *clkp_tmp; - clk_t clk; - hwreset_t rst = NULL; - int off, err, clkret; - - sc = device_get_softc(dev); - sc->sc_dev = dev; - - mtx_init(&sc->sc_mtx, "a10 gpio", "gpio", MTX_SPIN); - - rid = 0; - sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (!sc->sc_mem_res) { - device_printf(dev, "cannot allocate memory window\n"); - goto fail; - } - - sc->sc_bst = rman_get_bustag(sc->sc_mem_res); - sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); - - rid = 0; - sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (!sc->sc_irq_res) { - device_printf(dev, "cannot allocate interrupt\n"); - goto fail; - } - - /* Find our node. */ - gpio = ofw_bus_get_node(sc->sc_dev); - if (!OF_hasprop(gpio, "gpio-controller")) - /* Node is not a GPIO controller. */ - goto fail; - - /* Use the right pin data for the current SoC */ - sc->padconf = (struct allwinner_padconf *)ofw_bus_search_compatible(dev, - compat_data)->ocd_data; - - if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) { - error = hwreset_deassert(rst); - if (error != 0) { - device_printf(dev, "cannot de-assert reset\n"); - goto fail; - } - } - - TAILQ_INIT(&sc->clk_list); - for (off = 0, clkret = 0; clkret == 0; off++) { - clkret = clk_get_by_ofw_index(dev, 0, off, &clk); - if (clkret != 0) - break; - err = clk_enable(clk); - if (err != 0) { - device_printf(dev, "Could not enable clock %s\n", - clk_get_name(clk)); - goto fail; - } - clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); - clkp->clk = clk; - TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next); - } - if (clkret != 0 && clkret != ENOENT) { - device_printf(dev, "Could not find clock at offset %d (%d)\n", - off, clkret); - goto fail; - } - - sc->sc_busdev = gpiobus_attach_bus(dev); - if (sc->sc_busdev == NULL) - goto fail; - - /* - * Register as a pinctrl device - */ - fdt_pinctrl_register(dev, "pins"); - fdt_pinctrl_configure_tree(dev); - fdt_pinctrl_register(dev, "allwinner,pins"); - fdt_pinctrl_configure_tree(dev); - - return (0); - -fail: - if (sc->sc_irq_res) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); - if (sc->sc_mem_res) - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); - mtx_destroy(&sc->sc_mtx); - - /* Disable clock */ - TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) { - err = clk_disable(clkp->clk); - if (err != 0) - device_printf(dev, "Could not disable clock %s\n", - clk_get_name(clkp->clk)); - err = clk_release(clkp->clk); - if (err != 0) - device_printf(dev, "Could not release clock %s\n", - clk_get_name(clkp->clk)); - TAILQ_REMOVE(&sc->clk_list, clkp, next); - free(clkp, M_DEVBUF); - } - - /* Assert resets */ - if (rst) { - hwreset_assert(rst); - hwreset_release(rst); - } - - return (ENXIO); -} - -static int -a10_gpio_detach(device_t dev) -{ - - return (EBUSY); -} - -static phandle_t -a10_gpio_get_node(device_t dev, device_t bus) -{ - - /* We only have one child, the GPIO bus, which needs our own node. */ - return (ofw_bus_get_node(dev)); -} - -static int -a10_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, - pcell_t *gpios, uint32_t *pin, uint32_t *flags) -{ - struct a10_gpio_softc *sc; - int i; - - sc = device_get_softc(bus); - - /* The GPIO pins are mapped as: . */ - for (i = 0; i < sc->padconf->npins; i++) - if (sc->padconf->pins[i].port == gpios[0] && - sc->padconf->pins[i].pin == gpios[1]) { - *pin = i; - break; - } - *flags = gpios[gcells - 1]; - - return (0); -} - -static device_method_t a10_gpio_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, a10_gpio_probe), - DEVMETHOD(device_attach, a10_gpio_attach), - DEVMETHOD(device_detach, a10_gpio_detach), - - /* GPIO protocol */ - DEVMETHOD(gpio_get_bus, a10_gpio_get_bus), - DEVMETHOD(gpio_pin_max, a10_gpio_pin_max), - DEVMETHOD(gpio_pin_getname, a10_gpio_pin_getname), - DEVMETHOD(gpio_pin_getflags, a10_gpio_pin_getflags), - DEVMETHOD(gpio_pin_getcaps, a10_gpio_pin_getcaps), - DEVMETHOD(gpio_pin_setflags, a10_gpio_pin_setflags), - DEVMETHOD(gpio_pin_get, a10_gpio_pin_get), - DEVMETHOD(gpio_pin_set, a10_gpio_pin_set), - DEVMETHOD(gpio_pin_toggle, a10_gpio_pin_toggle), - DEVMETHOD(gpio_pin_access_32, a10_gpio_pin_access_32), - DEVMETHOD(gpio_pin_config_32, a10_gpio_pin_config_32), - DEVMETHOD(gpio_map_gpios, a10_gpio_map_gpios), - - /* ofw_bus interface */ - DEVMETHOD(ofw_bus_get_node, a10_gpio_get_node), - - /* fdt_pinctrl interface */ - DEVMETHOD(fdt_pinctrl_configure,aw_fdt_configure_pins), - - DEVMETHOD_END -}; - -static devclass_t a10_gpio_devclass; - -static driver_t a10_gpio_driver = { - "gpio", - a10_gpio_methods, - sizeof(struct a10_gpio_softc), -}; - -EARLY_DRIVER_MODULE(a10_gpio, simplebus, a10_gpio_driver, a10_gpio_devclass, 0, 0, - BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); Property changes on: head/sys/arm/allwinner/a10_gpio.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/arm/allwinner/aw_gpio.c =================================================================== --- head/sys/arm/allwinner/aw_gpio.c (nonexistent) +++ head/sys/arm/allwinner/aw_gpio.c (revision 327199) @@ -0,0 +1,1027 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Ganbold Tsagaankhuu + * Copyright (c) 2012 Oleksandr Tymoshenko + * Copyright (c) 2012 Luiz Otavio O Souza. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(__aarch64__) +#include "opt_soc.h" +#endif + +#include "gpio_if.h" + +#define AW_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ + GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) + +#define AW_GPIO_NONE 0 +#define AW_GPIO_PULLUP 1 +#define AW_GPIO_PULLDOWN 2 + +#define AW_GPIO_INPUT 0 +#define AW_GPIO_OUTPUT 1 + +#define AW_GPIO_DRV_MASK 0x3 +#define AW_GPIO_PUD_MASK 0x3 + +#define AW_PINCTRL 1 +#define AW_R_PINCTRL 2 + +/* Defined in aw_padconf.c */ +#ifdef SOC_ALLWINNER_A10 +extern const struct allwinner_padconf a10_padconf; +#endif + +/* Defined in a13_padconf.c */ +#ifdef SOC_ALLWINNER_A13 +extern const struct allwinner_padconf a13_padconf; +#endif + +/* Defined in a20_padconf.c */ +#ifdef SOC_ALLWINNER_A20 +extern const struct allwinner_padconf a20_padconf; +#endif + +/* Defined in a31_padconf.c */ +#ifdef SOC_ALLWINNER_A31 +extern const struct allwinner_padconf a31_padconf; +#endif + +/* Defined in a31s_padconf.c */ +#ifdef SOC_ALLWINNER_A31S +extern const struct allwinner_padconf a31s_padconf; +#endif + +#if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S) +extern const struct allwinner_padconf a31_r_padconf; +#endif + +/* Defined in a33_padconf.c */ +#ifdef SOC_ALLWINNER_A33 +extern const struct allwinner_padconf a33_padconf; +#endif + +/* Defined in h3_padconf.c */ +#if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) +extern const struct allwinner_padconf h3_padconf; +extern const struct allwinner_padconf h3_r_padconf; +#endif + +/* Defined in a83t_padconf.c */ +#ifdef SOC_ALLWINNER_A83T +extern const struct allwinner_padconf a83t_padconf; +extern const struct allwinner_padconf a83t_r_padconf; +#endif + +/* Defined in a64_padconf.c */ +#ifdef SOC_ALLWINNER_A64 +extern const struct allwinner_padconf a64_padconf; +extern const struct allwinner_padconf a64_r_padconf; +#endif + +static struct ofw_compat_data compat_data[] = { +#ifdef SOC_ALLWINNER_A10 + {"allwinner,sun4i-a10-pinctrl", (uintptr_t)&a10_padconf}, +#endif +#ifdef SOC_ALLWINNER_A13 + {"allwinner,sun5i-a13-pinctrl", (uintptr_t)&a13_padconf}, +#endif +#ifdef SOC_ALLWINNER_A20 + {"allwinner,sun7i-a20-pinctrl", (uintptr_t)&a20_padconf}, +#endif +#ifdef SOC_ALLWINNER_A31 + {"allwinner,sun6i-a31-pinctrl", (uintptr_t)&a31_padconf}, +#endif +#ifdef SOC_ALLWINNER_A31S + {"allwinner,sun6i-a31s-pinctrl", (uintptr_t)&a31s_padconf}, +#endif +#if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S) + {"allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&a31_r_padconf}, +#endif +#ifdef SOC_ALLWINNER_A33 + {"allwinner,sun6i-a33-pinctrl", (uintptr_t)&a33_padconf}, +#endif +#ifdef SOC_ALLWINNER_A83T + {"allwinner,sun8i-a83t-pinctrl", (uintptr_t)&a83t_padconf}, + {"allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&a83t_r_padconf}, +#endif +#if defined(SOC_ALLWINNER_H3) || defined(SOC_ALLWINNER_H5) + {"allwinner,sun8i-h3-pinctrl", (uintptr_t)&h3_padconf}, + {"allwinner,sun50i-h5-pinctrl", (uintptr_t)&h3_padconf}, + {"allwinner,sun8i-h3-r-pinctrl", (uintptr_t)&h3_r_padconf}, +#endif +#ifdef SOC_ALLWINNER_A64 + {"allwinner,sun50i-a64-pinctrl", (uintptr_t)&a64_padconf}, + {"allwinner,sun50i-a64-r-pinctrl", (uintptr_t)&a64_r_padconf}, +#endif + {NULL, 0} +}; + +struct clk_list { + TAILQ_ENTRY(clk_list) next; + clk_t clk; +}; + +struct aw_gpio_softc { + device_t sc_dev; + device_t sc_busdev; + struct mtx sc_mtx; + struct resource * sc_mem_res; + struct resource * sc_irq_res; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + void * sc_intrhand; + const struct allwinner_padconf * padconf; + TAILQ_HEAD(, clk_list) clk_list; +}; + +#define AW_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) +#define AW_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx) +#define AW_GPIO_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) + +#define AW_GPIO_GP_CFG(_bank, _idx) 0x00 + ((_bank) * 0x24) + ((_idx) << 2) +#define AW_GPIO_GP_DAT(_bank) 0x10 + ((_bank) * 0x24) +#define AW_GPIO_GP_DRV(_bank, _idx) 0x14 + ((_bank) * 0x24) + ((_idx) << 2) +#define AW_GPIO_GP_PUL(_bank, _idx) 0x1c + ((_bank) * 0x24) + ((_idx) << 2) + +#define AW_GPIO_GP_INT_CFG0 0x200 +#define AW_GPIO_GP_INT_CFG1 0x204 +#define AW_GPIO_GP_INT_CFG2 0x208 +#define AW_GPIO_GP_INT_CFG3 0x20c + +#define AW_GPIO_GP_INT_CTL 0x210 +#define AW_GPIO_GP_INT_STA 0x214 +#define AW_GPIO_GP_INT_DEB 0x218 + +static char *aw_gpio_parse_function(phandle_t node); +static const char **aw_gpio_parse_pins(phandle_t node, int *pins_nb); +static uint32_t aw_gpio_parse_bias(phandle_t node); +static int aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive); + +static int aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value); +static int aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value); +static int aw_gpio_pin_get_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int *value); +static int aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin, unsigned int value); + +#define AW_GPIO_WRITE(_sc, _off, _val) \ + bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) +#define AW_GPIO_READ(_sc, _off) \ + bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off) + +static uint32_t +aw_gpio_get_function(struct aw_gpio_softc *sc, uint32_t pin) +{ + uint32_t bank, func, offset; + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + if (pin > sc->padconf->npins) + return (0); + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + offset = ((pin & 0x07) << 2); + + func = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3)); + + return ((func >> offset) & 0x7); +} + +static int +aw_gpio_set_function(struct aw_gpio_softc *sc, uint32_t pin, uint32_t f) +{ + uint32_t bank, data, offset; + + /* Check if the function exists in the padconf data */ + if (sc->padconf->pins[pin].functions[f] == NULL) + return (EINVAL); + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + offset = ((pin & 0x07) << 2); + + data = AW_GPIO_READ(sc, AW_GPIO_GP_CFG(bank, pin >> 3)); + data &= ~(7 << offset); + data |= (f << offset); + AW_GPIO_WRITE(sc, AW_GPIO_GP_CFG(bank, pin >> 3), data); + + return (0); +} + +static uint32_t +aw_gpio_get_pud(struct aw_gpio_softc *sc, uint32_t pin) +{ + uint32_t bank, offset, val; + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + offset = ((pin & 0x0f) << 1); + + val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4)); + + return ((val >> offset) & AW_GPIO_PUD_MASK); +} + +static void +aw_gpio_set_pud(struct aw_gpio_softc *sc, uint32_t pin, uint32_t state) +{ + uint32_t bank, offset, val; + + if (aw_gpio_get_pud(sc, pin) == state) + return; + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + offset = ((pin & 0x0f) << 1); + + val = AW_GPIO_READ(sc, AW_GPIO_GP_PUL(bank, pin >> 4)); + val &= ~(AW_GPIO_PUD_MASK << offset); + val |= (state << offset); + AW_GPIO_WRITE(sc, AW_GPIO_GP_PUL(bank, pin >> 4), val); +} + +static uint32_t +aw_gpio_get_drv(struct aw_gpio_softc *sc, uint32_t pin) +{ + uint32_t bank, offset, val; + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + offset = ((pin & 0x0f) << 1); + + val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4)); + + return ((val >> offset) & AW_GPIO_DRV_MASK); +} + +static void +aw_gpio_set_drv(struct aw_gpio_softc *sc, uint32_t pin, uint32_t drive) +{ + uint32_t bank, offset, val; + + if (aw_gpio_get_drv(sc, pin) == drive) + return; + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + offset = ((pin & 0x0f) << 1); + + val = AW_GPIO_READ(sc, AW_GPIO_GP_DRV(bank, pin >> 4)); + val &= ~(AW_GPIO_DRV_MASK << offset); + val |= (drive << offset); + AW_GPIO_WRITE(sc, AW_GPIO_GP_DRV(bank, pin >> 4), val); +} + +static int +aw_gpio_pin_configure(struct aw_gpio_softc *sc, uint32_t pin, uint32_t flags) +{ + u_int val; + int err = 0; + + /* Must be called with lock held. */ + AW_GPIO_LOCK_ASSERT(sc); + + if (pin > sc->padconf->npins) + return (EINVAL); + + /* Manage input/output. */ + if (flags & GPIO_PIN_INPUT) { + err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT); + } else if ((flags & GPIO_PIN_OUTPUT) && + aw_gpio_get_function(sc, pin) != AW_GPIO_OUTPUT) { + if (flags & GPIO_PIN_PRESET_LOW) { + aw_gpio_pin_set_locked(sc, pin, 0); + } else if (flags & GPIO_PIN_PRESET_HIGH) { + aw_gpio_pin_set_locked(sc, pin, 1); + } else { + /* Read the pin and preset output to current state. */ + err = aw_gpio_set_function(sc, pin, AW_GPIO_INPUT); + if (err == 0) { + aw_gpio_pin_get_locked(sc, pin, &val); + aw_gpio_pin_set_locked(sc, pin, val); + } + } + if (err == 0) + err = aw_gpio_set_function(sc, pin, AW_GPIO_OUTPUT); + } + + if (err) + return (err); + + /* Manage Pull-up/pull-down. */ + if (flags & GPIO_PIN_PULLUP) + aw_gpio_set_pud(sc, pin, AW_GPIO_PULLUP); + else if (flags & GPIO_PIN_PULLDOWN) + aw_gpio_set_pud(sc, pin, AW_GPIO_PULLDOWN); + else + aw_gpio_set_pud(sc, pin, AW_GPIO_NONE); + + return (0); +} + +static device_t +aw_gpio_get_bus(device_t dev) +{ + struct aw_gpio_softc *sc; + + sc = device_get_softc(dev); + + return (sc->sc_busdev); +} + +static int +aw_gpio_pin_max(device_t dev, int *maxpin) +{ + struct aw_gpio_softc *sc; + + sc = device_get_softc(dev); + + *maxpin = sc->padconf->npins - 1; + return (0); +} + +static int +aw_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) +{ + struct aw_gpio_softc *sc; + + sc = device_get_softc(dev); + if (pin >= sc->padconf->npins) + return (EINVAL); + + *caps = AW_GPIO_DEFAULT_CAPS; + + return (0); +} + +static int +aw_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) +{ + struct aw_gpio_softc *sc; + uint32_t func; + uint32_t pud; + + sc = device_get_softc(dev); + if (pin >= sc->padconf->npins) + return (EINVAL); + + AW_GPIO_LOCK(sc); + func = aw_gpio_get_function(sc, pin); + switch (func) { + case AW_GPIO_INPUT: + *flags = GPIO_PIN_INPUT; + break; + case AW_GPIO_OUTPUT: + *flags = GPIO_PIN_OUTPUT; + break; + default: + *flags = 0; + break; + } + + pud = aw_gpio_get_pud(sc, pin); + switch (pud) { + case AW_GPIO_PULLDOWN: + *flags |= GPIO_PIN_PULLDOWN; + break; + case AW_GPIO_PULLUP: + *flags |= GPIO_PIN_PULLUP; + break; + default: + break; + } + + AW_GPIO_UNLOCK(sc); + + return (0); +} + +static int +aw_gpio_pin_getname(device_t dev, uint32_t pin, char *name) +{ + struct aw_gpio_softc *sc; + + sc = device_get_softc(dev); + if (pin >= sc->padconf->npins) + return (EINVAL); + + snprintf(name, GPIOMAXNAME - 1, "%s", + sc->padconf->pins[pin].name); + name[GPIOMAXNAME - 1] = '\0'; + + return (0); +} + +static int +aw_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) +{ + struct aw_gpio_softc *sc; + int err; + + sc = device_get_softc(dev); + if (pin > sc->padconf->npins) + return (EINVAL); + + AW_GPIO_LOCK(sc); + err = aw_gpio_pin_configure(sc, pin, flags); + AW_GPIO_UNLOCK(sc); + + return (err); +} + +static int +aw_gpio_pin_set_locked(struct aw_gpio_softc *sc, uint32_t pin, + unsigned int value) +{ + uint32_t bank, data; + + AW_GPIO_LOCK_ASSERT(sc); + + if (pin > sc->padconf->npins) + return (EINVAL); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + + data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank)); + if (value) + data |= (1 << pin); + else + data &= ~(1 << pin); + AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data); + + return (0); +} + +static int +aw_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) +{ + struct aw_gpio_softc *sc; + int ret; + + sc = device_get_softc(dev); + + AW_GPIO_LOCK(sc); + ret = aw_gpio_pin_set_locked(sc, pin, value); + AW_GPIO_UNLOCK(sc); + + return (ret); +} + +static int +aw_gpio_pin_get_locked(struct aw_gpio_softc *sc,uint32_t pin, + unsigned int *val) +{ + uint32_t bank, reg_data; + + AW_GPIO_LOCK_ASSERT(sc); + + if (pin > sc->padconf->npins) + return (EINVAL); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + + reg_data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank)); + *val = (reg_data & (1 << pin)) ? 1 : 0; + + return (0); +} + +static char * +aw_gpio_parse_function(phandle_t node) +{ + char *function; + + if (OF_getprop_alloc(node, "function", sizeof(*function), + (void **)&function) != -1) + return (function); + if (OF_getprop_alloc(node, "allwinner,function", sizeof(*function), + (void **)&function) != -1) + return (function); + + return (NULL); +} + +static const char ** +aw_gpio_parse_pins(phandle_t node, int *pins_nb) +{ + const char **pinlist; + + *pins_nb = ofw_bus_string_list_to_array(node, "pins", &pinlist); + if (*pins_nb > 0) + return (pinlist); + + *pins_nb = ofw_bus_string_list_to_array(node, "allwinner,pins", + &pinlist); + if (*pins_nb > 0) + return (pinlist); + + return (NULL); +} + +static uint32_t +aw_gpio_parse_bias(phandle_t node) +{ + uint32_t bias; + + if (OF_getencprop(node, "pull", &bias, sizeof(bias)) != -1) + return (bias); + if (OF_getencprop(node, "allwinner,pull", &bias, sizeof(bias)) != -1) + return (bias); + if (OF_hasprop(node, "bias-disable")) + return (AW_GPIO_NONE); + if (OF_hasprop(node, "bias-pull-up")) + return (AW_GPIO_PULLUP); + if (OF_hasprop(node, "bias-pull-down")) + return (AW_GPIO_PULLDOWN); + + return (AW_GPIO_NONE); +} + +static int +aw_gpio_parse_drive_strength(phandle_t node, uint32_t *drive) +{ + uint32_t drive_str; + + if (OF_getencprop(node, "drive", drive, sizeof(*drive)) != -1) + return (0); + if (OF_getencprop(node, "allwinner,drive", drive, sizeof(*drive)) != -1) + return (0); + if (OF_getencprop(node, "drive-strength", &drive_str, + sizeof(drive_str)) != -1) { + *drive = (drive_str / 10) - 1; + return (0); + } + + return (1); +} + +static int +aw_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) +{ + struct aw_gpio_softc *sc; + int ret; + + sc = device_get_softc(dev); + + AW_GPIO_LOCK(sc); + ret = aw_gpio_pin_get_locked(sc, pin, val); + AW_GPIO_UNLOCK(sc); + + return (ret); +} + +static int +aw_gpio_pin_toggle(device_t dev, uint32_t pin) +{ + struct aw_gpio_softc *sc; + uint32_t bank, data; + + sc = device_get_softc(dev); + if (pin > sc->padconf->npins) + return (EINVAL); + + bank = sc->padconf->pins[pin].port; + pin = sc->padconf->pins[pin].pin; + + AW_GPIO_LOCK(sc); + data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank)); + if (data & (1 << pin)) + data &= ~(1 << pin); + else + data |= (1 << pin); + AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), data); + AW_GPIO_UNLOCK(sc); + + return (0); +} + +static int +aw_gpio_pin_access_32(device_t dev, uint32_t first_pin, uint32_t clear_pins, + uint32_t change_pins, uint32_t *orig_pins) +{ + struct aw_gpio_softc *sc; + uint32_t bank, data, pin; + + sc = device_get_softc(dev); + if (first_pin > sc->padconf->npins) + return (EINVAL); + + /* + * We require that first_pin refers to the first pin in a bank, because + * this API is not about convenience, it's for making a set of pins + * change simultaneously (required) with reasonably high performance + * (desired); we need to do a read-modify-write on a single register. + */ + bank = sc->padconf->pins[first_pin].port; + pin = sc->padconf->pins[first_pin].pin; + if (pin != 0) + return (EINVAL); + + AW_GPIO_LOCK(sc); + data = AW_GPIO_READ(sc, AW_GPIO_GP_DAT(bank)); + if ((clear_pins | change_pins) != 0) + AW_GPIO_WRITE(sc, AW_GPIO_GP_DAT(bank), + (data & ~clear_pins) ^ change_pins); + AW_GPIO_UNLOCK(sc); + + if (orig_pins != NULL) + *orig_pins = data; + + return (0); +} + +static int +aw_gpio_pin_config_32(device_t dev, uint32_t first_pin, uint32_t num_pins, + uint32_t *pin_flags) +{ + struct aw_gpio_softc *sc; + uint32_t bank, pin; + int err; + + sc = device_get_softc(dev); + if (first_pin > sc->padconf->npins) + return (EINVAL); + + bank = sc->padconf->pins[first_pin].port; + if (sc->padconf->pins[first_pin].pin != 0) + return (EINVAL); + + /* + * The configuration for a bank of pins is scattered among several + * registers; we cannot g'tee to simultaneously change the state of all + * the pins in the flags array. So just loop through the array + * configuring each pin for now. If there was a strong need, it might + * be possible to support some limited simultaneous config, such as + * adjacent groups of 8 pins that line up the same as the config regs. + */ + for (err = 0, pin = first_pin; err == 0 && pin < num_pins; ++pin) { + if (pin_flags[pin] & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) + err = aw_gpio_pin_configure(sc, pin, pin_flags[pin]); + } + + return (err); +} + +static int +aw_find_pinnum_by_name(struct aw_gpio_softc *sc, const char *pinname) +{ + int i; + + for (i = 0; i < sc->padconf->npins; i++) + if (!strcmp(pinname, sc->padconf->pins[i].name)) + return i; + + return (-1); +} + +static int +aw_find_pin_func(struct aw_gpio_softc *sc, int pin, const char *func) +{ + int i; + + for (i = 0; i < AW_MAX_FUNC_BY_PIN; i++) + if (sc->padconf->pins[pin].functions[i] && + !strcmp(func, sc->padconf->pins[pin].functions[i])) + return (i); + + return (-1); +} + +static int +aw_fdt_configure_pins(device_t dev, phandle_t cfgxref) +{ + struct aw_gpio_softc *sc; + phandle_t node; + const char **pinlist = NULL; + char *pin_function = NULL; + uint32_t pin_drive, pin_pull; + int pins_nb, pin_num, pin_func, i, ret; + bool set_drive; + + sc = device_get_softc(dev); + node = OF_node_from_xref(cfgxref); + ret = 0; + set_drive = false; + + /* Getting all prop for configuring pins */ + pinlist = aw_gpio_parse_pins(node, &pins_nb); + if (pinlist == NULL) + return (ENOENT); + + pin_function = aw_gpio_parse_function(node); + if (pin_function == NULL) { + ret = ENOENT; + goto out; + } + + if (aw_gpio_parse_drive_strength(node, &pin_drive) == 0) + set_drive = true; + + pin_pull = aw_gpio_parse_bias(node); + + /* Configure each pin to the correct function, drive and pull */ + for (i = 0; i < pins_nb; i++) { + pin_num = aw_find_pinnum_by_name(sc, pinlist[i]); + if (pin_num == -1) { + ret = ENOENT; + goto out; + } + pin_func = aw_find_pin_func(sc, pin_num, pin_function); + if (pin_func == -1) { + ret = ENOENT; + goto out; + } + + AW_GPIO_LOCK(sc); + + if (aw_gpio_get_function(sc, pin_num) != pin_func) + aw_gpio_set_function(sc, pin_num, pin_func); + if (set_drive) + aw_gpio_set_drv(sc, pin_num, pin_drive); + if (pin_pull != AW_GPIO_NONE) + aw_gpio_set_pud(sc, pin_num, pin_pull); + + AW_GPIO_UNLOCK(sc); + } + + out: + OF_prop_free(pinlist); + OF_prop_free(pin_function); + return (ret); +} + +static int +aw_gpio_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "Allwinner GPIO/Pinmux controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +aw_gpio_attach(device_t dev) +{ + int rid, error; + phandle_t gpio; + struct aw_gpio_softc *sc; + struct clk_list *clkp, *clkp_tmp; + clk_t clk; + hwreset_t rst = NULL; + int off, err, clkret; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + + mtx_init(&sc->sc_mtx, "aw gpio", "gpio", MTX_SPIN); + + rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (!sc->sc_mem_res) { + device_printf(dev, "cannot allocate memory window\n"); + goto fail; + } + + sc->sc_bst = rman_get_bustag(sc->sc_mem_res); + sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); + + rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (!sc->sc_irq_res) { + device_printf(dev, "cannot allocate interrupt\n"); + goto fail; + } + + /* Find our node. */ + gpio = ofw_bus_get_node(sc->sc_dev); + if (!OF_hasprop(gpio, "gpio-controller")) + /* Node is not a GPIO controller. */ + goto fail; + + /* Use the right pin data for the current SoC */ + sc->padconf = (struct allwinner_padconf *)ofw_bus_search_compatible(dev, + compat_data)->ocd_data; + + if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) { + error = hwreset_deassert(rst); + if (error != 0) { + device_printf(dev, "cannot de-assert reset\n"); + goto fail; + } + } + + TAILQ_INIT(&sc->clk_list); + for (off = 0, clkret = 0; clkret == 0; off++) { + clkret = clk_get_by_ofw_index(dev, 0, off, &clk); + if (clkret != 0) + break; + err = clk_enable(clk); + if (err != 0) { + device_printf(dev, "Could not enable clock %s\n", + clk_get_name(clk)); + goto fail; + } + clkp = malloc(sizeof(*clkp), M_DEVBUF, M_WAITOK | M_ZERO); + clkp->clk = clk; + TAILQ_INSERT_TAIL(&sc->clk_list, clkp, next); + } + if (clkret != 0 && clkret != ENOENT) { + device_printf(dev, "Could not find clock at offset %d (%d)\n", + off, clkret); + goto fail; + } + + sc->sc_busdev = gpiobus_attach_bus(dev); + if (sc->sc_busdev == NULL) + goto fail; + + /* + * Register as a pinctrl device + */ + fdt_pinctrl_register(dev, "pins"); + fdt_pinctrl_configure_tree(dev); + fdt_pinctrl_register(dev, "allwinner,pins"); + fdt_pinctrl_configure_tree(dev); + + return (0); + +fail: + if (sc->sc_irq_res) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); + if (sc->sc_mem_res) + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); + mtx_destroy(&sc->sc_mtx); + + /* Disable clock */ + TAILQ_FOREACH_SAFE(clkp, &sc->clk_list, next, clkp_tmp) { + err = clk_disable(clkp->clk); + if (err != 0) + device_printf(dev, "Could not disable clock %s\n", + clk_get_name(clkp->clk)); + err = clk_release(clkp->clk); + if (err != 0) + device_printf(dev, "Could not release clock %s\n", + clk_get_name(clkp->clk)); + TAILQ_REMOVE(&sc->clk_list, clkp, next); + free(clkp, M_DEVBUF); + } + + /* Assert resets */ + if (rst) { + hwreset_assert(rst); + hwreset_release(rst); + } + + return (ENXIO); +} + +static int +aw_gpio_detach(device_t dev) +{ + + return (EBUSY); +} + +static phandle_t +aw_gpio_get_node(device_t dev, device_t bus) +{ + + /* We only have one child, the GPIO bus, which needs our own node. */ + return (ofw_bus_get_node(dev)); +} + +static int +aw_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, + pcell_t *gpios, uint32_t *pin, uint32_t *flags) +{ + struct aw_gpio_softc *sc; + int i; + + sc = device_get_softc(bus); + + /* The GPIO pins are mapped as: . */ + for (i = 0; i < sc->padconf->npins; i++) + if (sc->padconf->pins[i].port == gpios[0] && + sc->padconf->pins[i].pin == gpios[1]) { + *pin = i; + break; + } + *flags = gpios[gcells - 1]; + + return (0); +} + +static device_method_t aw_gpio_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, aw_gpio_probe), + DEVMETHOD(device_attach, aw_gpio_attach), + DEVMETHOD(device_detach, aw_gpio_detach), + + /* GPIO protocol */ + DEVMETHOD(gpio_get_bus, aw_gpio_get_bus), + DEVMETHOD(gpio_pin_max, aw_gpio_pin_max), + DEVMETHOD(gpio_pin_getname, aw_gpio_pin_getname), + DEVMETHOD(gpio_pin_getflags, aw_gpio_pin_getflags), + DEVMETHOD(gpio_pin_getcaps, aw_gpio_pin_getcaps), + DEVMETHOD(gpio_pin_setflags, aw_gpio_pin_setflags), + DEVMETHOD(gpio_pin_get, aw_gpio_pin_get), + DEVMETHOD(gpio_pin_set, aw_gpio_pin_set), + DEVMETHOD(gpio_pin_toggle, aw_gpio_pin_toggle), + DEVMETHOD(gpio_pin_access_32, aw_gpio_pin_access_32), + DEVMETHOD(gpio_pin_config_32, aw_gpio_pin_config_32), + DEVMETHOD(gpio_map_gpios, aw_gpio_map_gpios), + + /* ofw_bus interface */ + DEVMETHOD(ofw_bus_get_node, aw_gpio_get_node), + + /* fdt_pinctrl interface */ + DEVMETHOD(fdt_pinctrl_configure,aw_fdt_configure_pins), + + DEVMETHOD_END +}; + +static devclass_t aw_gpio_devclass; + +static driver_t aw_gpio_driver = { + "gpio", + aw_gpio_methods, + sizeof(struct aw_gpio_softc), +}; + +EARLY_DRIVER_MODULE(aw_gpio, simplebus, aw_gpio_driver, aw_gpio_devclass, 0, 0, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); Property changes on: head/sys/arm/allwinner/aw_gpio.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property