diff --git a/Documentation/ABI/testing/configfs-usb-gadget-ffs b/Documentation/ABI/testing/configfs-usb-gadget-ffs new file mode 100644 index 000000000000..14343e237e83 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-ffs @@ -0,0 +1,9 @@ +What: /config/usb-gadget/gadget/functions/ffs.name +Date: Nov 2013 +KenelVersion: 3.13 +Description: The purpose of this directory is to create and remove it. + + A corresponding USB function instance is created/removed. + There are no attributes here. + + All parameters are set through FunctionFS. diff --git a/Documentation/ABI/testing/configfs-usb-gadget-loopback b/Documentation/ABI/testing/configfs-usb-gadget-loopback new file mode 100644 index 000000000000..852b2365a5b5 --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-loopback @@ -0,0 +1,8 @@ +What: /config/usb-gadget/gadget/functions/Loopback.name +Date: Nov 2013 +KenelVersion: 3.13 +Description: + The attributes: + + qlen - depth of loopback queue + bulk_buflen - buffer length diff --git a/Documentation/ABI/testing/configfs-usb-gadget-sourcesink b/Documentation/ABI/testing/configfs-usb-gadget-sourcesink new file mode 100644 index 000000000000..a30f3093ef6c --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-sourcesink @@ -0,0 +1,12 @@ +What: /config/usb-gadget/gadget/functions/SourceSink.name +Date: Nov 2013 +KenelVersion: 3.13 +Description: + The attributes: + + pattern - 0 (all zeros), 1 (mod63), 2 (none) + isoc_interval - 1..16 + isoc_maxpacket - 0 - 1023 (fs), 0 - 1024 (hs/ss) + isoc_mult - 0..2 (hs/ss only) + isoc_maxburst - 0..15 (ss only) + qlen - buffer length diff --git a/Documentation/ABI/testing/debugfs-driver-genwqe b/Documentation/ABI/testing/debugfs-driver-genwqe new file mode 100644 index 000000000000..1c2f25674e8c --- /dev/null +++ b/Documentation/ABI/testing/debugfs-driver-genwqe @@ -0,0 +1,91 @@ +What: /sys/kernel/debug/genwqe/genwqe_card/ddcb_info +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: DDCB queue dump used for debugging queueing problems. + +What: /sys/kernel/debug/genwqe/genwqe_card/curr_regs +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Dump of the current error registers. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/curr_dbg_uid0 +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Internal chip state of UID0 (unit id 0). + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/curr_dbg_uid1 +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Internal chip state of UID1. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/curr_dbg_uid2 +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Internal chip state of UID2. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/prev_regs +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Dump of the error registers before the last reset of + the card occured. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/prev_dbg_uid0 +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Internal chip state of UID0 before card was reset. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/prev_dbg_uid1 +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Internal chip state of UID1 before card was reset. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/prev_dbg_uid2 +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Internal chip state of UID2 before card was reset. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/info +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Comprehensive summary of bitstream version and software + version. Used bitstream and bitstream clocking information. + +What: /sys/kernel/debug/genwqe/genwqe_card/err_inject +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Possibility to inject error cases to ensure that the drivers + error handling code works well. + +What: /sys/kernel/debug/genwqe/genwqe_card/vf<0..14>_jobtimeout_msec +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Default VF timeout 250ms. Testing might require 1000ms. + Using 0 will use the cards default value (whatever that is). + + The timeout depends on the max number of available cards + in the system and the maximum allowed queue size. + + The driver ensures that the settings are done just before + the VFs get enabled. Changing the timeouts in flight is not + possible. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/jobtimer +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Dump job timeout register values for PF and VFs. + Only available for PF. + +What: /sys/kernel/debug/genwqe/genwqe_card/queue_working_time +Date: Dec 2013 +Contact: haver@linux.vnet.ibm.com +Description: Dump queue working time register values for PF and VFs. + Only available for PF. diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci index 5210a51c90fd..a3c5a6685036 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci +++ b/Documentation/ABI/testing/sysfs-bus-pci @@ -70,18 +70,15 @@ Date: September, 2011 Contact: Neil Horman Description: The /sys/devices/.../msi_irqs directory contains a variable set - of sub-directories, with each sub-directory being named after a - corresponding msi irq vector allocated to that device. Each - numbered sub-directory N contains attributes of that irq. - Note that this directory is not created for device drivers which - do not support msi irqs + of files, with each file being named after a corresponding msi + irq vector allocated to that device. -What: /sys/bus/pci/devices/.../msi_irqs//mode +What: /sys/bus/pci/devices/.../msi_irqs/ Date: September 2011 Contact: Neil Horman Description: This attribute indicates the mode that the irq vector named by - the parent directory is in (msi vs. msix) + the file is in (msi vs. msix) What: /sys/bus/pci/devices/.../remove Date: January 2009 diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 1430f584b266..614d451cee41 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -50,13 +50,19 @@ Description: This may allow the driver to support more hardware than was included in the driver's static device ID support table at compile time. The format for the device ID is: - idVendor idProduct bInterfaceClass. + idVendor idProduct bInterfaceClass RefIdVendor RefIdProduct The vendor ID and device ID fields are required, the - interface class is optional. + rest is optional. The Ref* tuple can be used to tell the + driver to use the same driver_data for the new device as + it is used for the reference device. Upon successfully adding an ID, the driver will probe for the device and attempt to bind to it. For example: # echo "8086 10f5" > /sys/bus/usb/drivers/foo/new_id + Here add a new device (0458:7045) using driver_data from + an already supported device (0458:704c): + # echo "0458 7045 0 0458 704c" > /sys/bus/usb/drivers/foo/new_id + Reading from this file will list all dynamically added device IDs in the same format, with one entry per line. For example: diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh index 0baa657b18c4..4793d3dff6af 100644 --- a/Documentation/ABI/testing/sysfs-class-net-mesh +++ b/Documentation/ABI/testing/sysfs-class-net-mesh @@ -68,6 +68,14 @@ Description: Defines the penalty which will be applied to an originator message's tq-field on every hop. +What: /sys/class/net//mesh/isolation_mark +Date: Nov 2013 +Contact: Antonio Quartulli +Description: + Defines the isolation mark (and its bitmask) which + is used to classify clients as "isolated" by the + Extended Isolation feature. + What: /sys/class/net//mesh/network_coding Date: Nov 2012 Contact: Martin Hundeboll diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 468e4d48f884..d5a0d33c571f 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -200,3 +200,27 @@ Description: address and size of the percpu note. note of cpu#. crash_notes_size: size of the note of cpu#. + + +What: /sys/devices/system/cpu/intel_pstate/max_perf_pct + /sys/devices/system/cpu/intel_pstate/min_perf_pct + /sys/devices/system/cpu/intel_pstate/no_turbo +Date: February 2013 +Contact: linux-pm@vger.kernel.org +Description: Parameters for the Intel P-state driver + + Logic for selecting the current P-state in Intel + Sandybridge+ processors. The three knobs control + limits for the P-state that will be requested by the + driver. + + max_perf_pct: limits the maximum P state that will be requested by + the driver stated as a percentage of the available performance. + + min_perf_pct: limits the minimum P state that will be requested by + the driver stated as a percentage of the available performance. + + no_turbo: limits the driver to selecting P states below the turbo + frequency range. + + More details can be found in Documentation/cpu-freq/intel-pstate.txt diff --git a/Documentation/ABI/testing/sysfs-driver-genwqe b/Documentation/ABI/testing/sysfs-driver-genwqe new file mode 100644 index 000000000000..1870737a1f5e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-genwqe @@ -0,0 +1,62 @@ +What: /sys/class/genwqe/genwqe_card/version +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Unique bitstream identification e.g. + '0000000330336283.00000000475a4950'. + +What: /sys/class/genwqe/genwqe_card/appid +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Identifies the currently active card application e.g. 'GZIP' + for compression/decompression. + +What: /sys/class/genwqe/genwqe_card/type +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Type of the card e.g. 'GenWQE5-A7'. + +What: /sys/class/genwqe/genwqe_card/curr_bitstream +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Currently active bitstream. 1 is default, 0 is backup. + +What: /sys/class/genwqe/genwqe_card/next_bitstream +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Interface to set the next bitstream to be used. + +What: /sys/class/genwqe/genwqe_card/tempsens +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Interface to read the cards temperature sense register. + +What: /sys/class/genwqe/genwqe_card/freerunning_timer +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Interface to read the cards free running timer. + Used for performance and utilization measurements. + +What: /sys/class/genwqe/genwqe_card/queue_working_time +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Interface to read queue working time. + Used for performance and utilization measurements. + +What: /sys/class/genwqe/genwqe_card/state +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: State of the card: "unused", "used", "error". + +What: /sys/class/genwqe/genwqe_card/base_clock +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Base clock frequency of the card. + +What: /sys/class/genwqe/genwqe_card/device/sriov_numvfs +Date: Oct 2013 +Contact: haver@linux.vnet.ibm.com +Description: Enable VFs (1..15): + sudo sh -c 'echo 15 > \ + /sys/bus/pci/devices/0000\:1b\:00.0/sriov_numvfs' + Disable VFs: + Write a 0 into the same sysfs entry. diff --git a/Documentation/ABI/testing/sysfs-firmware-efi b/Documentation/ABI/testing/sysfs-firmware-efi new file mode 100644 index 000000000000..05874da7ce80 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-efi @@ -0,0 +1,20 @@ +What: /sys/firmware/efi/fw_vendor +Date: December 2013 +Contact: Dave Young +Description: It shows the physical address of firmware vendor field in the + EFI system table. +Users: Kexec + +What: /sys/firmware/efi/runtime +Date: December 2013 +Contact: Dave Young +Description: It shows the physical address of runtime service table entry in + the EFI system table. +Users: Kexec + +What: /sys/firmware/efi/config_table +Date: December 2013 +Contact: Dave Young +Description: It shows the physical address of config table entry in the EFI + system table. +Users: Kexec diff --git a/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map new file mode 100644 index 000000000000..c61b9b348e99 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-efi-runtime-map @@ -0,0 +1,34 @@ +What: /sys/firmware/efi/runtime-map/ +Date: December 2013 +Contact: Dave Young +Description: Switching efi runtime services to virtual mode requires + that all efi memory ranges which have the runtime attribute + bit set to be mapped to virtual addresses. + + The efi runtime services can only be switched to virtual + mode once without rebooting. The kexec kernel must maintain + the same physical to virtual address mappings as the first + kernel. The mappings are exported to sysfs so userspace tools + can reassemble them and pass them into the kexec kernel. + + /sys/firmware/efi/runtime-map/ is the directory the kernel + exports that information in. + + subdirectories are named with the number of the memory range: + + /sys/firmware/efi/runtime-map/0 + /sys/firmware/efi/runtime-map/1 + /sys/firmware/efi/runtime-map/2 + /sys/firmware/efi/runtime-map/3 + ... + + Each subdirectory contains five files: + + attribute : The attributes of the memory range. + num_pages : The size of the memory range in pages. + phys_addr : The physical address of the memory range. + type : The type of the memory range. + virt_addr : The virtual address of the memory range. + + Above values are all hexadecimal numbers with the '0x' prefix. +Users: Kexec diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 31942efcaf0e..32b0809203dd 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -24,3 +24,34 @@ Date: July 2013 Contact: "Namjae Jeon" Description: Controls the victim selection policy for garbage collection. + +What: /sys/fs/f2fs//reclaim_segments +Date: October 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the issue rate of segment discard commands. + +What: /sys/fs/f2fs//ipu_policy +Date: November 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the in-place-update policy. + +What: /sys/fs/f2fs//min_ipu_util +Date: November 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the FS utilization condition for the in-place-update + policies. + +What: /sys/fs/f2fs//max_small_discards +Date: November 2013 +Contact: "Jaegeuk Kim" +Description: + Controls the issue rate of small discard commands. + +What: /sys/fs/f2fs//max_victim_search +Date: January 2014 +Contact: "Jaegeuk Kim" +Description: + Controls the number of trials to find a victim segment. diff --git a/Documentation/ABI/testing/sysfs-kernel-boot_params b/Documentation/ABI/testing/sysfs-kernel-boot_params new file mode 100644 index 000000000000..eca38ce2852d --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-boot_params @@ -0,0 +1,38 @@ +What: /sys/kernel/boot_params +Date: December 2013 +Contact: Dave Young +Description: The /sys/kernel/boot_params directory contains two + files: "data" and "version" and one subdirectory "setup_data". + It is used to export the kernel boot parameters of an x86 + platform to userspace for kexec and debugging purpose. + + If there's no setup_data in boot_params the subdirectory will + not be created. + + "data" file is the binary representation of struct boot_params. + + "version" file is the string representation of boot + protocol version. + + "setup_data" subdirectory contains the setup_data data + structure in boot_params. setup_data is maintained in kernel + as a link list. In "setup_data" subdirectory there's one + subdirectory for each link list node named with the number + of the list nodes. The list node subdirectory contains two + files "type" and "data". "type" file is the string + representation of setup_data type. "data" file is the binary + representation of setup_data payload. + + The whole boot_params directory structure is like below: + /sys/kernel/boot_params + |__ data + |__ setup_data + | |__ 0 + | | |__ data + | | |__ type + | |__ 1 + | |__ data + | |__ type + |__ version + +Users: Kexec diff --git a/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo b/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo new file mode 100644 index 000000000000..7bd81168e063 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-vmcoreinfo @@ -0,0 +1,14 @@ +What: /sys/kernel/vmcoreinfo +Date: October 2007 +KernelVersion: 2.6.24 +Contact: Ken'ichi Ohmichi + Kexec Mailing List + Vivek Goyal +Description + Shows physical address and size of vmcoreinfo ELF note. + First value contains physical address of note in hex and + second value contains the size of note in hex. This ELF + note info is parsed by second kernel and exported to user + space as part of ELF note in /proc/vmcore file. This note + contains various information like struct size, symbol + values, page size etc. diff --git a/Documentation/ABI/testing/sysfs-platform-tahvo-usb b/Documentation/ABI/testing/sysfs-platform-tahvo-usb new file mode 100644 index 000000000000..f6e20ce4b538 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-tahvo-usb @@ -0,0 +1,16 @@ +What: /sys/bus/platform/devices/tahvo-usb/otg_mode +Date: December 2013 +Contact: Aaro Koskinen +Description: + Set or read the current OTG mode. Valid values are "host" and + "peripheral". + + Reading: returns the current mode. + +What: /sys/bus/platform/devices/tahvo-usb/vbus +Date: December 2013 +Contact: Aaro Koskinen +Description: + Read the current VBUS state. + + Reading: returns "on" or "off". diff --git a/Documentation/DocBook/.gitignore b/Documentation/DocBook/.gitignore index 720f245ceb1f..7ebd5465d927 100644 --- a/Documentation/DocBook/.gitignore +++ b/Documentation/DocBook/.gitignore @@ -10,5 +10,6 @@ *.out *.png *.gif +*.svg media-indices.tmpl media-entities.tmpl diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index bc3d9f8c0a90..0f9c6ff41aac 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -54,6 +54,7 @@ htmldocs: $(HTML) MAN := $(patsubst %.xml, %.9, $(BOOKS)) mandocs: $(MAN) + $(if $(wildcard $(obj)/man/*.9),gzip -f $(obj)/man/*.9) installmandocs: mandocs mkdir -p /usr/local/man/man9/ @@ -145,7 +146,7 @@ build_main_index = rm -rf $(main_idx); \ cat $(HTML) >> $(main_idx) quiet_cmd_db2html = HTML $@ - cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \ + cmd_db2html = xmlto html $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \ echo ' \ $(patsubst %.html,%,$(notdir $@))

' > $@ @@ -159,7 +160,7 @@ quiet_cmd_db2html = HTML $@ cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi quiet_cmd_db2man = MAN $@ - cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; gzip -f $(obj)/man/*.9; fi + cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; fi %.9 : %.xml @(which xmlto > /dev/null 2>&1) || \ (echo "*** You need to install xmlto ***"; \ diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index f75ab4c1b281..ecfd0ea40661 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -109,6 +109,7 @@ X!Ilib/string.c The Slab Cache !Iinclude/linux/slab.h !Emm/slab.c +!Emm/util.c User Space Memory Access !Iarch/x86/include/asm/uaccess_32.h diff --git a/Documentation/HOWTO b/Documentation/HOWTO index 27faae3e3846..57cf5efb044d 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -112,7 +112,7 @@ required reading: Other excellent descriptions of how to create patches properly are: "The Perfect Patch" - http://kerneltrap.org/node/3737 + http://www.ozlabs.org/~akpm/stuff/tpp.txt "Linux kernel patch submission format" http://linux.yyz.us/patch-format.html @@ -579,7 +579,7 @@ all time. It should describe the patch completely, containing: For more details on what this should all look like, please see the ChangeLog section of the document: "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt index 9bc95942ec22..03df71aeb38c 100644 --- a/Documentation/IRQ-domain.txt +++ b/Documentation/IRQ-domain.txt @@ -141,7 +141,7 @@ will use a legacy domain only if an IRQ range is supplied by the system and will otherwise use a linear domain mapping. The semantics of this call are such that if an IRQ range is specified then descriptors will be allocated on-the-fly for it, and if no range is -specified it will fall through to irq_domain_add_linear() which meand +specified it will fall through to irq_domain_add_linear() which means *no* irq descriptors will be allocated. A typical use case for simple domains is where an irqchip provider diff --git a/Documentation/PCI/00-INDEX b/Documentation/PCI/00-INDEX index 812b17fe3ed0..147231f1613e 100644 --- a/Documentation/PCI/00-INDEX +++ b/Documentation/PCI/00-INDEX @@ -2,12 +2,12 @@ - this file MSI-HOWTO.txt - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ. -PCI-DMA-mapping.txt - - info for PCI drivers using DMA portably across all platforms PCIEBUS-HOWTO.txt - a guide describing the PCI Express Port Bus driver pci-error-recovery.txt - info on PCI error recovery +pci-iov-howto.txt + - the PCI Express I/O Virtualization HOWTO pci.txt - info on the PCI subsystem for device driver authors pcieaer-howto.txt diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a09178086c30..a8d01005f480 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -82,93 +82,111 @@ Most of the hard work is done for the driver in the PCI layer. It simply has to request that the PCI layer set up the MSI capability for this device. -4.2.1 pci_enable_msi +4.2.1 pci_enable_msi_range -int pci_enable_msi(struct pci_dev *dev) +int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) -A successful call allocates ONE interrupt to the device, regardless -of how many MSIs the device supports. The device is switched from -pin-based interrupt mode to MSI mode. The dev->irq number is changed -to a new number which represents the message signaled interrupt; -consequently, this function should be called before the driver calls -request_irq(), because an MSI is delivered via a vector that is -different from the vector of a pin-based interrupt. +This function allows a device driver to request any number of MSI +interrupts within specified range from 'minvec' to 'maxvec'. -4.2.2 pci_enable_msi_block - -int pci_enable_msi_block(struct pci_dev *dev, int count) - -This variation on the above call allows a device driver to request multiple -MSIs. The MSI specification only allows interrupts to be allocated in -powers of two, up to a maximum of 2^5 (32). - -If this function returns 0, it has succeeded in allocating at least as many -interrupts as the driver requested (it may have allocated more in order -to satisfy the power-of-two requirement). In this case, the function -enables MSI on this device and updates dev->irq to be the lowest of -the new interrupts assigned to it. The other interrupts assigned to -the device are in the range dev->irq to dev->irq + count - 1. - -If this function returns a negative number, it indicates an error and -the driver should not attempt to request any more MSI interrupts for -this device. If this function returns a positive number, it is -less than 'count' and indicates the number of interrupts that could have -been allocated. In neither case is the irq value updated or the device -switched into MSI mode. - -The device driver must decide what action to take if -pci_enable_msi_block() returns a value less than the number requested. -For instance, the driver could still make use of fewer interrupts; -in this case the driver should call pci_enable_msi_block() -again. Note that it is not guaranteed to succeed, even when the -'count' has been reduced to the value returned from a previous call to -pci_enable_msi_block(). This is because there are multiple constraints -on the number of vectors that can be allocated; pci_enable_msi_block() -returns as soon as it finds any constraint that doesn't allow the -call to succeed. - -4.2.3 pci_enable_msi_block_auto - -int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *count) - -This variation on pci_enable_msi() call allows a device driver to request -the maximum possible number of MSIs. The MSI specification only allows -interrupts to be allocated in powers of two, up to a maximum of 2^5 (32). - -If this function returns a positive number, it indicates that it has -succeeded and the returned value is the number of allocated interrupts. In -this case, the function enables MSI on this device and updates dev->irq to -be the lowest of the new interrupts assigned to it. The other interrupts -assigned to the device are in the range dev->irq to dev->irq + returned -value - 1. +If this function returns a positive number it indicates the number of +MSI interrupts that have been successfully allocated. In this case +the device is switched from pin-based interrupt mode to MSI mode and +updates dev->irq to be the lowest of the new interrupts assigned to it. +The other interrupts assigned to the device are in the range dev->irq +to dev->irq + returned value - 1. Device driver can use the returned +number of successfully allocated MSI interrupts to further allocate +and initialize device resources. If this function returns a negative number, it indicates an error and the driver should not attempt to request any more MSI interrupts for this device. -If the device driver needs to know the number of interrupts the device -supports it can pass the pointer count where that number is stored. The -device driver must decide what action to take if pci_enable_msi_block_auto() -succeeds, but returns a value less than the number of interrupts supported. -If the device driver does not need to know the number of interrupts -supported, it can set the pointer count to NULL. +This function should be called before the driver calls request_irq(), +because MSI interrupts are delivered via vectors that are different +from the vector of a pin-based interrupt. -4.2.4 pci_disable_msi +It is ideal if drivers can cope with a variable number of MSI interrupts; +there are many reasons why the platform may not be able to provide the +exact number that a driver asks for. + +There could be devices that can not operate with just any number of MSI +interrupts within a range. See chapter 4.3.1.3 to get the idea how to +handle such devices for MSI-X - the same logic applies to MSI. + +4.2.1.1 Maximum possible number of MSI interrupts + +The typical usage of MSI interrupts is to allocate as many vectors as +possible, likely up to the limit returned by pci_msi_vec_count() function: + +static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) +{ + return pci_enable_msi_range(pdev, 1, nvec); +} + +Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, +the value of 0 would be meaningless and could result in error. + +Some devices have a minimal limit on number of MSI interrupts. +In this case the function could look like this: + +static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) +{ + return pci_enable_msi_range(pdev, FOO_DRIVER_MINIMUM_NVEC, nvec); +} + +4.2.1.2 Exact number of MSI interrupts + +If a driver is unable or unwilling to deal with a variable number of MSI +interrupts it could request a particular number of interrupts by passing +that number to pci_enable_msi_range() function as both 'minvec' and 'maxvec' +parameters: + +static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec) +{ + return pci_enable_msi_range(pdev, nvec, nvec); +} + +4.2.1.3 Single MSI mode + +The most notorious example of the request type described above is +enabling the single MSI mode for a device. It could be done by passing +two 1s as 'minvec' and 'maxvec': + +static int foo_driver_enable_single_msi(struct pci_dev *pdev) +{ + return pci_enable_msi_range(pdev, 1, 1); +} + +4.2.2 pci_disable_msi void pci_disable_msi(struct pci_dev *dev) -This function should be used to undo the effect of pci_enable_msi() or -pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores -dev->irq to the pin-based interrupt number and frees the previously -allocated message signaled interrupt(s). The interrupt may subsequently be -assigned to another device, so drivers should not cache the value of -dev->irq. +This function should be used to undo the effect of pci_enable_msi_range(). +Calling it restores dev->irq to the pin-based interrupt number and frees +the previously allocated MSIs. The interrupts may subsequently be assigned +to another device, so drivers should not cache the value of dev->irq. Before calling this function, a device driver must always call free_irq() on any interrupt for which it previously called request_irq(). Failure to do so results in a BUG_ON(), leaving the device with MSI enabled and thus leaking its vector. +4.2.3 pci_msi_vec_count + +int pci_msi_vec_count(struct pci_dev *dev) + +This function could be used to retrieve the number of MSI vectors the +device requested (via the Multiple Message Capable register). The MSI +specification only allows the returned value to be a power of two, +up to a maximum of 2^5 (32). + +If this function returns a negative number, it indicates the device is +not capable of sending MSIs. + +If this function returns a positive number, it indicates the maximum +number of MSI interrupt vectors that could be allocated. + 4.3 Using MSI-X The MSI-X capability is much more flexible than the MSI capability. @@ -188,26 +206,31 @@ in each element of the array to indicate for which entries the kernel should assign interrupts; it is invalid to fill in two entries with the same number. -4.3.1 pci_enable_msix +4.3.1 pci_enable_msix_range -int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) +int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, + int minvec, int maxvec) -Calling this function asks the PCI subsystem to allocate 'nvec' MSIs. +Calling this function asks the PCI subsystem to allocate any number of +MSI-X interrupts within specified range from 'minvec' to 'maxvec'. The 'entries' argument is a pointer to an array of msix_entry structs -which should be at least 'nvec' entries in size. On success, the -device is switched into MSI-X mode and the function returns 0. -The 'vector' member in each entry is populated with the interrupt number; +which should be at least 'maxvec' entries in size. + +On success, the device is switched into MSI-X mode and the function +returns the number of MSI-X interrupts that have been successfully +allocated. In this case the 'vector' member in entries numbered from +0 to the returned value - 1 is populated with the interrupt number; the driver should then call request_irq() for each 'vector' that it decides to use. The device driver is responsible for keeping track of the interrupts assigned to the MSI-X vectors so it can free them again later. +Device driver can use the returned number of successfully allocated MSI-X +interrupts to further allocate and initialize device resources. If this function returns a negative number, it indicates an error and the driver should not attempt to allocate any more MSI-X interrupts for -this device. If it returns a positive number, it indicates the maximum -number of interrupt vectors that could have been allocated. See example -below. +this device. -This function, in contrast with pci_enable_msi(), does not adjust +This function, in contrast with pci_enable_msi_range(), does not adjust dev->irq. The device will not generate interrupts for this interrupt number once MSI-X is enabled. @@ -218,28 +241,103 @@ It is ideal if drivers can cope with a variable number of MSI-X interrupts; there are many reasons why the platform may not be able to provide the exact number that a driver asks for. -A request loop to achieve that might look like: +There could be devices that can not operate with just any number of MSI-X +interrupts within a range. E.g., an network adapter might need let's say +four vectors per each queue it provides. Therefore, a number of MSI-X +interrupts allocated should be a multiple of four. In this case interface +pci_enable_msix_range() can not be used alone to request MSI-X interrupts +(since it can allocate any number within the range, without any notion of +the multiple of four) and the device driver should master a custom logic +to request the required number of MSI-X interrupts. + +4.3.1.1 Maximum possible number of MSI-X interrupts + +The typical usage of MSI-X interrupts is to allocate as many vectors as +possible, likely up to the limit returned by pci_msix_vec_count() function: static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) { - while (nvec >= FOO_DRIVER_MINIMUM_NVEC) { - rc = pci_enable_msix(adapter->pdev, - adapter->msix_entries, nvec); - if (rc > 0) - nvec = rc; - else - return rc; + return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, + 1, nvec); +} + +Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive, +the value of 0 would be meaningless and could result in error. + +Some devices have a minimal limit on number of MSI-X interrupts. +In this case the function could look like this: + +static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) +{ + return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, + FOO_DRIVER_MINIMUM_NVEC, nvec); +} + +4.3.1.2 Exact number of MSI-X interrupts + +If a driver is unable or unwilling to deal with a variable number of MSI-X +interrupts it could request a particular number of interrupts by passing +that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec' +parameters: + +static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec) +{ + return pci_enable_msi_range(adapter->pdev, adapter->msix_entries, + nvec, nvec); +} + +4.3.1.3 Specific requirements to the number of MSI-X interrupts + +As noted above, there could be devices that can not operate with just any +number of MSI-X interrupts within a range. E.g., let's assume a device that +is only capable sending the number of MSI-X interrupts which is a power of +two. A routine that enables MSI-X mode for such device might look like this: + +/* + * Assume 'minvec' and 'maxvec' are non-zero + */ +static int foo_driver_enable_msix(struct foo_adapter *adapter, + int minvec, int maxvec) +{ + int rc; + + minvec = roundup_pow_of_two(minvec); + maxvec = rounddown_pow_of_two(maxvec); + + if (minvec > maxvec) + return -ERANGE; + +retry: + rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries, + maxvec, maxvec); + /* + * -ENOSPC is the only error code allowed to be analized + */ + if (rc == -ENOSPC) { + if (maxvec == 1) + return -ENOSPC; + + maxvec /= 2; + + if (minvec > maxvec) + return -ENOSPC; + + goto retry; } - return -ENOSPC; + return rc; } +Note how pci_enable_msix_range() return value is analized for a fallback - +any error code other than -ENOSPC indicates a fatal error and should not +be retried. + 4.3.2 pci_disable_msix void pci_disable_msix(struct pci_dev *dev) -This function should be used to undo the effect of pci_enable_msix(). It frees -the previously allocated message signaled interrupts. The interrupts may +This function should be used to undo the effect of pci_enable_msix_range(). +It frees the previously allocated MSI-X interrupts. The interrupts may subsequently be assigned to another device, so drivers should not cache the value of the 'vector' elements over a call to pci_disable_msix(). @@ -255,18 +353,32 @@ MSI-X Table. This address is mapped by the PCI subsystem, and should not be accessed directly by the device driver. If the driver wishes to mask or unmask an interrupt, it should call disable_irq() / enable_irq(). +4.3.4 pci_msix_vec_count + +int pci_msix_vec_count(struct pci_dev *dev) + +This function could be used to retrieve number of entries in the device +MSI-X table. + +If this function returns a negative number, it indicates the device is +not capable of sending MSI-Xs. + +If this function returns a positive number, it indicates the maximum +number of MSI-X interrupt vectors that could be allocated. + 4.4 Handling devices implementing both MSI and MSI-X capabilities If a device implements both MSI and MSI-X capabilities, it can run in either MSI mode or MSI-X mode, but not both simultaneously. This is a requirement of the PCI spec, and it is enforced by the -PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or -pci_enable_msix() when MSI is already enabled results in an error. -If a device driver wishes to switch between MSI and MSI-X at runtime, -it must first quiesce the device, then switch it back to pin-interrupt -mode, before calling pci_enable_msi() or pci_enable_msix() and resuming -operation. This is not expected to be a common operation but may be -useful for debugging or testing during development. +PCI layer. Calling pci_enable_msi_range() when MSI-X is already +enabled or pci_enable_msix_range() when MSI is already enabled +results in an error. If a device driver wishes to switch between MSI +and MSI-X at runtime, it must first quiesce the device, then switch +it back to pin-interrupt mode, before calling pci_enable_msi_range() +or pci_enable_msix_range() and resuming operation. This is not expected +to be a common operation but may be useful for debugging or testing +during development. 4.5 Considerations when using MSIs @@ -381,5 +493,5 @@ or disabled (0). If 0 is found in any of the msi_bus files belonging to bridges between the PCI root and the device, MSIs are disabled. It is also worth checking the device driver to see whether it supports MSIs. -For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or -pci_enable_msi_block(). +For example, it may contain calls to pci_enable_msi_range() or +pci_enable_msix_range(). diff --git a/Documentation/PCI/pci.txt b/Documentation/PCI/pci.txt index 6f458564d625..9518006f6675 100644 --- a/Documentation/PCI/pci.txt +++ b/Documentation/PCI/pci.txt @@ -123,8 +123,10 @@ initialization with a pointer to a structure describing the driver The ID table is an array of struct pci_device_id entries ending with an -all-zero entry; use of the macro DEFINE_PCI_DEVICE_TABLE is the preferred -method of declaring the table. Each entry consists of: +all-zero entry. Definitions with static const are generally preferred. +Use of the deprecated macro DEFINE_PCI_DEVICE_TABLE should be avoided. + +Each entry consists of: vendor,device Vendor and device ID to match (or PCI_ANY_ID) diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt index f3778f8952da..910870b15acd 100644 --- a/Documentation/RCU/trace.txt +++ b/Documentation/RCU/trace.txt @@ -396,14 +396,14 @@ o Each element of the form "3/3 ..>. 0:7 ^0" represents one rcu_node The output of "cat rcu/rcu_sched/rcu_pending" looks as follows: - 0!np=26111 qsp=29 rpq=5386 cbr=1 cng=570 gpc=3674 gps=577 nn=15903 - 1!np=28913 qsp=35 rpq=6097 cbr=1 cng=448 gpc=3700 gps=554 nn=18113 - 2!np=32740 qsp=37 rpq=6202 cbr=0 cng=476 gpc=4627 gps=546 nn=20889 - 3 np=23679 qsp=22 rpq=5044 cbr=1 cng=415 gpc=3403 gps=347 nn=14469 - 4!np=30714 qsp=4 rpq=5574 cbr=0 cng=528 gpc=3931 gps=639 nn=20042 - 5 np=28910 qsp=2 rpq=5246 cbr=0 cng=428 gpc=4105 gps=709 nn=18422 - 6!np=38648 qsp=5 rpq=7076 cbr=0 cng=840 gpc=4072 gps=961 nn=25699 - 7 np=37275 qsp=2 rpq=6873 cbr=0 cng=868 gpc=3416 gps=971 nn=25147 + 0!np=26111 qsp=29 rpq=5386 cbr=1 cng=570 gpc=3674 gps=577 nn=15903 ndw=0 + 1!np=28913 qsp=35 rpq=6097 cbr=1 cng=448 gpc=3700 gps=554 nn=18113 ndw=0 + 2!np=32740 qsp=37 rpq=6202 cbr=0 cng=476 gpc=4627 gps=546 nn=20889 ndw=0 + 3 np=23679 qsp=22 rpq=5044 cbr=1 cng=415 gpc=3403 gps=347 nn=14469 ndw=0 + 4!np=30714 qsp=4 rpq=5574 cbr=0 cng=528 gpc=3931 gps=639 nn=20042 ndw=0 + 5 np=28910 qsp=2 rpq=5246 cbr=0 cng=428 gpc=4105 gps=709 nn=18422 ndw=0 + 6!np=38648 qsp=5 rpq=7076 cbr=0 cng=840 gpc=4072 gps=961 nn=25699 ndw=0 + 7 np=37275 qsp=2 rpq=6873 cbr=0 cng=868 gpc=3416 gps=971 nn=25147 ndw=0 The fields are as follows: @@ -432,6 +432,10 @@ o "gpc" is the number of times that an old grace period had o "gps" is the number of times that a new grace period had started, but this CPU was not yet aware of it. +o "ndw" is the number of times that a wakeup of an rcuo + callback-offload kthread had to be deferred in order to avoid + deadlock. + o "nn" is the number of times that this CPU needed nothing. @@ -443,7 +447,7 @@ The output of "cat rcu/rcuboost" looks as follows: balk: nt=0 egt=6541 bt=0 nb=0 ny=126 nos=0 This information is output only for rcu_preempt. Each two-line entry -corresponds to a leaf rcu_node strcuture. The fields are as follows: +corresponds to a leaf rcu_node structure. The fields are as follows: o "n:m" is the CPU-number range for the corresponding two-line entry. In the sample output above, the first entry covers diff --git a/Documentation/acpi/apei/einj.txt b/Documentation/acpi/apei/einj.txt index a58b63da1a36..f51861bcb07b 100644 --- a/Documentation/acpi/apei/einj.txt +++ b/Documentation/acpi/apei/einj.txt @@ -45,11 +45,22 @@ directory apei/einj. The following files are provided. injection. Before this, please specify all necessary error parameters. +- flags + Present for kernel version 3.13 and above. Used to specify which + of param{1..4} are valid and should be used by BIOS during injection. + Value is a bitmask as specified in ACPI5.0 spec for the + SET_ERROR_TYPE_WITH_ADDRESS data structure: + Bit 0 - Processor APIC field valid (see param3 below) + Bit 1 - Memory address and mask valid (param1 and param2) + Bit 2 - PCIe (seg,bus,dev,fn) valid (param4 below) + If set to zero, legacy behaviour is used where the type of injection + specifies just one bit set, and param1 is multiplexed. + - param1 This file is used to set the first error parameter value. Effect of parameter depends on error_type specified. For example, if error type is memory related type, the param1 should be a valid physical - memory address. + memory address. [Unless "flag" is set - see above] - param2 This file is used to set the second error parameter value. Effect of @@ -58,6 +69,12 @@ directory apei/einj. The following files are provided. address mask. Linux requires page or narrower granularity, say, 0xfffffffffffff000. +- param3 + Used when the 0x1 bit is set in "flag" to specify the APIC id + +- param4 + Used when the 0x4 bit is set in "flag" to specify target PCIe device + - notrigger The EINJ mechanism is a two step process. First inject the error, then perform some actions to trigger it. Setting "notrigger" to 1 skips the diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt index b994bcb32b92..2a1519b87177 100644 --- a/Documentation/acpi/enumeration.txt +++ b/Documentation/acpi/enumeration.txt @@ -293,36 +293,13 @@ the device to the driver. For example: These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0" specifies the path to the controller. In order to use these GPIOs in Linux -we need to translate them to the Linux GPIO numbers. +we need to translate them to the corresponding Linux GPIO descriptors. -In a simple case of just getting the Linux GPIO number from device -resources one can use acpi_get_gpio_by_index() helper function. It takes -pointer to the device and index of the GpioIo/GpioInt descriptor in the -device resources list. For example: +There is a standard GPIO API for that and is documented in +Documentation/gpio.txt. - int gpio_irq, gpio_power; - int ret; - - gpio_irq = acpi_get_gpio_by_index(dev, 1, NULL); - if (gpio_irq < 0) - /* handle error */ - - gpio_power = acpi_get_gpio_by_index(dev, 0, NULL); - if (gpio_power < 0) - /* handle error */ - - /* Now we can use the GPIO numbers */ - -Other GpioIo parameters must be converted first by the driver to be -suitable to the gpiolib before passing them. - -In case of GpioInt resource an additional call to gpio_to_irq() must be -done before calling request_irq(). - -Note that the above API is ACPI specific and not recommended for drivers -that need to support non-ACPI systems. The recommended way is to use -the descriptor based GPIO interfaces. The above example looks like this -when converted to the GPIO desc: +In the above example we can get the corresponding two GPIO descriptors with +a code like this: #include ... @@ -339,4 +316,5 @@ when converted to the GPIO desc: /* Now we can use the GPIO descriptors */ -See also Documentation/gpio.txt. +There are also devm_* versions of these functions which release the +descriptors once the device is released. diff --git a/Documentation/acpi/namespace.txt b/Documentation/acpi/namespace.txt index 260f6a3661fa..1860cb3865c6 100644 --- a/Documentation/acpi/namespace.txt +++ b/Documentation/acpi/namespace.txt @@ -235,10 +235,6 @@ Wysocki . named object's type in the second column). In that case the object's directory in sysfs will contain the 'path' attribute whose value is the full path to the node from the namespace root. - struct acpi_device objects are created for the ACPI namespace nodes - whose _STA control methods return PRESENT or FUNCTIONING. The power - resource nodes or nodes without _STA are assumed to be both PRESENT - and FUNCTIONING. F: The struct acpi_device object is created for a fixed hardware feature (as indicated by the fixed feature flag's name in the second @@ -340,7 +336,7 @@ Wysocki . | +-------------+-------+----------------+ | | | | +- - - - - - - +- - - - - - +- - - - - - - -+ - | +-| * PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: | + | +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: | | | +- - - - - - - +- - - - - - +- - - - - - - -+ | | | | +------------+------------+-----------------------+ @@ -390,6 +386,3 @@ Wysocki . attribute (as described earlier in this document). NOTE: N/A indicates the device object does not have the 'path' or the 'modalias' attribute. - NOTE: The PNP0C0D device listed above is highlighted (marked by "*") - to indicate it will be created only when its _STA methods return - PRESENT or FUNCTIONING. diff --git a/Documentation/arm/Marvell/README b/Documentation/arm/Marvell/README index da0151db9964..5a930c1528ad 100644 --- a/Documentation/arm/Marvell/README +++ b/Documentation/arm/Marvell/README @@ -211,6 +211,30 @@ MMP/MMP2 family (communication processor) Linux kernel mach directory: arch/arm/mach-mmp Linux kernel plat directory: arch/arm/plat-pxa +Berlin family (Digital Entertainment) +------------------------------------- + + Flavors: + 88DE3005, Armada 1500-mini + Design name: BG2CD + Core: ARM Cortex-A9, PL310 L2CC + Homepage: http://www.marvell.com/digital-entertainment/armada-1500-mini/ + 88DE3100, Armada 1500 + Design name: BG2 + Core: Marvell PJ4B (ARMv7), Tauros3 L2CC + Homepage: http://www.marvell.com/digital-entertainment/armada-1500/ + Product Brief: http://www.marvell.com/digital-entertainment/armada-1500/assets/Marvell-ARMADA-1500-Product-Brief.pdf + 88DE???? + Design name: BG3 + Core: ARM Cortex-A15, CA15 integrated L2CC + + Homepage: http://www.marvell.com/digital-entertainment/ + Directory: arch/arm/mach-berlin + + Comments: + * This line of SoCs is based on Marvell Sheeva or ARM Cortex CPUs + with Synopsys DesignWare (IRQ, GPIO, Timers, ...) and PXA IP (SDHCI, USB, ETH, ...). + Long-term plans --------------- diff --git a/Documentation/arm/Samsung-S3C24XX/GPIO.txt b/Documentation/arm/Samsung-S3C24XX/GPIO.txt index 8b46c79679c4..0ebd7e2244d0 100644 --- a/Documentation/arm/Samsung-S3C24XX/GPIO.txt +++ b/Documentation/arm/Samsung-S3C24XX/GPIO.txt @@ -85,21 +85,10 @@ between the calls. Headers ------- - See arch/arm/mach-s3c2410/include/mach/regs-gpio.h for the list + See arch/arm/mach-s3c24xx/include/mach/regs-gpio.h for the list of GPIO pins, and the configuration values for them. This is included by using #include - The GPIO management functions are defined in the hardware - header arch/arm/mach-s3c2410/include/mach/hardware.h which can be - included by #include - - A useful amount of documentation can be found in the hardware - header on how the GPIO functions (and others) work. - - Whilst a number of these functions do make some checks on what - is passed to them, for speed of use, they may not always ensure - that the user supplied data to them is correct. - PIN Numbers ----------- diff --git a/Documentation/block/null_blk.txt b/Documentation/block/null_blk.txt new file mode 100644 index 000000000000..b2830b435895 --- /dev/null +++ b/Documentation/block/null_blk.txt @@ -0,0 +1,72 @@ +Null block device driver +================================================================================ + +I. Overview + +The null block device (/dev/nullb*) is used for benchmarking the various +block-layer implementations. It emulates a block device of X gigabytes in size. +The following instances are possible: + + Single-queue block-layer + - Request-based. + - Single submission queue per device. + - Implements IO scheduling algorithms (CFQ, Deadline, noop). + Multi-queue block-layer + - Request-based. + - Configurable submission queues per device. + No block-layer (Known as bio-based) + - Bio-based. IO requests are submitted directly to the device driver. + - Directly accepts bio data structure and returns them. + +All of them have a completion queue for each core in the system. + +II. Module parameters applicable for all instances: + +queue_mode=[0-2]: Default: 2-Multi-queue + Selects which block-layer the module should instantiate with. + + 0: Bio-based. + 1: Single-queue. + 2: Multi-queue. + +home_node=[0--nr_nodes]: Default: NUMA_NO_NODE + Selects what CPU node the data structures are allocated from. + +gb=[Size in GB]: Default: 250GB + The size of the device reported to the system. + +bs=[Block size (in bytes)]: Default: 512 bytes + The block size reported to the system. + +nr_devices=[Number of devices]: Default: 2 + Number of block devices instantiated. They are instantiated as /dev/nullb0, + etc. + +irq_mode=[0-2]: Default: 1-Soft-irq + The completion mode used for completing IOs to the block-layer. + + 0: None. + 1: Soft-irq. Uses IPI to complete IOs across CPU nodes. Simulates the overhead + when IOs are issued from another CPU node than the home the device is + connected to. + 2: Timer: Waits a specific period (completion_nsec) for each IO before + completion. + +completion_nsec=[ns]: Default: 10.000ns + Combined with irq_mode=2 (timer). The time each completion event must wait. + +submit_queues=[0..nr_cpus]: + The number of submission queues attached to the device driver. If unset, it + defaults to 1 on single-queue and bio-based instances. For multi-queue, + it is ignored when use_per_node_hctx module parameter is 1. + +hw_queue_depth=[0..qdepth]: Default: 64 + The hardware queue depth of the device. + +III: Multi-queue specific parameters + +use_per_node_hctx=[0/1]: Default: 0 + 0: The number of submit queues are set to the value of the submit_queues + parameter. + 1: The multi-queue block layer is instantiated with a hardware dispatch + queue for each CPU node in the system. diff --git a/Documentation/blockdev/ramdisk.txt b/Documentation/blockdev/ramdisk.txt index fa72e97dd669..fe2ef978d85a 100644 --- a/Documentation/blockdev/ramdisk.txt +++ b/Documentation/blockdev/ramdisk.txt @@ -36,21 +36,30 @@ allowing one to squeeze more programs onto an average installation or rescue floppy disk. -2) Kernel Command Line Parameters +2) Parameters --------------------------------- +2a) Kernel Command Line Parameters + ramdisk_size=N ============== This parameter tells the RAM disk driver to set up RAM disks of N k size. The -default is 4096 (4 MB) (8192 (8 MB) on S390). +default is 4096 (4 MB). - ramdisk_blocksize=N - =================== +2b) Module parameters -This parameter tells the RAM disk driver how many bytes to use per block. The -default is 1024 (BLOCK_SIZE). + rd_nr + ===== + /dev/ramX devices created. + max_part + ======== + Maximum partition number. + + rd_size + ======= + See ramdisk_size. 3) Using "rdev -r" ------------------ diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index 638bf17ff869..821de56d1580 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -24,7 +24,6 @@ CONTENTS: 2.1 Basic Usage 2.2 Attaching processes 2.3 Mounting hierarchies by name - 2.4 Notification API 3. Kernel API 3.1 Overview 3.2 Synchronization @@ -472,25 +471,6 @@ you give a subsystem a name. The name of the subsystem appears as part of the hierarchy description in /proc/mounts and /proc//cgroups. -2.4 Notification API --------------------- - -There is mechanism which allows to get notifications about changing -status of a cgroup. - -To register a new notification handler you need to: - - create a file descriptor for event notification using eventfd(2); - - open a control file to be monitored (e.g. memory.usage_in_bytes); - - write " " to cgroup.event_control. - Interpretation of args is defined by control file implementation; - -eventfd will be woken up by control file implementation or when the -cgroup is removed. - -To unregister a notification handler just close eventfd. - -NOTE: Support of notifications should be implemented for the control -file. See documentation for the subsystem. 3. Kernel API ============= diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index e2bc132608fd..2622115276aa 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt @@ -577,7 +577,7 @@ Each memcg's numa_stat file includes "total", "file", "anon" and "unevictable" per-node page counts including "hierarchical_" which sums up all hierarchical children's values in addition to the memcg's own value. -The ouput format of memory.numa_stat is: +The output format of memory.numa_stat is: total= N0= N1= ... file= N0= N1= ... @@ -670,7 +670,7 @@ page tables. 8.1 Interface -This feature is disabled by default. It can be enabledi (and disabled again) by +This feature is disabled by default. It can be enabled (and disabled again) by writing to memory.move_charge_at_immigrate of the destination cgroup. If you want to enable it: diff --git a/Documentation/cgroups/net_cls.txt b/Documentation/cgroups/net_cls.txt index 9face6bb578a..ec182346dea2 100644 --- a/Documentation/cgroups/net_cls.txt +++ b/Documentation/cgroups/net_cls.txt @@ -6,6 +6,8 @@ tag network packets with a class identifier (classid). The Traffic Controller (tc) can be used to assign different priorities to packets from different cgroups. +Also, Netfilter (iptables) can use this tag to perform +actions on such packets. Creating a net_cls cgroups instance creates a net_cls.classid file. This net_cls.classid value is initialized to 0. @@ -32,3 +34,6 @@ tc class add dev eth0 parent 10: classid 10:1 htb rate 40mbit - creating traffic class 10:1 tc filter add dev eth0 parent 10: protocol ip prio 10 handle 1: cgroup + +configuring iptables, basic example: +iptables -A OUTPUT -m cgroup ! --cgroup 0x100001 -j DROP diff --git a/Documentation/cgroups/resource_counter.txt b/Documentation/cgroups/resource_counter.txt index c4d99ed0b418..52e1da16a309 100644 --- a/Documentation/cgroups/resource_counter.txt +++ b/Documentation/cgroups/resource_counter.txt @@ -97,8 +97,8 @@ to work with it. (struct res_counter *rc, struct res_counter *top, unsinged long val) - Almost same as res_cunter_uncharge() but propagation of uncharge - stops when rc == top. This is useful when kill a res_coutner in + Almost same as res_counter_uncharge() but propagation of uncharge + stops when rc == top. This is useful when kill a res_counter in child cgroup. 2.1 Other accounting routines diff --git a/Documentation/circular-buffers.txt b/Documentation/circular-buffers.txt index 8117e5bf6065..88951b179262 100644 --- a/Documentation/circular-buffers.txt +++ b/Documentation/circular-buffers.txt @@ -160,6 +160,7 @@ The producer will look something like this: spin_lock(&producer_lock); unsigned long head = buffer->head; + /* The spin_unlock() and next spin_lock() provide needed ordering. */ unsigned long tail = ACCESS_ONCE(buffer->tail); if (CIRC_SPACE(head, tail, buffer->size) >= 1) { @@ -168,9 +169,8 @@ The producer will look something like this: produce_item(item); - smp_wmb(); /* commit the item before incrementing the head */ - - buffer->head = (head + 1) & (buffer->size - 1); + smp_store_release(buffer->head, + (head + 1) & (buffer->size - 1)); /* wake_up() will make sure that the head is committed before * waking anyone up */ @@ -183,9 +183,14 @@ This will instruct the CPU that the contents of the new item must be written before the head index makes it available to the consumer and then instructs the CPU that the revised head index must be written before the consumer is woken. -Note that wake_up() doesn't have to be the exact mechanism used, but whatever -is used must guarantee a (write) memory barrier between the update of the head -index and the change of state of the consumer, if a change of state occurs. +Note that wake_up() does not guarantee any sort of barrier unless something +is actually awakened. We therefore cannot rely on it for ordering. However, +there is always one element of the array left empty. Therefore, the +producer must produce two elements before it could possibly corrupt the +element currently being read by the consumer. Therefore, the unlock-lock +pair between consecutive invocations of the consumer provides the necessary +ordering between the read of the index indicating that the consumer has +vacated a given element and the write by the producer to that same element. THE CONSUMER @@ -195,21 +200,20 @@ The consumer will look something like this: spin_lock(&consumer_lock); - unsigned long head = ACCESS_ONCE(buffer->head); + /* Read index before reading contents at that index. */ + unsigned long head = smp_load_acquire(buffer->head); unsigned long tail = buffer->tail; if (CIRC_CNT(head, tail, buffer->size) >= 1) { - /* read index before reading contents at that index */ - smp_read_barrier_depends(); /* extract one item from the buffer */ struct item *item = buffer[tail]; consume_item(item); - smp_mb(); /* finish reading descriptor before incrementing tail */ - - buffer->tail = (tail + 1) & (buffer->size - 1); + /* Finish reading descriptor before incrementing tail. */ + smp_store_release(buffer->tail, + (tail + 1) & (buffer->size - 1)); } spin_unlock(&consumer_lock); @@ -218,12 +222,17 @@ This will instruct the CPU to make sure the index is up to date before reading the new item, and then it shall make sure the CPU has finished reading the item before it writes the new tail pointer, which will erase the item. - -Note the use of ACCESS_ONCE() in both algorithms to read the opposition index. -This prevents the compiler from discarding and reloading its cached value - -which some compilers will do across smp_read_barrier_depends(). This isn't -strictly needed if you can be sure that the opposition index will _only_ be -used the once. +Note the use of ACCESS_ONCE() and smp_load_acquire() to read the +opposition index. This prevents the compiler from discarding and +reloading its cached value - which some compilers will do across +smp_read_barrier_depends(). This isn't strictly needed if you can +be sure that the opposition index will _only_ be used the once. +The smp_load_acquire() additionally forces the CPU to order against +subsequent memory references. Similarly, smp_store_release() is used +in both algorithms to write the thread's index. This documents the +fact that we are writing to something that can be read concurrently, +prevents the compiler from tearing the store, and enforces ordering +against previous accesses. =============== diff --git a/Documentation/clk.txt b/Documentation/clk.txt index 3aeb5c440442..699ef2a323b1 100644 --- a/Documentation/clk.txt +++ b/Documentation/clk.txt @@ -77,6 +77,11 @@ the operations defined in clk.h: int (*set_parent)(struct clk_hw *hw, u8 index); u8 (*get_parent)(struct clk_hw *hw); int (*set_rate)(struct clk_hw *hw, unsigned long); + int (*set_rate_and_parent)(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate, u8 index); + unsigned long (*recalc_accuracy)(struct clk_hw *hw, + unsigned long parent_accuracy); void (*init)(struct clk_hw *hw); }; @@ -202,6 +207,8 @@ optional or must be evaluated on a case-by-case basis. .set_parent | | | n | y | n | .get_parent | | | n | y | n | | | | | | | +.recalc_accuracy| | | | | | + | | | | | | .init | | | | | | ----------------------------------------------------------- [1] either one of round_rate or determine_rate is required. diff --git a/Documentation/cpu-freq/boost.txt b/Documentation/cpu-freq/boost.txt index 9b4edfcf486f..dd62e1334f0a 100644 --- a/Documentation/cpu-freq/boost.txt +++ b/Documentation/cpu-freq/boost.txt @@ -17,8 +17,8 @@ Introduction Some CPUs support a functionality to raise the operating frequency of some cores in a multi-core package if certain conditions apply, mostly if the whole chip is not fully utilized and below it's intended thermal -budget. This is done without operating system control by a combination -of hardware and firmware. +budget. The decision about boost disable/enable is made either at hardware +(e.g. x86) or software (e.g ARM). On Intel CPUs this is called "Turbo Boost", AMD calls it "Turbo-Core", in technical documentation "Core performance boost". In Linux we use the term "boost" for convenience. @@ -48,24 +48,24 @@ be desirable: User controlled switch ---------------------- -To allow the user to toggle the boosting functionality, the acpi-cpufreq -driver exports a sysfs knob to disable it. There is a file: +To allow the user to toggle the boosting functionality, the cpufreq core +driver exports a sysfs knob to enable or disable it. There is a file: /sys/devices/system/cpu/cpufreq/boost which can either read "0" (boosting disabled) or "1" (boosting enabled). -Reading the file is always supported, even if the processor does not -support boosting. In this case the file will be read-only and always -reads as "0". Explicitly changing the permissions and writing to that -file anyway will return EINVAL. +The file is exported only when cpufreq driver supports boosting. +Explicitly changing the permissions and writing to that file anyway will +return EINVAL. On supported CPUs one can write either a "0" or a "1" into this file. This will either disable the boost functionality on all cores in the -whole system (0) or will allow the hardware to boost at will (1). +whole system (0) or will allow the software or hardware to boost at will +(1). Writing a "1" does not explicitly boost the system, but just allows the -CPU (and the firmware) to boost at their discretion. Some implementations -take external factors like the chip's temperature into account, so -boosting once does not necessarily mean that it will occur every time -even using the exact same software setup. +CPU to boost at their discretion. Some implementations take external +factors like the chip's temperature into account, so boosting once does +not necessarily mean that it will occur every time even using the exact +same software setup. AMD legacy cpb switch diff --git a/Documentation/cpu-freq/intel-pstate.txt b/Documentation/cpu-freq/intel-pstate.txt new file mode 100644 index 000000000000..e742d21dbd96 --- /dev/null +++ b/Documentation/cpu-freq/intel-pstate.txt @@ -0,0 +1,40 @@ +Intel P-state driver +-------------------- + +This driver implements a scaling driver with an internal governor for +Intel Core processors. The driver follows the same model as the +Transmeta scaling driver (longrun.c) and implements the setpolicy() +instead of target(). Scaling drivers that implement setpolicy() are +assumed to implement internal governors by the cpufreq core. All the +logic for selecting the current P state is contained within the +driver; no external governor is used by the cpufreq core. + +Intel SandyBridge+ processors are supported. + +New sysfs files for controlling P state selection have been added to +/sys/devices/system/cpu/intel_pstate/ + + max_perf_pct: limits the maximum P state that will be requested by + the driver stated as a percentage of the available performance. + + min_perf_pct: limits the minimum P state that will be requested by + the driver stated as a percentage of the available performance. + + no_turbo: limits the driver to selecting P states below the turbo + frequency range. + +For contemporary Intel processors, the frequency is controlled by the +processor itself and the P-states exposed to software are related to +performance levels. The idea that frequency can be set to a single +frequency is fiction for Intel Core processors. Even if the scaling +driver selects a single P state the actual frequency the processor +will run at is selected by the processor itself. + +New debugfs files have also been added to /sys/kernel/debug/pstate_snb/ + + deadband + d_gain_pct + i_gain_pct + p_gain_pct + sample_rate_ms + setpoint diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 8cb9938cc47e..be675d2d15a7 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -285,7 +285,7 @@ A: This is what you would need in your kernel code to receive notifications. return NOTIFY_OK; } - static struct notifier_block foobar_cpu_notifer = + static struct notifier_block foobar_cpu_notifier = { .notifier_call = foobar_cpu_callback, }; diff --git a/Documentation/device-mapper/cache-policies.txt b/Documentation/device-mapper/cache-policies.txt index df52a849957f..66c2774c0c64 100644 --- a/Documentation/device-mapper/cache-policies.txt +++ b/Documentation/device-mapper/cache-policies.txt @@ -40,8 +40,11 @@ on hit count on entry. The policy aims to take different cache miss costs into account and to adjust to varying load patterns automatically. Message and constructor argument pairs are: - 'sequential_threshold <#nr_sequential_ios>' and - 'random_threshold <#nr_random_ios>'. + 'sequential_threshold <#nr_sequential_ios>' + 'random_threshold <#nr_random_ios>' + 'read_promote_adjustment ' + 'write_promote_adjustment ' + 'discard_promote_adjustment ' The sequential threshold indicates the number of contiguous I/Os required before a stream is treated as sequential. The random threshold @@ -55,6 +58,15 @@ since spindles tend to have good bandwidth. The io_tracker counts contiguous I/Os to try to spot when the io is in one of these sequential modes. +Internally the mq policy maintains a promotion threshold variable. If +the hit count of a block not in the cache goes above this threshold it +gets promoted to the cache. The read, write and discard promote adjustment +tunables allow you to tweak the promotion threshold by adding a small +value based on the io type. They default to 4, 8 and 1 respectively. +If you're trying to quickly warm a new cache device you may wish to +reduce these to encourage promotion. Remember to switch them back to +their defaults after the cache fills though. + cleaner ------- diff --git a/Documentation/device-mapper/cache.txt b/Documentation/device-mapper/cache.txt index 719320b5ed3f..e6b72d355151 100644 --- a/Documentation/device-mapper/cache.txt +++ b/Documentation/device-mapper/cache.txt @@ -217,36 +217,43 @@ the characteristics of a specific policy, always request it by name. Status ------ -<#used metadata blocks>/<#total metadata blocks> <#read hits> <#read misses> -<#write hits> <#write misses> <#demotions> <#promotions> <#blocks in cache> -<#dirty> <#features> * <#core args> * <#policy args> -* + <#used metadata blocks>/<#total metadata blocks> + <#used cache blocks>/<#total cache blocks> +<#read hits> <#read misses> <#write hits> <#write misses> +<#demotions> <#promotions> <#dirty> <#features> * +<#core args> * <#policy args> * -#used metadata blocks : Number of metadata blocks used -#total metadata blocks : Total number of metadata blocks -#read hits : Number of times a READ bio has been mapped +metadata block size : Fixed block size for each metadata block in + sectors +#used metadata blocks : Number of metadata blocks used +#total metadata blocks : Total number of metadata blocks +cache block size : Configurable block size for the cache device + in sectors +#used cache blocks : Number of blocks resident in the cache +#total cache blocks : Total number of cache blocks +#read hits : Number of times a READ bio has been mapped to the cache -#read misses : Number of times a READ bio has been mapped +#read misses : Number of times a READ bio has been mapped to the origin -#write hits : Number of times a WRITE bio has been mapped +#write hits : Number of times a WRITE bio has been mapped to the cache -#write misses : Number of times a WRITE bio has been +#write misses : Number of times a WRITE bio has been mapped to the origin -#demotions : Number of times a block has been removed +#demotions : Number of times a block has been removed from the cache -#promotions : Number of times a block has been moved to +#promotions : Number of times a block has been moved to the cache -#blocks in cache : Number of blocks resident in the cache -#dirty : Number of blocks in the cache that differ +#dirty : Number of blocks in the cache that differ from the origin -#feature args : Number of feature args to follow -feature args : 'writethrough' (optional) -#core args : Number of core arguments (must be even) -core args : Key/value pairs for tuning the core +#feature args : Number of feature args to follow +feature args : 'writethrough' (optional) +#core args : Number of core arguments (must be even) +core args : Key/value pairs for tuning the core e.g. migration_threshold -#policy args : Number of policy arguments to follow (must be even) -policy args : Key/value pairs - e.g. 'sequential_threshold 1024 +policy name : Name of the policy +#policy args : Number of policy arguments to follow (must be even) +policy args : Key/value pairs + e.g. sequential_threshold Messages -------- diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt index 50c44cf79b0e..8a7a3d46e0da 100644 --- a/Documentation/device-mapper/thin-provisioning.txt +++ b/Documentation/device-mapper/thin-provisioning.txt @@ -235,6 +235,8 @@ i) Constructor read_only: Don't allow any changes to be made to the pool metadata. + error_if_no_space: Error IOs, instead of queueing, if no space. + Data block size must be between 64KB (128 sectors) and 1GB (2097152 sectors) inclusive. @@ -276,6 +278,11 @@ ii) Status contain the string 'Fail'. The userspace recovery tools should then be used. + error_if_no_space|queue_if_no_space + If the pool runs out of data or metadata space, the pool will + either queue or error the IO destined to the data device. The + default is to queue the IO until more space is added. + iii) Messages create_thin diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 80b72419ffd8..10378cc48374 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -409,6 +409,7 @@ Your cooperation is appreciated. 193 = /dev/d7s SPARC 7-segment display 194 = /dev/zkshim Zero-Knowledge network shim control 195 = /dev/elographics/e2201 Elographics touchscreen E271-2201 + 196 = /dev/vfio/vfio VFIO userspace driver interface 198 = /dev/sexec Signed executable interface 199 = /dev/scanners/cuecat :CueCat barcode scanner 200 = /dev/net/tun TAP/TUN network device diff --git a/Documentation/devicetree/bindings/ABI.txt b/Documentation/devicetree/bindings/ABI.txt new file mode 100644 index 000000000000..d25f8d379680 --- /dev/null +++ b/Documentation/devicetree/bindings/ABI.txt @@ -0,0 +1,39 @@ + + Devicetree (DT) ABI + +I. Regarding stable bindings/ABI, we quote from the 2013 ARM mini-summit + summary document: + + "That still leaves the question of, what does a stable binding look + like? Certainly a stable binding means that a newer kernel will not + break on an older device tree, but that doesn't mean the binding is + frozen for all time. Grant said there are ways to change bindings that + don't result in breakage. For instance, if a new property is added, + then default to the previous behaviour if it is missing. If a binding + truly needs an incompatible change, then change the compatible string + at the same time. The driver can bind against both the old and the + new. These guidelines aren't new, but they desperately need to be + documented." + +II. General binding rules + + 1) Maintainers, don't let perfect be the enemy of good. Don't hold up a + binding because it isn't perfect. + + 2) Use specific compatible strings so that if we need to add a feature (DMA) + in the future, we can create a new compatible string. See I. + + 3) Bindings can be augmented, but the driver shouldn't break when given + the old binding. ie. add additional properties, but don't change the + meaning of an existing property. For drivers, default to the original + behaviour when a newly added property is missing. + + 4) Don't submit bindings for staging or unstable. That will be decided by + the devicetree maintainers *after* discussion on the mailinglist. + +III. Notes + + 1) This document is intended as a general familiarization with the process as + decided at the 2013 Kernel Summit. When in doubt, the current word of the + devicetree maintainers overrules this document. In that situation, a patch + updating this document would be appreciated. diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 5fac246a9530..3509707f9320 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -14,6 +14,9 @@ Required nodes: - core-module: the root node to the Integrator platforms must have a core-module with regs and the compatible string "arm,core-module-integrator" +- external-bus-interface: the root node to the Integrator platforms + must have an external bus interface with regs and the + compatible-string "arm,external-bus-interface" Required properties for the core module: - regs: the location and size of the core module registers, one @@ -48,6 +51,11 @@ Required nodes: reg = <0x10000000 0x200>; }; + ebi@12000000 { + compatible = "arm,external-bus-interface"; + reg = <0x12000000 0x100>; + }; + syscon { compatible = "arm,integrator-ap-syscon"; reg = <0x11000000 0x100>; diff --git a/Documentation/devicetree/bindings/arm/atmel-aic.txt b/Documentation/devicetree/bindings/arm/atmel-aic.txt index ad031211b5b8..2742e9cfd6b1 100644 --- a/Documentation/devicetree/bindings/arm/atmel-aic.txt +++ b/Documentation/devicetree/bindings/arm/atmel-aic.txt @@ -2,6 +2,7 @@ Required properties: - compatible: Should be "atmel,-aic" + can be "at91rm9200" or "sama5d3" - interrupt-controller: Identifies the node as an interrupt controller. - interrupt-parent: For single AIC system, it is an empty property. - #interrupt-cells: The number of cells to define the interrupts. It should be 3. diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index 1196290082d1..16f60b41c147 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -20,6 +20,10 @@ TC/TCLIB Timer required properties: - interrupts: Should contain all interrupts for the TC block Note that you can specify several interrupt cells if the TC block has one interrupt per channel. +- clock-names: tuple listing input clock names. + Required elements: "t0_clk" + Optional elements: "t1_clk", "t2_clk" +- clocks: phandles to input clocks. Examples: @@ -28,6 +32,8 @@ One interrupt per TC block: compatible = "atmel,at91rm9200-tcb"; reg = <0xfff7c000 0x100>; interrupts = <18 4>; + clocks = <&tcb0_clk>; + clock-names = "t0_clk"; }; One interrupt per TC channel in a TC block: @@ -35,6 +41,8 @@ One interrupt per TC channel in a TC block: compatible = "atmel,at91rm9200-tcb"; reg = <0xfffdc000 0x100>; interrupts = <26 4 27 4 28 4>; + clocks = <&tcb1_clk>; + clock-names = "t0_clk"; }; RSTC Reset Controller required properties: @@ -50,7 +58,8 @@ Example: }; RAMC SDRAM/DDR Controller required properties: -- compatible: Should be "atmel,at91sam9260-sdramc", +- compatible: Should be "atmel,at91rm9200-sdramc", + "atmel,at91sam9260-sdramc", "atmel,at91sam9g45-ddramc", - reg: Should contain registers location and length For at91sam9263 and at91sam9g45 you must specify 2 entries. diff --git a/Documentation/devicetree/bindings/arm/firmware/tlm,trusted-foundations.txt b/Documentation/devicetree/bindings/arm/firmware/tlm,trusted-foundations.txt new file mode 100644 index 000000000000..780d0392a66b --- /dev/null +++ b/Documentation/devicetree/bindings/arm/firmware/tlm,trusted-foundations.txt @@ -0,0 +1,20 @@ +Trusted Foundations +------------------- + +Boards that use the Trusted Foundations secure monitor can signal its +presence by declaring a node compatible with "tlm,trusted-foundations" +under the /firmware/ node + +Required properties: +- compatible: "tlm,trusted-foundations" +- tlm,version-major: major version number of Trusted Foundations firmware +- tlm,version-minor: minor version number of Trusted Foundations firmware + +Example: + firmware { + trusted-foundations { + compatible = "tlm,trusted-foundations"; + tlm,version-major = <2>; + tlm,version-minor = <8>; + }; + }; diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index 3dfb0c0384f5..bae0d87a38b2 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt @@ -11,6 +11,7 @@ have PPIs or SGIs. Main node required properties: - compatible : should be one of: + "arm,gic-400" "arm,cortex-a15-gic" "arm,cortex-a9-gic" "arm,cortex-a7-gic" diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt new file mode 100644 index 000000000000..8c7a4653508d --- /dev/null +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -0,0 +1,32 @@ +Hisilicon Platforms Device Tree Bindings +---------------------------------------------------- + +Hi4511 Board +Required root node properties: + - compatible = "hisilicon,hi3620-hi4511"; + +Hisilicon system controller + +Required properties: +- compatible : "hisilicon,sysctrl" +- reg : Register address and size + +Optional properties: +- smp-offset : offset in sysctrl for notifying slave cpu booting + cpu 1, reg; + cpu 2, reg + 0x4; + cpu 3, reg + 0x8; + If reg value is not zero, cpun exit wfi and go +- resume-offset : offset in sysctrl for notifying cpu0 when resume +- reboot-offset : offset in sysctrl for system reboot + +Example: + + /* for Hi3620 */ + sysctrl: system-controller@fc802000 { + compatible = "hisilicon,sysctrl"; + reg = <0xfc802000 0x1000>; + smp-offset = <0x31c>; + resume-offset = <0x308>; + reboot-offset = <0x4>; + }; diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt index c0c7626fd0ff..b513cb8196fe 100644 --- a/Documentation/devicetree/bindings/arm/l2cc.txt +++ b/Documentation/devicetree/bindings/arm/l2cc.txt @@ -7,20 +7,21 @@ The ARM L2 cache representation in the device tree should be done as follows: Required properties: - compatible : should be one of: - "arm,pl310-cache" - "arm,l220-cache" - "arm,l210-cache" - "marvell,aurora-system-cache": Marvell Controller designed to be + "arm,pl310-cache" + "arm,l220-cache" + "arm,l210-cache" + "bcm,bcm11351-a2-pl310-cache": DEPRECATED by "brcm,bcm11351-a2-pl310-cache" + "brcm,bcm11351-a2-pl310-cache": For Broadcom bcm11351 chipset where an + offset needs to be added to the address before passing down to the L2 + cache controller + "marvell,aurora-system-cache": Marvell Controller designed to be compatible with the ARM one, with system cache mode (meaning maintenance operations on L1 are broadcasted to the L2 and L2 performs the same operation). - "marvell,"aurora-outer-cache: Marvell Controller designed to be - compatible with the ARM one with outer cache mode. - "brcm,bcm11351-a2-pl310-cache": For Broadcom bcm11351 chipset where an - offset needs to be added to the address before passing down to the L2 - cache controller - "bcm,bcm11351-a2-pl310-cache": DEPRECATED by - "brcm,bcm11351-a2-pl310-cache" + "marvell,aurora-outer-cache": Marvell Controller designed to be + compatible with the ARM one with outer cache mode. + "marvell,tauros3-cache": Marvell Tauros3 cache controller, compatible + with arm,pl310-cache controller. - cache-unified : Specifies the cache is a unified cache. - cache-level : Should be set to 2 for a level 2 cache. - reg : Physical base address and size of cache controller's memory mapped diff --git a/Documentation/devicetree/bindings/arm/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell,berlin.txt new file mode 100644 index 000000000000..737afa5f8148 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell,berlin.txt @@ -0,0 +1,24 @@ +Marvell Berlin SoC Family Device Tree Bindings +--------------------------------------------------------------- + +Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500 +shall have the following properties: + +* Required root node properties: +compatible: must contain "marvell,berlin" + +In addition, the above compatible shall be extended with the specific +SoC and board used. Currently known SoC compatibles are: + "marvell,berlin2" for Marvell Armada 1500 (BG2, 88DE3100), + "marvell,berlin2cd" for Marvell Armada 1500-mini (BG2CD, 88DE3005) + "marvell,berlin2ct" for Marvell Armada ? (BG2CT, 88DE????) + "marvell,berlin3" for Marvell Armada ? (BG3, 88DE????) + +* Example: + +/ { + model = "Sony NSZ-GS7"; + compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin"; + + ... +} diff --git a/Documentation/devicetree/bindings/arm/moxart.txt b/Documentation/devicetree/bindings/arm/moxart.txt new file mode 100644 index 000000000000..11087edb0658 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/moxart.txt @@ -0,0 +1,12 @@ +MOXA ART device tree bindings + +Boards with the MOXA ART SoC shall have the following properties: + +Required root node property: + +compatible = "moxa,moxart"; + +Boards: + +- UC-7112-LX: embedded computer + compatible = "moxa,moxart-uc-7112-lx", "moxa,moxart" diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt index 808c1543b0f8..34dc40cffdfd 100644 --- a/Documentation/devicetree/bindings/arm/omap/omap.txt +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt @@ -31,6 +31,59 @@ spinlock@1 { ti,hwmods = "spinlock"; }; +SoC Type (optional): + +- General Purpose devices + compatible = "ti,gp" +- High Security devices + compatible = "ti,hs" + +SoC Families: + +- OMAP2 generic - defaults to OMAP2420 + compatible = "ti,omap2" +- OMAP3 generic - defaults to OMAP3430 + compatible = "ti,omap3" +- OMAP4 generic - defaults to OMAP4430 + compatible = "ti,omap4" +- OMAP5 generic - defaults to OMAP5430 + compatible = "ti,omap5" +- DRA7 generic - defaults to DRA742 + compatible = "ti,dra7" +- AM43x generic - defaults to AM4372 + compatible = "ti,am43" + +SoCs: + +- OMAP2420 + compatible = "ti,omap2420", "ti,omap2" +- OMAP2430 + compatible = "ti,omap2430", "ti,omap2" + +- OMAP3430 + compatible = "ti,omap3430", "ti,omap3" +- AM3517 + compatible = "ti,am3517", "ti,omap3" +- OMAP3630 + compatible = "ti,omap36xx", "ti,omap3" +- AM33xx + compatible = "ti,am33xx", "ti,omap3" + +- OMAP4430 + compatible = "ti,omap4430", "ti,omap4" +- OMAP4460 + compatible = "ti,omap4460", "ti,omap4" + +- OMAP5430 + compatible = "ti,omap5430", "ti,omap5" +- OMAP5432 + compatible = "ti,omap5432", "ti,omap5" + +- DRA742 + compatible = "ti,dra7xx", "ti,dra7" + +- AM4372 + compatible = "ti,am4372", "ti,am43" Boards: diff --git a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt index 5039c0a12f55..0ab3251a6ec2 100644 --- a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt +++ b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt @@ -1,7 +1,12 @@ SAMSUNG S5P/Exynos SoC series System Registers (SYSREG) Properties: - - name : should be 'sysreg'; - compatible : should contain "samsung,-sysreg", "syscon"; For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon"; - reg : offset and length of the register set. + +Example: + syscon@10010000 { + compatible = "samsung,exynos4-sysreg", "syscon"; + reg = <0x10010000 0x400>; + }; diff --git a/Documentation/devicetree/bindings/arm/tegra.txt b/Documentation/devicetree/bindings/arm/tegra.txt index ed9c85334436..558ed4b4ef39 100644 --- a/Documentation/devicetree/bindings/arm/tegra.txt +++ b/Documentation/devicetree/bindings/arm/tegra.txt @@ -32,3 +32,8 @@ board-specific compatible values: nvidia,whistler toradex,colibri_t20-512 toradex,iris + +Trusted Foundations +------------------------------------------- +Tegra supports the Trusted Foundation secure monitor. See the +"tlm,trusted-foundations" binding's documentation for more details. diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt index 1608a54e90e1..68ac65f82a1c 100644 --- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt @@ -9,6 +9,7 @@ Required properties: - compatible : Should contain "nvidia,tegra-pmc". - reg : Offset and length of the register set for the device - clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: "pclk" (The Tegra clock of that name), "clk32k_in" (The 32KHz clock input to Tegra). diff --git a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt index 9989eda755d9..c9cf605bb995 100644 --- a/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt +++ b/Documentation/devicetree/bindings/arm/versatile-fpga-irq.txt @@ -29,3 +29,8 @@ pic: pic@14000000 { clear-mask = <0xffffffff>; valid-mask = <0x003fffff>; }; + +Optional properties: +- interrupts: if the FPGA IRQ controller is cascaded, i.e. if its IRQ + output is simply connected to the input of another IRQ controller, + then the parent IRQ shall be specified in this property. diff --git a/Documentation/devicetree/bindings/ata/marvell.txt b/Documentation/devicetree/bindings/ata/marvell.txt index b5cdd20cde9c..1c8351604d38 100644 --- a/Documentation/devicetree/bindings/ata/marvell.txt +++ b/Documentation/devicetree/bindings/ata/marvell.txt @@ -1,7 +1,7 @@ * Marvell Orion SATA Required Properties: -- compatibility : "marvell,orion-sata" +- compatibility : "marvell,orion-sata" or "marvell,armada-370-sata" - reg : Address range of controller - interrupts : Interrupt controller is using - nr-ports : Number of SATA ports in use. diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt new file mode 100644 index 000000000000..1e6111333fa8 --- /dev/null +++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt @@ -0,0 +1,18 @@ +* Renesas R-Car SATA + +Required properties: +- compatible : should contain one of the following: + - "renesas,sata-r8a7779" for R-Car H1 + - "renesas,sata-r8a7790" for R-Car H2 + - "renesas,sata-r8a7791" for R-Car M2 +- reg : address and length of the SATA registers; +- interrupts : must consist of one interrupt specifier. + +Example: + +sata: sata@fc600000 { + compatible = "renesas,sata-r8a7779"; + reg = <0xfc600000 0x2000>; + interrupt-parent = <&gic>; + interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; +}; diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt new file mode 100644 index 000000000000..cd5e23912888 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt @@ -0,0 +1,339 @@ +Device Tree Clock bindings for arch-at91 + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of the following: + "atmel,at91rm9200-pmc" or + "atmel,at91sam9g45-pmc" or + "atmel,at91sam9n12-pmc" or + "atmel,at91sam9x5-pmc" or + "atmel,sama5d3-pmc": + at91 PMC (Power Management Controller) + All at91 specific clocks (clocks defined below) must be child + node of the PMC node. + + "atmel,at91rm9200-clk-main": + at91 main oscillator + + "atmel,at91rm9200-clk-master" or + "atmel,at91sam9x5-clk-master": + at91 master clock + + "atmel,at91sam9x5-clk-peripheral" or + "atmel,at91rm9200-clk-peripheral": + at91 peripheral clocks + + "atmel,at91rm9200-clk-pll" or + "atmel,at91sam9g45-clk-pll" or + "atmel,at91sam9g20-clk-pllb" or + "atmel,sama5d3-clk-pll": + at91 pll clocks + + "atmel,at91sam9x5-clk-plldiv": + at91 plla divisor + + "atmel,at91rm9200-clk-programmable" or + "atmel,at91sam9g45-clk-programmable" or + "atmel,at91sam9x5-clk-programmable": + at91 programmable clocks + + "atmel,at91sam9x5-clk-smd": + at91 SMD (Soft Modem) clock + + "atmel,at91rm9200-clk-system": + at91 system clocks + + "atmel,at91rm9200-clk-usb" or + "atmel,at91sam9x5-clk-usb" or + "atmel,at91sam9n12-clk-usb": + at91 usb clock + + "atmel,at91sam9x5-clk-utmi": + at91 utmi clock + +Required properties for PMC node: +- reg : defines the IO memory reserved for the PMC. +- #size-cells : shall be 0 (reg is used to encode clk id). +- #address-cells : shall be 1 (reg is used to encode clk id). +- interrupts : shall be set to PMC interrupt line. +- interrupt-controller : tell that the PMC is an interrupt controller. +- #interrupt-cells : must be set to 1. The first cell encodes the interrupt id, + and reflect the bit position in the PMC_ER/DR/SR registers. + You can use the dt macros defined in dt-bindings/clk/at91.h. + 0 (AT91_PMC_MOSCS) -> main oscillator ready + 1 (AT91_PMC_LOCKA) -> PLL A ready + 2 (AT91_PMC_LOCKB) -> PLL B ready + 3 (AT91_PMC_MCKRDY) -> master clock ready + 6 (AT91_PMC_LOCKU) -> UTMI PLL clock ready + 8 .. 15 (AT91_PMC_PCKRDY(id)) -> programmable clock ready + 16 (AT91_PMC_MOSCSELS) -> main oscillator selected + 17 (AT91_PMC_MOSCRCS) -> RC main oscillator stabilized + 18 (AT91_PMC_CFDEV) -> clock failure detected + +For example: + pmc: pmc@fffffc00 { + compatible = "atmel,sama5d3-pmc"; + interrupts = <1 4 7>; + interrupt-controller; + #interrupt-cells = <2>; + #size-cells = <0>; + #address-cells = <1>; + + /* put at91 clocks here */ + }; + +Required properties for main clock: +- interrupt-parent : must reference the PMC node. +- interrupts : shall be set to "<0>". +- #clock-cells : from common clock binding; shall be set to 0. +- clocks (optional if clock-frequency is provided) : shall be the slow clock + phandle. This clock is used to calculate the main clock rate if + "clock-frequency" is not provided. +- clock-frequency : the main oscillator frequency.Prefer the use of + "clock-frequency" over automatic clock rate calculation. + +For example: + main: mainck { + compatible = "atmel,at91rm9200-clk-main"; + interrupt-parent = <&pmc>; + interrupts = <0>; + #clock-cells = <0>; + clocks = <&ck32k>; + clock-frequency = <18432000>; + }; + +Required properties for master clock: +- interrupt-parent : must reference the PMC node. +- interrupts : shall be set to "<3>". +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : shall be the master clock sources (see atmel datasheet) phandles. + e.g. "<&ck32k>, <&main>, <&plla>, <&pllb>". +- atmel,clk-output-range : minimum and maximum clock frequency (two u32 + fields). + e.g. output = <0 133000000>; <=> 0 to 133MHz. +- atmel,clk-divisors : master clock divisors table (four u32 fields). + 0 <=> reserved value. + e.g. divisors = <1 2 4 6>; +- atmel,master-clk-have-div3-pres : some SoC use the reserved value 7 in the + PRES field as CLOCK_DIV3 (e.g sam9x5). + +For example: + mck: mck { + compatible = "atmel,at91rm9200-clk-master"; + interrupt-parent = <&pmc>; + interrupts = <3>; + #clock-cells = <0>; + atmel,clk-output-range = <0 133000000>; + atmel,clk-divisors = <1 2 4 0>; + }; + +Required properties for peripheral clocks: +- #size-cells : shall be 0 (reg is used to encode clk id). +- #address-cells : shall be 1 (reg is used to encode clk id). +- clocks : shall be the master clock phandle. + e.g. clocks = <&mck>; +- name: device tree node describing a specific system clock. + * #clock-cells : from common clock binding; shall be set to 0. + * reg: peripheral id. See Atmel's datasheets to get a full + list of peripheral ids. + * atmel,clk-output-range : minimum and maximum clock frequency + (two u32 fields). Only valid on at91sam9x5-clk-peripheral + compatible IPs. + +For example: + periph: periphck { + compatible = "atmel,at91sam9x5-clk-peripheral"; + #size-cells = <0>; + #address-cells = <1>; + clocks = <&mck>; + + ssc0_clk { + #clock-cells = <0>; + reg = <2>; + atmel,clk-output-range = <0 133000000>; + }; + + usart0_clk { + #clock-cells = <0>; + reg = <3>; + atmel,clk-output-range = <0 66000000>; + }; + }; + + +Required properties for pll clocks: +- interrupt-parent : must reference the PMC node. +- interrupts : shall be set to "<1>". +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : shall be the main clock phandle. +- reg : pll id. + 0 -> PLL A + 1 -> PLL B +- atmel,clk-input-range : minimum and maximum source clock frequency (two u32 + fields). + e.g. input = <1 32000000>; <=> 1 to 32MHz. +- #atmel,pll-clk-output-range-cells : number of cells reserved for pll output + range description. Sould be set to 2, 3 + or 4. + * 1st and 2nd cells represent the frequency range (min-max). + * 3rd cell is optional and represents the OUT field value for the given + range. + * 4th cell is optional and represents the ICPLL field (PLLICPR + register) +- atmel,pll-clk-output-ranges : pll output frequency ranges + optional parameter + depending on #atmel,pll-output-range-cells + property value. + +For example: + plla: pllack { + compatible = "atmel,at91sam9g45-clk-pll"; + interrupt-parent = <&pmc>; + interrupts = <1>; + #clock-cells = <0>; + clocks = <&main>; + reg = <0>; + atmel,clk-input-range = <2000000 32000000>; + #atmel,pll-clk-output-range-cells = <4>; + atmel,pll-clk-output-ranges = <74500000 800000000 0 0 + 69500000 750000000 1 0 + 64500000 700000000 2 0 + 59500000 650000000 3 0 + 54500000 600000000 0 1 + 49500000 550000000 1 1 + 44500000 500000000 2 1 + 40000000 450000000 3 1>; + }; + +Required properties for plldiv clocks (plldiv = pll / 2): +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : shall be the plla clock phandle. + +The pll divisor is equal to 2 and cannot be changed. + +For example: + plladiv: plladivck { + compatible = "atmel,at91sam9x5-clk-plldiv"; + #clock-cells = <0>; + clocks = <&plla>; + }; + +Required properties for programmable clocks: +- interrupt-parent : must reference the PMC node. +- #size-cells : shall be 0 (reg is used to encode clk id). +- #address-cells : shall be 1 (reg is used to encode clk id). +- clocks : shall be the programmable clock source phandles. + e.g. clocks = <&clk32k>, <&main>, <&plla>, <&pllb>; +- name: device tree node describing a specific prog clock. + * #clock-cells : from common clock binding; shall be set to 0. + * reg : programmable clock id (register offset from PCKx + register). + * interrupts : shall be set to "<(8 + id)>". + +For example: + prog: progck { + compatible = "atmel,at91sam9g45-clk-programmable"; + #size-cells = <0>; + #address-cells = <1>; + interrupt-parent = <&pmc>; + clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>; + + prog0 { + #clock-cells = <0>; + reg = <0>; + interrupts = <8>; + }; + + prog1 { + #clock-cells = <0>; + reg = <1>; + interrupts = <9>; + }; + }; + + +Required properties for smd clock: +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : shall be the smd clock source phandles. + e.g. clocks = <&plladiv>, <&utmi>; + +For example: + smd: smdck { + compatible = "atmel,at91sam9x5-clk-smd"; + #clock-cells = <0>; + clocks = <&plladiv>, <&utmi>; + }; + +Required properties for system clocks: +- #size-cells : shall be 0 (reg is used to encode clk id). +- #address-cells : shall be 1 (reg is used to encode clk id). +- name: device tree node describing a specific system clock. + * #clock-cells : from common clock binding; shall be set to 0. + * reg: system clock id (bit position in SCER/SCDR/SCSR registers). + See Atmel's datasheet to get a full list of system clock ids. + +For example: + system: systemck { + compatible = "atmel,at91rm9200-clk-system"; + #address-cells = <1>; + #size-cells = <0>; + + ddrck { + #clock-cells = <0>; + reg = <2>; + clocks = <&mck>; + }; + + uhpck { + #clock-cells = <0>; + reg = <6>; + clocks = <&usb>; + }; + + udpck { + #clock-cells = <0>; + reg = <7>; + clocks = <&usb>; + }; + }; + + +Required properties for usb clock: +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : shall be the smd clock source phandles. + e.g. clocks = <&pllb>; +- atmel,clk-divisors (only available for "atmel,at91rm9200-clk-usb"): + usb clock divisor table. + e.g. divisors = <1 2 4 0>; + +For example: + usb: usbck { + compatible = "atmel,at91sam9x5-clk-usb"; + #clock-cells = <0>; + clocks = <&plladiv>, <&utmi>; + }; + + usb: usbck { + compatible = "atmel,at91rm9200-clk-usb"; + #clock-cells = <0>; + clocks = <&pllb>; + atmel,clk-divisors = <1 2 4 0>; + }; + + +Required properties for utmi clock: +- interrupt-parent : must reference the PMC node. +- interrupts : shall be set to "". +- #clock-cells : from common clock binding; shall be set to 0. +- clocks : shall be the main clock source phandle. + +For example: + utmi: utmick { + compatible = "atmel,at91sam9x5-clk-utmi"; + interrupt-parent = <&pmc>; + interrupts = ; + #clock-cells = <0>; + clocks = <&main>; + }; diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt index 75e2e1999f87..180e8835569e 100644 --- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt +++ b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt @@ -8,12 +8,29 @@ Required Properties: - compatible: should be one of the following: - "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs. - - "samsung,exynos5250-audss-clock" - controller compatible with all Exynos5 SoCs. - + - "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250 + SoCs. + - "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420 + SoCs. - reg: physical base address and length of the controller's register set. - #clock-cells: should be 1. +- clocks: + - pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll" + is used if not specified. + - pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll" + is used if not specified. + - cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not + specified. + - sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if + not specified. + - sclk_pcm_in: PCM clock, parent of sclk_pcm. "sclk_pcm0" is used if not + specified. + +- clock-names: Aliases for the above clocks. They should be "pll_ref", + "pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively. + The following is the list of clocks generated by the controller. Each clock is assigned an identifier and client nodes use this identifier to specify the clock which they consume. Some of the clocks are available only on a particular @@ -34,8 +51,10 @@ i2s_bus 6 sclk_i2s 7 pcm_bus 8 sclk_pcm 9 +adma 10 Exynos5420 -Example 1: An example of a clock controller node is listed below. +Example 1: An example of a clock controller node using the default input + clock names is listed below. clock_audss: audss-clock-controller@3810000 { compatible = "samsung,exynos5250-audss-clock"; @@ -43,7 +62,19 @@ clock_audss: audss-clock-controller@3810000 { #clock-cells = <1>; }; -Example 2: I2S controller node that consumes the clock generated by the clock +Example 2: An example of a clock controller node with the input clocks + specified. + +clock_audss: audss-clock-controller@3810000 { + compatible = "samsung,exynos5250-audss-clock"; + reg = <0x03810000 0x0C>; + #clock-cells = <1>; + clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>, + <&ext_i2s_clk>; + clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk"; +}; + +Example 3: I2S controller node that consumes the clock generated by the clock controller. Refer to the standard clock bindings for information about 'clocks' and 'clock-names' property. diff --git a/Documentation/devicetree/bindings/clock/clock-bindings.txt b/Documentation/devicetree/bindings/clock/clock-bindings.txt index eb65d417f8c4..7c52c29d99fa 100644 --- a/Documentation/devicetree/bindings/clock/clock-bindings.txt +++ b/Documentation/devicetree/bindings/clock/clock-bindings.txt @@ -5,7 +5,7 @@ Sources of clock signal can be represented by any node in the device tree. Those nodes are designated as clock providers. Clock consumer nodes use a phandle and clock specifier pair to connect clock provider outputs to clock inputs. Similar to the gpio specifiers, a clock -specifier is an array of one more more cells identifying the clock +specifier is an array of zero, one or more cells identifying the clock output on a device. The length of a clock specifier is defined by the value of a #clock-cells property in the clock provider node. diff --git a/Documentation/devicetree/bindings/clock/emev2-clock.txt b/Documentation/devicetree/bindings/clock/emev2-clock.txt new file mode 100644 index 000000000000..60bbb1a8c69a --- /dev/null +++ b/Documentation/devicetree/bindings/clock/emev2-clock.txt @@ -0,0 +1,98 @@ +Device tree Clock bindings for Renesas EMMA Mobile EV2 + +This binding uses the common clock binding. + +* SMU +System Management Unit described in user's manual R19UH0037EJ1000_SMU. +This is not a clock provider, but clocks under SMU depend on it. + +Required properties: +- compatible: Should be "renesas,emev2-smu" +- reg: Address and Size of SMU registers + +* SMU_CLKDIV +Function block with an input mux and a divider, which corresponds to +"Serial clock generator" in fig."Clock System Overview" of the manual, +and "xxx frequency division setting register" (XXXCLKDIV) registers. +This makes internal (neither input nor output) clock that is provided +to input of xxxGCLK block. + +Required properties: +- compatible: Should be "renesas,emev2-smu-clkdiv" +- reg: Byte offset from SMU base and Bit position in the register +- clocks: Parent clocks. Input clocks as described in clock-bindings.txt +- #clock-cells: Should be <0> + +* SMU_GCLK +Clock gating node shown as "Clock stop processing block" in the +fig."Clock System Overview" of the manual. +Registers are "xxx clock gate control register" (XXXGCLKCTRL). + +Required properties: +- compatible: Should be "renesas,emev2-smu-gclk" +- reg: Byte offset from SMU base and Bit position in the register +- clocks: Input clock as described in clock-bindings.txt +- #clock-cells: Should be <0> + +Example of provider: + +usia_u0_sclkdiv: usia_u0_sclkdiv { + compatible = "renesas,emev2-smu-clkdiv"; + reg = <0x610 0>; + clocks = <&pll3_fo>, <&pll4_fo>, <&pll1_fo>, <&osc1_fo>; + #clock-cells = <0>; +}; + +usia_u0_sclk: usia_u0_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x4a0 1>; + clocks = <&usia_u0_sclkdiv>; + #clock-cells = <0>; +}; + +Example of consumer: + +uart@e1020000 { + compatible = "renesas,em-uart"; + reg = <0xe1020000 0x38>; + interrupts = <0 8 0>; + clocks = <&usia_u0_sclk>; + clock-names = "sclk"; +}; + +Example of clock-tree description: + + This describes a clock path in the clock tree + c32ki -> pll3_fo -> usia_u0_sclkdiv -> usia_u0_sclk + +smu@e0110000 { + compatible = "renesas,emev2-smu"; + reg = <0xe0110000 0x10000>; + #address-cells = <2>; + #size-cells = <0>; + + c32ki: c32ki { + compatible = "fixed-clock"; + clock-frequency = <32768>; + #clock-cells = <0>; + }; + pll3_fo: pll3_fo { + compatible = "fixed-factor-clock"; + clocks = <&c32ki>; + clock-div = <1>; + clock-mult = <7000>; + #clock-cells = <0>; + }; + usia_u0_sclkdiv: usia_u0_sclkdiv { + compatible = "renesas,emev2-smu-clkdiv"; + reg = <0x610 0>; + clocks = <&pll3_fo>; + #clock-cells = <0>; + }; + usia_u0_sclk: usia_u0_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x4a0 1>; + clocks = <&usia_u0_sclkdiv>; + #clock-cells = <0>; + }; +}; diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt index 46f5c791ea0d..72ce617dea82 100644 --- a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt @@ -62,6 +62,7 @@ clock which they consume. div_i2s1 157 div_i2s2 158 sclk_hdmiphy 159 + div_pcm0 160 [Peripheral Clock Gates] @@ -159,6 +160,8 @@ clock which they consume. mixer 343 hdmi 344 g2d 345 + mdma0 346 + smmu_mdma0 347 [Clock Muxes] diff --git a/Documentation/devicetree/bindings/clock/fixed-clock.txt b/Documentation/devicetree/bindings/clock/fixed-clock.txt index 0b1fe7824093..48ea0ad8ad46 100644 --- a/Documentation/devicetree/bindings/clock/fixed-clock.txt +++ b/Documentation/devicetree/bindings/clock/fixed-clock.txt @@ -10,6 +10,8 @@ Required properties: - clock-frequency : frequency of clock in Hz. Should be a single cell. Optional properties: +- clock-accuracy : accuracy of clock in ppb (parts per billion). + Should be a single cell. - gpios : From common gpio binding; gpio connection to clock enable pin. - clock-output-names : From common clock binding. @@ -18,4 +20,5 @@ Example: compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <1000000000>; + clock-accuracy = <100>; }; diff --git a/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt b/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt index 5757f9abfc26..1bae8527eb9b 100644 --- a/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt +++ b/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt @@ -19,6 +19,6 @@ Example: compatible = "fixed-factor-clock"; clocks = <&parentclk>; #clock-cells = <0>; - div = <2>; - mult = <1>; + clock-div = <2>; + clock-mult = <1>; }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt new file mode 100644 index 000000000000..4b71ab41be53 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -0,0 +1,19 @@ +* Hisilicon Hi3620 Clock Controller + +The Hi3620 clock controller generates and supplies clock to various +controllers within the Hi3620 SoC. + +Required Properties: + +- compatible: should be one of the following. + - "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + +All these identifier could be found in . diff --git a/Documentation/devicetree/bindings/clock/imx35-clock.txt b/Documentation/devicetree/bindings/clock/imx35-clock.txt new file mode 100644 index 000000000000..a70356452a82 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/imx35-clock.txt @@ -0,0 +1,113 @@ +* Clock bindings for Freescale i.MX35 + +Required properties: +- compatible: Should be "fsl,imx35-ccm" +- reg: Address and length of the register set +- interrupts: Should contain CCM interrupt +- #clock-cells: Should be <1> + +The clock consumer should specify the desired clock by having the clock +ID in its "clocks" phandle cell. The following is a full list of i.MX35 +clocks and IDs. + + Clock ID + --------------------------- + ckih 0 + mpll 1 + ppll 2 + mpll_075 3 + arm 4 + hsp 5 + hsp_div 6 + hsp_sel 7 + ahb 8 + ipg 9 + arm_per_div 10 + ahb_per_div 11 + ipg_per 12 + uart_sel 13 + uart_div 14 + esdhc_sel 15 + esdhc1_div 16 + esdhc2_div 17 + esdhc3_div 18 + spdif_sel 19 + spdif_div_pre 20 + spdif_div_post 21 + ssi_sel 22 + ssi1_div_pre 23 + ssi1_div_post 24 + ssi2_div_pre 25 + ssi2_div_post 26 + usb_sel 27 + usb_div 28 + nfc_div 29 + asrc_gate 30 + pata_gate 31 + audmux_gate 32 + can1_gate 33 + can2_gate 34 + cspi1_gate 35 + cspi2_gate 36 + ect_gate 37 + edio_gate 38 + emi_gate 39 + epit1_gate 40 + epit2_gate 41 + esai_gate 42 + esdhc1_gate 43 + esdhc2_gate 44 + esdhc3_gate 45 + fec_gate 46 + gpio1_gate 47 + gpio2_gate 48 + gpio3_gate 49 + gpt_gate 50 + i2c1_gate 51 + i2c2_gate 52 + i2c3_gate 53 + iomuxc_gate 54 + ipu_gate 55 + kpp_gate 56 + mlb_gate 57 + mshc_gate 58 + owire_gate 59 + pwm_gate 60 + rngc_gate 61 + rtc_gate 62 + rtic_gate 63 + scc_gate 64 + sdma_gate 65 + spba_gate 66 + spdif_gate 67 + ssi1_gate 68 + ssi2_gate 69 + uart1_gate 70 + uart2_gate 71 + uart3_gate 72 + usbotg_gate 73 + wdog_gate 74 + max_gate 75 + admux_gate 76 + csi_gate 77 + csi_div 78 + csi_sel 79 + iim_gate 80 + gpu2d_gate 81 + +Examples: + +clks: ccm@53f80000 { + compatible = "fsl,imx35-ccm"; + reg = <0x53f80000 0x4000>; + interrupts = <31>; + #clock-cells = <1>; +}; + +esdhc1: esdhc@53fb4000 { + compatible = "fsl,imx35-esdhc"; + reg = <0x53fb4000 0x4000>; + interrupts = <7>; + clocks = <&clks 9>, <&clks 8>, <&clks 43>; + clock-names = "ipg", "ahb", "per"; +}; diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index 4c029a8739d3..cadc4d29ada6 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -7,197 +7,8 @@ Required properties: - #clock-cells: Should be <1> The clock consumer should specify the desired clock by having the clock -ID in its "clocks" phandle cell. The following is a full list of i.MX5 -clocks and IDs. - - Clock ID - --------------------------- - dummy 0 - ckil 1 - osc 2 - ckih1 3 - ckih2 4 - ahb 5 - ipg 6 - axi_a 7 - axi_b 8 - uart_pred 9 - uart_root 10 - esdhc_a_pred 11 - esdhc_b_pred 12 - esdhc_c_s 13 - esdhc_d_s 14 - emi_sel 15 - emi_slow_podf 16 - nfc_podf 17 - ecspi_pred 18 - ecspi_podf 19 - usboh3_pred 20 - usboh3_podf 21 - usb_phy_pred 22 - usb_phy_podf 23 - cpu_podf 24 - di_pred 25 - tve_s 27 - uart1_ipg_gate 28 - uart1_per_gate 29 - uart2_ipg_gate 30 - uart2_per_gate 31 - uart3_ipg_gate 32 - uart3_per_gate 33 - i2c1_gate 34 - i2c2_gate 35 - gpt_ipg_gate 36 - pwm1_ipg_gate 37 - pwm1_hf_gate 38 - pwm2_ipg_gate 39 - pwm2_hf_gate 40 - gpt_hf_gate 41 - fec_gate 42 - usboh3_per_gate 43 - esdhc1_ipg_gate 44 - esdhc2_ipg_gate 45 - esdhc3_ipg_gate 46 - esdhc4_ipg_gate 47 - ssi1_ipg_gate 48 - ssi2_ipg_gate 49 - ssi3_ipg_gate 50 - ecspi1_ipg_gate 51 - ecspi1_per_gate 52 - ecspi2_ipg_gate 53 - ecspi2_per_gate 54 - cspi_ipg_gate 55 - sdma_gate 56 - emi_slow_gate 57 - ipu_s 58 - ipu_gate 59 - nfc_gate 60 - ipu_di1_gate 61 - vpu_s 62 - vpu_gate 63 - vpu_reference_gate 64 - uart4_ipg_gate 65 - uart4_per_gate 66 - uart5_ipg_gate 67 - uart5_per_gate 68 - tve_gate 69 - tve_pred 70 - esdhc1_per_gate 71 - esdhc2_per_gate 72 - esdhc3_per_gate 73 - esdhc4_per_gate 74 - usb_phy_gate 75 - hsi2c_gate 76 - mipi_hsc1_gate 77 - mipi_hsc2_gate 78 - mipi_esc_gate 79 - mipi_hsp_gate 80 - ldb_di1_div_3_5 81 - ldb_di1_div 82 - ldb_di0_div_3_5 83 - ldb_di0_div 84 - ldb_di1_gate 85 - can2_serial_gate 86 - can2_ipg_gate 87 - i2c3_gate 88 - lp_apm 89 - periph_apm 90 - main_bus 91 - ahb_max 92 - aips_tz1 93 - aips_tz2 94 - tmax1 95 - tmax2 96 - tmax3 97 - spba 98 - uart_sel 99 - esdhc_a_sel 100 - esdhc_b_sel 101 - esdhc_a_podf 102 - esdhc_b_podf 103 - ecspi_sel 104 - usboh3_sel 105 - usb_phy_sel 106 - iim_gate 107 - usboh3_gate 108 - emi_fast_gate 109 - ipu_di0_gate 110 - gpc_dvfs 111 - pll1_sw 112 - pll2_sw 113 - pll3_sw 114 - ipu_di0_sel 115 - ipu_di1_sel 116 - tve_ext_sel 117 - mx51_mipi 118 - pll4_sw 119 - ldb_di1_sel 120 - di_pll4_podf 121 - ldb_di0_sel 122 - ldb_di0_gate 123 - usb_phy1_gate 124 - usb_phy2_gate 125 - per_lp_apm 126 - per_pred1 127 - per_pred2 128 - per_podf 129 - per_root 130 - ssi_apm 131 - ssi1_root_sel 132 - ssi2_root_sel 133 - ssi3_root_sel 134 - ssi_ext1_sel 135 - ssi_ext2_sel 136 - ssi_ext1_com_sel 137 - ssi_ext2_com_sel 138 - ssi1_root_pred 139 - ssi1_root_podf 140 - ssi2_root_pred 141 - ssi2_root_podf 142 - ssi_ext1_pred 143 - ssi_ext1_podf 144 - ssi_ext2_pred 145 - ssi_ext2_podf 146 - ssi1_root_gate 147 - ssi2_root_gate 148 - ssi3_root_gate 149 - ssi_ext1_gate 150 - ssi_ext2_gate 151 - epit1_ipg_gate 152 - epit1_hf_gate 153 - epit2_ipg_gate 154 - epit2_hf_gate 155 - can_sel 156 - can1_serial_gate 157 - can1_ipg_gate 158 - owire_gate 159 - gpu3d_s 160 - gpu2d_s 161 - gpu3d_gate 162 - gpu2d_gate 163 - garb_gate 164 - cko1_sel 165 - cko1_podf 166 - cko1 167 - cko2_sel 168 - cko2_podf 169 - cko2 170 - srtc_gate 171 - pata_gate 172 - sata_gate 173 - spdif_xtal_sel 174 - spdif0_sel 175 - spdif1_sel 176 - spdif0_pred 177 - spdif0_podf 178 - spdif1_pred 179 - spdif1_podf 180 - spdif0_com_sel 181 - spdif1_com_sel 182 - spdif0_gate 183 - spdif1_gate 184 - spdif_ipg_gate 185 - ocram 186 +ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx5-clock.h +for the full list of i.MX5 clock IDs. Examples (for mx53): @@ -212,7 +23,7 @@ can1: can@53fc8000 { compatible = "fsl,imx53-flexcan", "fsl,p1010-flexcan"; reg = <0x53fc8000 0x4000>; interrupts = <82>; - clocks = <&clks 158>, <&clks 157>; + clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>; clock-names = "ipg", "per"; status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/keystone-pll.txt b/Documentation/devicetree/bindings/clock/keystone-pll.txt index 12bd72605a31..225990f79b7c 100644 --- a/Documentation/devicetree/bindings/clock/keystone-pll.txt +++ b/Documentation/devicetree/bindings/clock/keystone-pll.txt @@ -17,13 +17,14 @@ Required properties: - reg - pll control0 and pll multipler registers - reg-names : control and multiplier. The multiplier is applicable only for main pll clock -- fixed-postdiv : fixed post divider value +- fixed-postdiv : fixed post divider value. If absent, use clkod register bits + for postdiv Example: mainpllclk: mainpllclk@2310110 { #clock-cells = <0>; compatible = "ti,keystone,main-pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclksys>; reg = <0x02620350 4>, <0x02310110 4>; reg-names = "control", "multiplier"; fixed-postdiv = <2>; @@ -32,11 +33,10 @@ Example: papllclk: papllclk@2620358 { #clock-cells = <0>; compatible = "ti,keystone,pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclkpass>; clock-output-names = "pa-pll-clk"; reg = <0x02620358 4>; reg-names = "control"; - fixed-postdiv = <6>; }; Required properties: diff --git a/Documentation/devicetree/bindings/clock/maxim,max77686.txt b/Documentation/devicetree/bindings/clock/maxim,max77686.txt new file mode 100644 index 000000000000..96ce71bbd745 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/maxim,max77686.txt @@ -0,0 +1,38 @@ +Binding for Maxim MAX77686 32k clock generator block + +This is a part of device tree bindings of MAX77686 multi-function device. +More information can be found in bindings/mfd/max77686.txt file. + +The MAX77686 contains three 32.768khz clock outputs that can be controlled +(gated/ungated) over I2C. + +Following properties should be presend in main device node of the MFD chip. + +Required properties: +- #clock-cells: simple one-cell clock specifier format is used, where the + only cell is used as an index of the clock inside the provider. Following + indices are allowed: + - 0: 32khz_ap clock, + - 1: 32khz_cp clock, + - 2: 32khz_pmic clock. + +Example: Node of the MFD chip + + max77686: max77686@09 { + compatible = "maxim,max77686"; + interrupt-parent = <&wakeup_eint>; + interrupts = <26 0>; + reg = <0x09>; + #clock-cells = <1>; + + /* ... */ + }; + +Example: Clock consumer node + + foo@0 { + compatible = "bar,foo"; + /* ... */ + clock-names = "my-clock"; + clocks = <&max77686 2>; + }; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt index 0c80c2677104..9acea9d93160 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt @@ -15,6 +15,9 @@ Required properties : In clock consumers, this cell represents the clock ID exposed by the CAR. The assignments may be found in header file . +- #reset-cells : Should be 1. + In clock consumers, this cell represents the bit number in the CAR's + array of CLK_RST_CONTROLLER_RST_DEVICES_* registers. Example SoC include file: @@ -23,6 +26,7 @@ Example SoC include file: compatible = "nvidia,tegra114-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; usb@c5004000 { diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt new file mode 100644 index 000000000000..ded5d6212c84 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-car.txt @@ -0,0 +1,63 @@ +NVIDIA Tegra124 Clock And Reset Controller + +This binding uses the common clock binding: +Documentation/devicetree/bindings/clock/clock-bindings.txt + +The CAR (Clock And Reset) Controller on Tegra is the HW module responsible +for muxing and gating Tegra's clocks, and setting their rates. + +Required properties : +- compatible : Should be "nvidia,tegra124-car" +- reg : Should contain CAR registers location and length +- clocks : Should contain phandle and clock specifiers for two clocks: + the 32 KHz "32k_in", and the board-specific oscillator "osc". +- #clock-cells : Should be 1. + In clock consumers, this cell represents the clock ID exposed by the + CAR. The assignments may be found in header file + . +- #reset-cells : Should be 1. + In clock consumers, this cell represents the bit number in the CAR's + array of CLK_RST_CONTROLLER_RST_DEVICES_* registers. + +Example SoC include file: + +/ { + tegra_car: clock { + compatible = "nvidia,tegra124-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + usb@c5004000 { + clocks = <&tegra_car TEGRA124_CLK_USB2>; + }; +}; + +Example board file: + +/ { + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + osc: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <112400000>; + }; + + clk_32k: clock@1 { + compatible = "fixed-clock"; + reg = <1>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + &tegra_car { + clocks = <&clk_32k> <&osc>; + }; +}; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt index fcfed5bf73fb..6c5901b503d0 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt @@ -15,6 +15,9 @@ Required properties : In clock consumers, this cell represents the clock ID exposed by the CAR. The assignments may be found in header file . +- #reset-cells : Should be 1. + In clock consumers, this cell represents the bit number in the CAR's + array of CLK_RST_CONTROLLER_RST_DEVICES_* registers. Example SoC include file: @@ -23,6 +26,7 @@ Example SoC include file: compatible = "nvidia,tegra20-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; usb@c5004000 { diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt index 0f714081e986..63618cde12df 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra30-car.txt @@ -15,6 +15,9 @@ Required properties : In clock consumers, this cell represents the clock ID exposed by the CAR. The assignments may be found in header file . +- #reset-cells : Should be 1. + In clock consumers, this cell represents the bit number in the CAR's + array of CLK_RST_CONTROLLER_RST_DEVICES_* registers. Example SoC include file: @@ -23,6 +26,7 @@ Example SoC include file: compatible = "nvidia,tegra30-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; usb@c5004000 { diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt new file mode 100644 index 000000000000..767401f42871 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -0,0 +1,21 @@ +Qualcomm Global Clock & Reset Controller Binding +------------------------------------------------ + +Required properties : +- compatible : shall contain only one of the following: + + "qcom,gcc-msm8660" + "qcom,gcc-msm8960" + "qcom,gcc-msm8974" + +- reg : shall contain base register location and length +- #clock-cells : shall contain 1 +- #reset-cells : shall contain 1 + +Example: + clock-controller@900000 { + compatible = "qcom,gcc-msm8960"; + reg = <0x900000 0x4000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt new file mode 100644 index 000000000000..d572e9964c54 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt @@ -0,0 +1,21 @@ +Qualcomm Multimedia Clock & Reset Controller Binding +---------------------------------------------------- + +Required properties : +- compatible : shall contain only one of the following: + + "qcom,mmcc-msm8660" + "qcom,mmcc-msm8960" + "qcom,mmcc-msm8974" + +- reg : shall contain base register location and length +- #clock-cells : shall contain 1 +- #reset-cells : shall contain 1 + +Example: + clock-controller@4000000 { + compatible = "qcom,mmcc-msm8960"; + reg = <0x4000000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt new file mode 100644 index 000000000000..952e373178d2 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt @@ -0,0 +1,28 @@ +* Renesas CPG DIV6 Clock + +The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse +Generator (CPG). They clock input is divided by a configurable factor from 1 +to 64. + +Required Properties: + + - compatible: Must be one of the following + - "renesas,r8a7790-div6-clock" for R8A7790 (R-Car H2) DIV6 clocks + - "renesas,r8a7791-div6-clock" for R8A7791 (R-Car M2) DIV6 clocks + - "renesas,cpg-div6-clock" for generic DIV6 clocks + - reg: Base address and length of the memory resource used by the DIV6 clock + - clocks: Reference to the parent clock + - #clock-cells: Must be 0 + - clock-output-names: The name of the clock as a free-form string + + +Example +------- + + sd2_clk: sd2_clk@e6150078 { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150078 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sd2"; + }; diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt new file mode 100644 index 000000000000..a6a352c2771e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mstp-clocks.txt @@ -0,0 +1,51 @@ +* Renesas CPG Module Stop (MSTP) Clocks + +The CPG can gate SoC device clocks. The gates are organized in groups of up to +32 gates. + +This device tree binding describes a single 32 gate clocks group per node. +Clocks are referenced by user nodes by the MSTP node phandle and the clock +index in the group, from 0 to 31. + +Required Properties: + + - compatible: Must be one of the following + - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks + - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks + - "renesas,cpg-mstp-clock" for generic MSTP gate clocks + - reg: Base address and length of the I/O mapped registers used by the MSTP + clocks. The first register is the clock control register and is mandatory. + The second register is the clock status register and is optional when not + implemented in hardware. + - clocks: Reference to the parent clocks, one per output clock. The parents + must appear in the same order as the output clocks. + - #clock-cells: Must be 1 + - clock-output-names: The name of the clocks as free-form strings + - renesas,indices: Indices of the gate clocks into the group (0 to 31) + +The clocks, clock-output-names and renesas,indices properties contain one +entry per gate clock. The MSTP groups are sparsely populated. Unimplemented +gate clocks must not be declared. + + +Example +------- + + #include + + mstp3_clks: mstp3_clks@e615013c { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>; + clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>, + <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>, + <&mmc0_clk>; + #clock-cells = <1>; + clock-output-names = + "tpu0", "mmcif1", "sdhi3", "sdhi2", + "sdhi1", "sdhi0", "mmcif0"; + renesas,clock-indices = < + R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3 + R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 + R8A7790_CLK_MMCIF0 + >; + }; diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt new file mode 100644 index 000000000000..7b41c2fe54db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt @@ -0,0 +1,32 @@ +* Renesas R-Car Gen2 Clock Pulse Generator (CPG) + +The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs +and several fixed ratio dividers. + +Required Properties: + + - compatible: Must be one of + - "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG + - "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG + - "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG + + - reg: Base address and length of the memory resource used by the CPG + + - clocks: Reference to the parent clock + - #clock-cells: Must be 1 + - clock-output-names: The names of the clocks. Supported clocks are "main", + "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z" + + +Example +------- + + cpg_clocks: cpg_clocks@e6150000 { + compatible = "renesas,r8a7790-cpg-clocks", + "renesas,rcar-gen2-cpg-clocks"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>; + #clock-cells = <1>; + clock-output-names = "main", "pll0, "pll1", "pll3", + "lb", "qspi", "sdh", "sd0", "sd1", "z"; + }; diff --git a/Documentation/devicetree/bindings/clock/silabs,si570.txt b/Documentation/devicetree/bindings/clock/silabs,si570.txt new file mode 100644 index 000000000000..c09f21e1d98f --- /dev/null +++ b/Documentation/devicetree/bindings/clock/silabs,si570.txt @@ -0,0 +1,39 @@ +Binding for Silicon Labs 570, 571, 598 and 599 programmable +I2C clock generators. + +Reference +This binding uses the common clock binding[1]. Details about the devices can be +found in the data sheets[2][3]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Si570/571 Data Sheet + http://www.silabs.com/Support%20Documents/TechnicalDocs/si570.pdf +[3] Si598/599 Data Sheet + http://www.silabs.com/Support%20Documents/TechnicalDocs/si598-99.pdf + +Required properties: + - compatible: Shall be one of "silabs,si570", "silabs,si571", + "silabs,si598", "silabs,si599" + - reg: I2C device address. + - #clock-cells: From common clock bindings: Shall be 0. + - factory-fout: Factory set default frequency. This frequency is part specific. + The correct frequency for the part used has to be provided in + order to generate the correct output frequencies. For more + details, please refer to the data sheet. + - temperature-stability: Temperature stability of the device in PPM. Should be + one of: 7, 20, 50 or 100. + +Optional properties: + - clock-output-names: From common clock bindings. Recommended to be "si570". + - clock-frequency: Output frequency to generate. This defines the output + frequency set during boot. It can be reprogrammed during + runtime through the common clock framework. + +Example: + si570: clock-generator@5d { + #clock-cells = <0>; + compatible = "silabs,si570"; + temperature-stability = <50>; + reg = <0x5d>; + factory-fout = <156250000>; + }; diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index 91a748fed13d..c2cb7621ad2d 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -7,8 +7,10 @@ This binding uses the common clock binding[1]. Required properties: - compatible : shall be one of the following: "allwinner,sun4i-osc-clk" - for a gatable oscillator - "allwinner,sun4i-pll1-clk" - for the main PLL clock + "allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4 "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 + "allwinner,sun4i-pll5-clk" - for the PLL5 clock + "allwinner,sun4i-pll6-clk" - for the PLL6 clock "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock "allwinner,sun4i-axi-clk" - for the AXI clock "allwinner,sun4i-axi-gates-clk" - for the AXI gates @@ -33,10 +35,14 @@ Required properties: "allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20 "allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 + "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks + "allwinner,sun7i-a20-out-clk" - for the external output clocks Required properties for all clocks: - reg : shall be the control register address for the clock. -- clocks : shall be the input parent clock(s) phandle for the clock +- clocks : shall be the input parent clock(s) phandle for the clock. For + multiplexed clocks, the list order must match the hardware + programming order. - #clock-cells : from common clock binding; shall be set to 0 except for "allwinner,*-gates-clk" where it shall be set to 1 diff --git a/Documentation/devicetree/bindings/clock/zynq-7000.txt b/Documentation/devicetree/bindings/clock/zynq-7000.txt index d99af878f5d7..17b4a94916d6 100644 --- a/Documentation/devicetree/bindings/clock/zynq-7000.txt +++ b/Documentation/devicetree/bindings/clock/zynq-7000.txt @@ -22,6 +22,10 @@ Required properties: Optional properties: - clocks : as described in the clock bindings - clock-names : as described in the clock bindings + - fclk-enable : Bit mask to enable FCLKs statically at boot time. + Bit [0..3] correspond to FCLK0..FCLK3. The corresponding + FCLK will only be enabled if it is actually running at + boot time. Clock inputs: The following strings are optional parameters to the 'clock-names' property in diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt index 051f764bedb8..f055515d2b62 100644 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt @@ -15,6 +15,10 @@ Optional properties: - clock-latency: Specify the possible maximum transition latency for clock, in unit of nanoseconds. - voltage-tolerance: Specify the CPU voltage tolerance in percentage. +- #cooling-cells: +- cooling-min-level: +- cooling-max-level: + Please refer to Documentation/devicetree/bindings/thermal/thermal.txt. Examples: @@ -33,6 +37,9 @@ cpus { 198000 850000 >; clock-latency = <61036>; /* two CLK32 periods */ + #cooling-cells = <2>; + cooling-min-level = <0>; + cooling-max-level = <2>; }; cpu@1 { diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt new file mode 100644 index 000000000000..f2aab3dc2b52 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt @@ -0,0 +1,68 @@ +* Atmel HW cryptographic accelerators + +These are the HW cryptographic accelerators found on some Atmel products. + +* Advanced Encryption Standard (AES) + +Required properties: +- compatible : Should be "atmel,at91sam9g46-aes". +- reg: Should contain AES registers location and length. +- interrupts: Should contain the IRQ line for the AES. +- dmas: List of two DMA specifiers as described in + atmel-dma.txt and dma.txt files. +- dma-names: Contains one identifier string for each DMA specifier + in the dmas property. + +Example: +aes@f8038000 { + compatible = "atmel,at91sam9g46-aes"; + reg = <0xf8038000 0x100>; + interrupts = <43 4 0>; + dmas = <&dma1 2 18>, + <&dma1 2 19>; + dma-names = "tx", "rx"; + +* Triple Data Encryption Standard (Triple DES) + +Required properties: +- compatible : Should be "atmel,at91sam9g46-tdes". +- reg: Should contain TDES registers location and length. +- interrupts: Should contain the IRQ line for the TDES. + +Optional properties: +- dmas: List of two DMA specifiers as described in + atmel-dma.txt and dma.txt files. +- dma-names: Contains one identifier string for each DMA specifier + in the dmas property. + +Example: +tdes@f803c000 { + compatible = "atmel,at91sam9g46-tdes"; + reg = <0xf803c000 0x100>; + interrupts = <44 4 0>; + dmas = <&dma1 2 20>, + <&dma1 2 21>; + dma-names = "tx", "rx"; +}; + +* Secure Hash Algorithm (SHA) + +Required properties: +- compatible : Should be "atmel,at91sam9g46-sha". +- reg: Should contain SHA registers location and length. +- interrupts: Should contain the IRQ line for the SHA. + +Optional properties: +- dmas: One DMA specifiers as described in + atmel-dma.txt and dma.txt files. +- dma-names: Contains one identifier string for each DMA specifier + in the dmas property. Only one "tx" string needed. + +Example: +sha@f8034000 { + compatible = "atmel,at91sam9g46-sha"; + reg = <0xf8034000 0x100>; + interrupts = <42 4 0>; + dmas = <&dma1 2 17>; + dma-names = "tx"; +}; diff --git a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt new file mode 100644 index 000000000000..6949e50f1f16 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt @@ -0,0 +1,17 @@ +Freescale DCP (Data Co-Processor) found on i.MX23/i.MX28 . + +Required properties: +- compatible : Should be "fsl,-dcp" +- reg : Should contain MXS DCP registers location and length +- interrupts : Should contain MXS DCP interrupt numbers, VMI IRQ and DCP IRQ + must be supplied, optionally Secure IRQ can be present, but + is currently not implemented and not used. + +Example: + +dcp@80028000 { + compatible = "fsl,imx28-dcp", "fsl,imx23-dcp"; + reg = <0x80028000 0x2000>; + interrupts = <52 53>; + status = "okay"; +}; diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index a8c21c256baa..1f5729f10621 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -50,6 +50,9 @@ Each dmas request consists of 4 cells: 0x00000008: Use fixed channel: Use automatic channel selection when unset Use DMA request line number when set + 0x00000010: Set channel as high priority: + Normal priority when unset + High priority when set Example: diff --git a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt index 90fa7da525b8..c6908e7c42cc 100644 --- a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt +++ b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt @@ -5,6 +5,16 @@ Required properties: - reg: Should contain DMA registers location and length. This shuld include all of the per-channel registers. - interrupts: Should contain all of the per-channel DMA interrupts. +- clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - dma +- #dma-cells : Must be <1>. This dictates the length of DMA specifiers in + client nodes' dmas properties. The specifier represents the DMA request + select value for the peripheral. For more details, consult the Tegra TRM's + documentation of the APB DMA channel control register REQ_SEL field. Examples: @@ -27,4 +37,8 @@ apbdma: dma@6000a000 { 0 149 0x04 0 150 0x04 0 151 0x04 >; + clocks = <&tegra_car 34>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/extcon/extcon-palmas.txt b/Documentation/devicetree/bindings/extcon/extcon-palmas.txt index 7dab6a8f4a0e..45414bbcd945 100644 --- a/Documentation/devicetree/bindings/extcon/extcon-palmas.txt +++ b/Documentation/devicetree/bindings/extcon/extcon-palmas.txt @@ -2,7 +2,11 @@ EXTCON FOR PALMAS/TWL CHIPS PALMAS USB COMPARATOR Required Properties: - - compatible : Should be "ti,palmas-usb" or "ti,twl6035-usb" + - compatible: should contain one of: + * "ti,palmas-usb-vid". + * "ti,twl6035-usb-vid". + * "ti,palmas-usb" (DEPRECATED - use "ti,palmas-usb-vid"). + * "ti,twl6035-usb" (DEPRECATED - use "ti,twl6035-usb-vid"). Optional Properties: - ti,wakeup : To enable the wakeup comparator in probe diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt new file mode 100644 index 000000000000..a2e839d6e338 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt @@ -0,0 +1,41 @@ +Davinci GPIO controller bindings + +Required Properties: +- compatible: should be "ti,dm6441-gpio" + +- reg: Physical base address of the controller and the size of memory mapped + registers. + +- gpio-controller : Marks the device node as a gpio controller. + +- interrupt-parent: phandle of the parent interrupt controller. + +- interrupts: Array of GPIO interrupt number. Only banked or unbanked IRQs are + supported at a time. + +- ti,ngpio: The number of GPIO pins supported. + +- ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt + line to processor. + +The GPIO controller also acts as an interrupt controller. It uses the default +two cells specifier as described in Documentation/devicetree/bindings/ +interrupt-controller/interrupts.txt. + +Example: + +gpio: gpio@1e26000 { + compatible = "ti,dm6441-gpio"; + gpio-controller; + reg = <0x226000 0x1000>; + interrupt-parent = <&intc>; + interrupts = <42 IRQ_TYPE_EDGE_BOTH 43 IRQ_TYPE_EDGE_BOTH + 44 IRQ_TYPE_EDGE_BOTH 45 IRQ_TYPE_EDGE_BOTH + 46 IRQ_TYPE_EDGE_BOTH 47 IRQ_TYPE_EDGE_BOTH + 48 IRQ_TYPE_EDGE_BOTH 49 IRQ_TYPE_EDGE_BOTH + 50 IRQ_TYPE_EDGE_BOTH>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + interrupt-controller; + #interrupt-cells = <2>; +}; diff --git a/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt new file mode 100644 index 000000000000..80fcb7d70e13 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-lp3943.txt @@ -0,0 +1,37 @@ +TI/National Semiconductor LP3943 GPIO controller + +Required properties: + - compatible: "ti,lp3943-gpio" + - gpio-controller: Marks the device node as a GPIO controller. + - #gpio-cells: Should be 2. See gpio.txt in this directory for a + description of the cells format. + +Example: +Simple LED controls with LP3943 GPIO controller + +&i2c4 { + lp3943@60 { + compatible = "ti,lp3943"; + reg = <0x60>; + + gpioex: gpio { + compatible = "ti,lp3943-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + }; +}; + +leds { + compatible = "gpio-leds"; + indicator1 { + label = "indi1"; + gpios = <&gpioex 9 GPIO_ACTIVE_LOW>; + }; + + indicator2 { + label = "indi2"; + gpios = <&gpioex 10 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; +}; diff --git a/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt b/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt index daa30174bcc1..3ddc7ccfe5f3 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-mcp23s08.txt @@ -38,12 +38,38 @@ Required device specific properties (only for SPI chips): removed. - spi-max-frequency = The maximum frequency this chip is able to handle -Example I2C: +Optional properties: +- #interrupt-cells : Should be two. + - first cell is the pin number + - second cell is used to specify flags. +- interrupt-controller: Marks the device node as a interrupt controller. +NOTE: The interrupt functionality is only supported for i2c versions of the +chips. The spi chips can also do the interrupts, but this is not supported by +the linux driver yet. + +Optional device specific properties: +- microchip,irq-mirror: Sets the mirror flag in the IOCON register. Devices + with two interrupt outputs (these are the devices ending with 17 and + those that have 16 IOs) have two IO banks: IO 0-7 form bank 1 and + IO 8-15 are bank 2. These chips have two different interrupt outputs: + One for bank 1 and another for bank 2. If irq-mirror is set, both + interrupts are generated regardless of the bank that an input change + occured on. If it is not set, the interrupt are only generated for the + bank they belong to. + On devices with only one interrupt output this property is useless. + +Example I2C (with interrupt): gpiom1: gpio@20 { compatible = "microchip,mcp23017"; gpio-controller; #gpio-cells = <2>; reg = <0x20>; + + interrupt-parent = <&gpio1>; + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells=<2>; + microchip,irq-mirror; }; Example SPI: diff --git a/Documentation/devicetree/bindings/gpio/moxa,moxart-gpio.txt b/Documentation/devicetree/bindings/gpio/moxa,moxart-gpio.txt new file mode 100644 index 000000000000..f8e8f185a3db --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/moxa,moxart-gpio.txt @@ -0,0 +1,19 @@ +MOXA ART GPIO Controller + +Required properties: + +- #gpio-cells : Should be 2, The first cell is the pin number, + the second cell is used to specify polarity: + 0 = active high + 1 = active low +- compatible : Must be "moxa,moxart-gpio" +- reg : Should contain registers location and length + +Example: + + gpio: gpio@98700000 { + gpio-controller; + #gpio-cells = <2>; + compatible = "moxa,moxart-gpio"; + reg = <0x98700000 0xC>; + }; diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt index 8655df9440d5..f61cef74a212 100644 --- a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt +++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt @@ -2,10 +2,11 @@ Required Properties: - - compatible: should be one of the following. + - compatible: should contain one of the following. - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller. - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller. + - "renesas,gpio-r8a7791": for R8A7791 (R-Car M2) compatible GPIO controller. - "renesas,gpio-rcar": for generic R-Car GPIO controller. - reg: Base address and length of each memory resource used by the GPIO diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt index b4fa934ae3a2..ab45c02aa658 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt @@ -9,6 +9,12 @@ Required properties: - #size-cells: The number of cells used to represent the size of an address range in the host1x address space. Should be 1. - ranges: The mapping of the host1x address space to the CPU address space. +- clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - host1x The host1x top-level node defines a number of children, each representing one of the following host1x client modules: @@ -19,6 +25,12 @@ of the following host1x client modules: - compatible: "nvidia,tegra-mpe" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - mpe - vi: video input @@ -26,6 +38,12 @@ of the following host1x client modules: - compatible: "nvidia,tegra-vi" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - vi - epp: encoder pre-processor @@ -33,6 +51,12 @@ of the following host1x client modules: - compatible: "nvidia,tegra-epp" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - epp - isp: image signal processor @@ -40,6 +64,12 @@ of the following host1x client modules: - compatible: "nvidia,tegra-isp" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - isp - gr2d: 2D graphics engine @@ -47,12 +77,30 @@ of the following host1x client modules: - compatible: "nvidia,tegra-gr2d" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - 2d - gr3d: 3D graphics engine Required properties: - compatible: "nvidia,tegra-gr3d" - reg: Physical base address and length of the controller's registers. + - clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. + - clock-names: Must include the following entries: + (This property may be omitted if the only clock in the list is "3d") + - 3d + This MUST be the first entry. + - 3d2 (Only required on SoCs with two 3D clocks) + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - 3d + - 3d2 (Only required on SoCs with two 3D clocks) - dc: display controller @@ -60,6 +108,16 @@ of the following host1x client modules: - compatible: "nvidia,tegra-dc" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. + - clock-names: Must include the following entries: + - dc + This MUST be the first entry. + - parent + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - dc Each display controller node has a child node, named "rgb", that represents the RGB output associated with the controller. It can take the following @@ -76,6 +134,16 @@ of the following host1x client modules: - interrupts: The interrupt outputs from the controller. - vdd-supply: regulator for supply voltage - pll-supply: regulator for PLL + - clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. + - clock-names: Must include the following entries: + - hdmi + This MUST be the first entry. + - parent + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - hdmi Optional properties: - nvidia,ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing @@ -88,12 +156,24 @@ of the following host1x client modules: - compatible: "nvidia,tegra-tvo" - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt outputs from the controller. + - clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. - dsi: display serial interface Required properties: - compatible: "nvidia,tegra-dsi" - reg: Physical base address and length of the controller's registers. + - clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. + - clock-names: Must include the following entries: + - dsi + This MUST be the first entry. + - parent + - resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names: Must include the following entries: + - dsi Example: @@ -105,6 +185,9 @@ Example: reg = <0x50000000 0x00024000>; interrupts = <0 65 0x04 /* mpcore syncpt */ 0 67 0x04>; /* mpcore general */ + clocks = <&tegra_car TEGRA20_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; #address-cells = <1>; #size-cells = <1>; @@ -115,41 +198,64 @@ Example: compatible = "nvidia,tegra20-mpe"; reg = <0x54040000 0x00040000>; interrupts = <0 68 0x04>; + clocks = <&tegra_car TEGRA20_CLK_MPE>; + resets = <&tegra_car 60>; + reset-names = "mpe"; }; vi { compatible = "nvidia,tegra20-vi"; reg = <0x54080000 0x00040000>; interrupts = <0 69 0x04>; + clocks = <&tegra_car TEGRA20_CLK_VI>; + resets = <&tegra_car 100>; + reset-names = "vi"; }; epp { compatible = "nvidia,tegra20-epp"; reg = <0x540c0000 0x00040000>; interrupts = <0 70 0x04>; + clocks = <&tegra_car TEGRA20_CLK_EPP>; + resets = <&tegra_car 19>; + reset-names = "epp"; }; isp { compatible = "nvidia,tegra20-isp"; reg = <0x54100000 0x00040000>; interrupts = <0 71 0x04>; + clocks = <&tegra_car TEGRA20_CLK_ISP>; + resets = <&tegra_car 23>; + reset-names = "isp"; }; gr2d { compatible = "nvidia,tegra20-gr2d"; reg = <0x54140000 0x00040000>; interrupts = <0 72 0x04>; + clocks = <&tegra_car TEGRA20_CLK_GR2D>; + resets = <&tegra_car 21>; + reset-names = "2d"; }; gr3d { compatible = "nvidia,tegra20-gr3d"; reg = <0x54180000 0x00040000>; + clocks = <&tegra_car TEGRA20_CLK_GR3D>; + resets = <&tegra_car 24>; + reset-names = "3d"; }; dc@54200000 { compatible = "nvidia,tegra20-dc"; reg = <0x54200000 0x00040000>; interrupts = <0 73 0x04>; + clocks = <&tegra_car TEGRA20_CLK_DISP1>, + <&tegra_car TEGRA20_CLK_PLL_P>; + clock-names = "disp1", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; rgb { status = "disabled"; @@ -160,6 +266,11 @@ Example: compatible = "nvidia,tegra20-dc"; reg = <0x54240000 0x00040000>; interrupts = <0 74 0x04>; + clocks = <&tegra_car TEGRA20_CLK_DISP2>, + <&tegra_car TEGRA20_CLK_PLL_P>; + clock-names = "disp2", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; rgb { status = "disabled"; @@ -170,6 +281,11 @@ Example: compatible = "nvidia,tegra20-hdmi"; reg = <0x54280000 0x00040000>; interrupts = <0 75 0x04>; + clocks = <&tegra_car TEGRA20_CLK_HDMI>, + <&tegra_car TEGRA20_CLK_PLL_D_OUT0>; + clock-names = "hdmi", "parent"; + resets = <&tegra_car 51>; + reset-names = "hdmi"; status = "disabled"; }; @@ -177,12 +293,18 @@ Example: compatible = "nvidia,tegra20-tvo"; reg = <0x542c0000 0x00040000>; interrupts = <0 76 0x04>; + clocks = <&tegra_car TEGRA20_CLK_TVO>; status = "disabled"; }; dsi { compatible = "nvidia,tegra20-dsi"; reg = <0x54300000 0x00040000>; + clocks = <&tegra_car TEGRA20_CLK_DSI>, + <&tegra_car TEGRA20_CLK_PLL_D_OUT0>; + clock-names = "dsi", "parent"; + resets = <&tegra_car 48>; + reset-names = "dsi"; status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-at91.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt index b689a0d9441c..4fade84bea16 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-at91.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-at91.txt @@ -9,6 +9,7 @@ Required properties : - interrupts: interrupt number to the cpu. - #address-cells = <1>; - #size-cells = <0>; +- clocks: phandles to input clocks. Optional properties: - Child nodes conforming to i2c bus binding @@ -21,6 +22,7 @@ i2c0: i2c@fff84000 { interrupts = <12 4 6>; #address-cells = <1>; #size-cells = <0>; + clocks = <&twi0_clk>; 24c512@50 { compatible = "24c512"; diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt new file mode 100644 index 000000000000..34a3fb6f8488 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt @@ -0,0 +1,50 @@ +* NXP PCA954x I2C bus switch + +Required Properties: + + - compatible: Must contain one of the following. + "nxp,pca9540", "nxp,pca9542", "nxp,pca9543", "nxp,pca9544", + "nxp,pca9545", "nxp,pca9546", "nxp,pca9547", "nxp,pca9548" + + - reg: The I2C address of the device. + + The following required properties are defined externally: + + - Standard I2C mux properties. See i2c-mux.txt in this directory. + - I2C child bus nodes. See i2c-mux.txt in this directory. + +Optional Properties: + + - reset-gpios: Reference to the GPIO connected to the reset input. + + +Example: + + i2c-switch@74 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + eeprom@54 { + compatible = "at,24c08"; + reg = <0x54>; + }; + }; + + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt index 82e8f6f17179..582b4652a82a 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt @@ -5,7 +5,11 @@ Required properties : - reg : Offset and length of the register set for the device - compatible : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c" - or "marvell,mv78230-i2c" + or "marvell,mv78230-i2c" or "marvell,mv78230-a0-i2c" + Note: Only use "marvell,mv78230-a0-i2c" for a very rare, + initial version of the SoC which had broken offload + support. Linux auto-detects this and sets it + appropriately. - interrupts : The interrupt number Optional properties : diff --git a/Documentation/devicetree/bindings/i2c/i2c-riic.txt b/Documentation/devicetree/bindings/i2c/i2c-riic.txt new file mode 100644 index 000000000000..0bcc4716c319 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-riic.txt @@ -0,0 +1,29 @@ +Device tree configuration for Renesas RIIC driver + +Required properties: +- compatible : "renesas,riic-". "renesas,riic-rz" as fallback +- reg : address start and address range size of device +- interrupts : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI) +- clock-frequency : frequency of bus clock in Hz +- #address-cells : should be <1> +- #size-cells : should be <0> + +Pinctrl properties might be needed, too. See there. + +Example: + + i2c0: i2c@fcfee000 { + compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; + reg = <0xfcfee000 0x44>; + interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>, + <0 158 IRQ_TYPE_EDGE_RISING>, + <0 159 IRQ_TYPE_EDGE_RISING>, + <0 160 IRQ_TYPE_LEVEL_HIGH>, + <0 161 IRQ_TYPE_LEVEL_HIGH>, + <0 162 IRQ_TYPE_LEVEL_HIGH>, + <0 163 IRQ_TYPE_LEVEL_HIGH>, + <0 164 IRQ_TYPE_LEVEL_HIGH>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt index 296eb4536129..278de8e64bbf 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt @@ -10,6 +10,8 @@ Required properties: inside HDMIPHY block found on several samsung SoCs (d) "samsung, exynos5440-i2c", for s3c2440-like i2c used on EXYNOS5440 which does not need GPIO configuration. + (e) "samsung, exynos5-sata-phy-i2c", for s3c2440-like i2c used as + a host to SATA PHY controller on an internal bus. - reg: physical base address of the controller and length of memory mapped region. - interrupts: interrupt number to the cpu. diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt index ef77cc7a0e46..87507e9ce6db 100644 --- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt +++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt @@ -39,12 +39,23 @@ Required properties: - interrupts: Should contain I2C controller interrupts. - address-cells: Address cells for I2C device address. - size-cells: Size of the I2C device address. -- clocks: Clock ID as per - Documentation/devicetree/bindings/clock/tegra.txt - for I2C controller. -- clock-names: Name of the clock: - Tegra20/Tegra30 I2C controller: "div-clk and "fast-clk". - Tegra114 I2C controller: "div-clk". +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: Must include the following entries: + Tegra20/Tegra30: + - div-clk + - fast-clk + Tegra114: + - div-clk +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - i2c +- dmas: Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names: Must include the following entries: + - rx + - tx Example: @@ -56,5 +67,9 @@ Example: #size-cells = <0>; clocks = <&tegra_car 12>, <&tegra_car 124>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index c65f71cfaa5c..1a1ac2e560e9 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -40,6 +40,7 @@ fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) +isl,isl12057 Intersil ISL12057 I2C RTC Chip maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface diff --git a/Documentation/devicetree/bindings/input/gpio-beeper.txt b/Documentation/devicetree/bindings/input/gpio-beeper.txt new file mode 100644 index 000000000000..a5086e37fce6 --- /dev/null +++ b/Documentation/devicetree/bindings/input/gpio-beeper.txt @@ -0,0 +1,13 @@ +* GPIO beeper device tree bindings + +Register a beeper connected to GPIO pin. + +Required properties: +- compatible: Should be "gpio-beeper". +- gpios: From common gpio binding; gpio connection to beeper enable pin. + +Example: + beeper: beeper { + compatible = "gpio-beeper"; + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt index 2995fae7ee47..0382b8bd69c6 100644 --- a/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt +++ b/Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt @@ -13,6 +13,12 @@ Required properties: array of pin numbers which is used as column. - linux,keymap: The keymap for keys as described in the binding document devicetree/bindings/input/matrix-keymap.txt. +- clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - kbc Optional properties, in addition to those specified by the shared matrix-keyboard bindings: @@ -31,6 +37,9 @@ keyboard: keyboard { compatible = "nvidia,tegra20-kbc"; reg = <0x7000e200 0x100>; interrupts = <0 85 0x04>; + clocks = <&tegra_car 36>; + resets = <&tegra_car 36>; + reset-names = "kbc"; nvidia,ghost-filter; nvidia,debounce-delay-ms = <640>; nvidia,kbc-row-pins = <0 1 2>; /* pin 0, 1, 2 as rows */ diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt new file mode 100644 index 000000000000..ec365e172236 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2007.txt @@ -0,0 +1,41 @@ +* Texas Instruments tsc2007 touchscreen controller + +Required properties: +- compatible: must be "ti,tsc2007". +- reg: I2C address of the chip. +- ti,x-plate-ohms: X-plate resistance in ohms. + +Optional properties: +- gpios: the interrupt gpio the chip is connected to (trough the penirq pin). + The penirq pin goes to low when the panel is touched. + (see GPIO binding[1] for more details). +- interrupt-parent: the phandle for the gpio controller + (see interrupt binding[0]). +- interrupts: (gpio) interrupt to which the chip is connected + (see interrupt binding[0]). +- ti,max-rt: maximum pressure. +- ti,fuzzx: specifies the absolute input fuzz x value. + If set, it will permit noise in the data up to +- the value given to the fuzz + parameter, that is used to filter noise from the event stream. +- ti,fuzzy: specifies the absolute input fuzz y value. +- ti,fuzzz: specifies the absolute input fuzz z value. +- ti,poll-period: how much time to wait (in milliseconds) before reading again the + values from the tsc2007. + +[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +[1]: Documentation/devicetree/bindings/gpio/gpio.txt + +Example: + &i2c1 { + /* ... */ + tsc2007@49 { + compatible = "ti,tsc2007"; + reg = <0x49>; + interrupt-parent = <&gpio4>; + interrupts = <0x0 0x8>; + gpios = <&gpio4 0 0>; + ti,x-plate-ohms = <180>; + }; + + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/input/twl4030-keypad.txt b/Documentation/devicetree/bindings/input/twl4030-keypad.txt new file mode 100644 index 000000000000..e4be2f76a717 --- /dev/null +++ b/Documentation/devicetree/bindings/input/twl4030-keypad.txt @@ -0,0 +1,27 @@ +* TWL4030's Keypad Controller device tree bindings + +TWL4030's Keypad controller is used to interface a SoC with a matrix-type +keypad device. The keypad controller supports multiple row and column lines. +A key can be placed at each intersection of a unique row and a unique column. +The keypad controller can sense a key-press and key-release and report the +event using a interrupt to the cpu. + +This binding is based on the matrix-keymap binding with the following +changes: + + * keypad,num-rows and keypad,num-columns are required. + +Required SoC Specific Properties: +- compatible: should be one of the following + - "ti,twl4030-keypad": For controllers compatible with twl4030 keypad + controller. +- interrupt: should be one of the following + - <1>: For controllers compatible with twl4030 keypad controller. + +Example: + twl_keypad: keypad { + compatible = "ti,twl4030-keypad"; + interrupts = <1>; + keypad,num-rows = <8>; + keypad,num-columns = <8>; + }; diff --git a/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt b/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt new file mode 100644 index 000000000000..c864a46cddcf --- /dev/null +++ b/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt @@ -0,0 +1,21 @@ +Texas Instruments TWL family (twl4030) pwrbutton module + +This module is part of the TWL4030. For more details about the whole +chip see Documentation/devicetree/bindings/mfd/twl-familly.txt. + +This module provides a simple power button event via an Interrupt. + +Required properties: +- compatible: should be one of the following + - "ti,twl4030-pwrbutton": For controllers compatible with twl4030 +- interrupts: should be one of the following + - <8>: For controllers compatible with twl4030 + +Example: + +&twl { + twl_pwrbutton: pwrbutton { + compatible = "ti,twl4030-pwrbutton"; + interrupts = <8>; + }; +}; diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt index 3d3b2b91e333..32cec4b26cd0 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sun4i-ic.txt @@ -14,5 +14,5 @@ intc: interrupt-controller { compatible = "allwinner,sun4i-ic"; reg = <0x01c20400 0x400>; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt b/Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt new file mode 100644 index 000000000000..492911744ca3 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt @@ -0,0 +1,32 @@ +Synopsys DesignWare APB interrupt controller (dw_apb_ictl) + +Synopsys DesignWare provides interrupt controller IP for APB known as +dw_apb_ictl. The IP is used as secondary interrupt controller in some SoCs with +APB bus, e.g. Marvell Armada 1500. + +Required properties: +- compatible: shall be "snps,dw-apb-ictl" +- reg: physical base address of the controller and length of memory mapped + region starting with ENABLE_LOW register +- interrupt-controller: identifies the node as an interrupt controller +- #interrupt-cells: number of cells to encode an interrupt-specifier, shall be 1 +- interrupts: interrupt reference to primary interrupt controller +- interrupt-parent: (optional) reference specific primary interrupt controller + +The interrupt sources map to the corresponding bits in the interrupt +registers, i.e. +- 0 maps to bit 0 of low interrupts, +- 1 maps to bit 1 of low interrupts, +- 32 maps to bit 0 of high interrupts, +- 33 maps to bit 1 of high interrupts, +- (optional) fast interrupts start at 64. + +Example: + aic: interrupt-controller@3000 { + compatible = "snps,dw-apb-ictl"; + reg = <0x3000 0xc00>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic>; + interrupts = ; + }; diff --git a/Documentation/devicetree/bindings/marvell.txt b/Documentation/devicetree/bindings/marvell.txt index f7a0da6b4022..ea2b16ced49b 100644 --- a/Documentation/devicetree/bindings/marvell.txt +++ b/Documentation/devicetree/bindings/marvell.txt @@ -79,7 +79,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Required properties: - #address-cells : Should be <1> - #size-cells : Should be <0> - - device_type : Should be "mdio" - compatible : Should be "marvell,mv64360-mdio" Example: @@ -87,7 +86,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. mdio { #address-cells = <1>; #size-cells = <0>; - device_type = "mdio"; compatible = "marvell,mv64360-mdio"; ethernet-phy@0 { @@ -132,7 +130,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Ethernet port node Required properties: - - device_type : Should be "network". - compatible : Should be "marvell,mv64360-eth". - reg : Should be <0>, <1>, or <2>, according to which registers within the silicon block the device uses. @@ -145,7 +142,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Example Discovery Ethernet port node: ethernet@0 { - device_type = "network"; compatible = "marvell,mv64360-eth"; reg = <0>; interrupts = <32>; @@ -159,7 +155,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. c) Marvell Discovery PHY nodes Required properties: - - device_type : Should be "ethernet-phy" - interrupts : where a is the interrupt number for this phy. - interrupt-parent : the phandle for the interrupt controller that services interrupts for this device. @@ -167,7 +162,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Example Discovery PHY node: ethernet-phy@1 { - device_type = "ethernet-phy"; compatible = "broadcom,bcm5421"; interrupts = <76>; /* GPP 12 */ interrupt-parent = <&PIC>; @@ -271,7 +265,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. serial port. Required properties: - - device_type : "serial" - compatible : "marvell,mv64360-mpsc" - reg : Offset and length of the register set for this device - sdma : the phandle for the SDMA node used by this port @@ -288,7 +281,6 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd. Example Discovery MPSCINTR node: mpsc@8000 { - device_type = "serial"; compatible = "marvell,mv64360-mpsc"; reg = <0x8000 0x38>; virtual-reg = <0xf1008000>; diff --git a/Documentation/devicetree/bindings/mfd/as3722.txt b/Documentation/devicetree/bindings/mfd/as3722.txt index fc2191ecfd6b..8edcb9bd873b 100644 --- a/Documentation/devicetree/bindings/mfd/as3722.txt +++ b/Documentation/devicetree/bindings/mfd/as3722.txt @@ -112,6 +112,15 @@ Following are properties of regulator subnode. ams,enable-tracking: Enable tracking with SD1, only supported by LDO3. +Power-off: +========= +AS3722 supports the system power off by turning off all its rail. This +is provided through pm_power_off. +The device node should have the following properties to enable this +functionality +ams,system-power-controller: Boolean, to enable the power off functionality + through this device. + Example: -------- #include @@ -120,6 +129,8 @@ ams3722 { compatible = "ams,as3722"; reg = <0x48>; + ams,system-power-controller; + interrupt-parent = <&intc>; interrupt-controller; #interrupt-cells = <2>; diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt index 5f229c5f6da9..8009c3d87f33 100644 --- a/Documentation/devicetree/bindings/mfd/cros-ec.txt +++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt @@ -17,6 +17,15 @@ Required properties (SPI): - compatible: "google,cros-ec-spi" - reg: SPI chip select +Optional properties (SPI): +- google,cros-ec-spi-msg-delay: Some implementations of the EC require some + additional processing time in order to accept new transactions. If the delay + between transactions is not long enough the EC may not be able to respond + properly to subsequent transactions and cause them to hang. This property + specifies the delay, in usecs, introduced between transactions to account + for the time required by the EC to get back into a state in which new data + can be accepted. + Required properties (LPC): - compatible: "google,cros-ec-lpc" - reg: List of (IO address, size) pairs defining the interface uses diff --git a/Documentation/devicetree/bindings/mfd/lp3943.txt b/Documentation/devicetree/bindings/mfd/lp3943.txt new file mode 100644 index 000000000000..e8591d6b11b4 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/lp3943.txt @@ -0,0 +1,33 @@ +TI/National Semiconductor LP3943 MFD driver + +Required properties: + - compatible: "ti,lp3943" + - reg: I2C slave address. From 0x60 to 0x67. + +LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm. + +For the LP3943 GPIO properties please refer to: +Documentation/devicetree/bindings/gpio/gpio-lp3943.txt + +For the LP3943 PWM properties please refer to: +Documentation/devicetree/bindings/pwm/pwm-lp3943.txt + +Example: + +lp3943@60 { + compatible = "ti,lp3943"; + reg = <0x60>; + + gpioex: gpio { + compatible = "ti,lp3943-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + + pwm3943: pwm { + compatible = "ti,lp3943-pwm"; + #pwm-cells = <2>; + ti,pwm0 = <8 9 10>; + ti,pwm1 = <15>; + }; +}; diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt index c6a3469d3436..678f3cf0b8f0 100644 --- a/Documentation/devicetree/bindings/mfd/max77686.txt +++ b/Documentation/devicetree/bindings/mfd/max77686.txt @@ -7,6 +7,9 @@ different i2c slave address,presently for which we are statically creating i2c client while probing.This document describes the binding for mfd device and PMIC submodule. +Binding for the built-in 32k clock generator block is defined separately +in bindings/clk/maxim,max77686.txt file. + Required properties: - compatible : Must be "maxim,max77686"; - reg : Specifies the i2c slave address of PMIC block. diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt index 78a840d7510d..15ee89c3cc7b 100644 --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt @@ -60,7 +60,7 @@ as per the datasheet of s2mps11. - LDOn - valid values for n are 1 to 38 - - Example: LDO0, LD01, LDO28 + - Example: LDO1, LD02, LDO28 - BUCKn - valid values for n are 1 to 10. - Example: BUCK1, BUCK2, BUCK9 diff --git a/Documentation/devicetree/bindings/mfd/tps65910.txt b/Documentation/devicetree/bindings/mfd/tps65910.txt index 2e3304888ffc..b4bd98af1cc7 100644 --- a/Documentation/devicetree/bindings/mfd/tps65910.txt +++ b/Documentation/devicetree/bindings/mfd/tps65910.txt @@ -21,7 +21,7 @@ Required properties: The valid regulator-compatible values are: tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1, - vaux2, vaux33, vmmc + vaux2, vaux33, vmmc, vbb tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8 @@ -38,7 +38,7 @@ Required properties: vcc4-supply: VAUX1 and VAUX2 input. vcc5-supply: VPLL and VDAC input. vcc6-supply: VDIG1 and VDIG2 input. - vcc7-supply: VRTC input. + vcc7-supply: VRTC and VBB input. vccio-supply: VIO input. tps65911: vcc1-supply: VDD1 input. diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt index a45ae08c8ed1..60960b2755f4 100644 --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -6,6 +6,9 @@ Required properties: - atmel,at91sam9g45-ssc: support dma transfer - reg: Should contain SSC registers location and length - interrupts: Should contain SSC interrupt +- clock-names: tuple listing input clock names. + Required elements: "pclk" +- clocks: phandles to input clocks. Required properties for devices compatible with "atmel,at91sam9g45-ssc": @@ -20,6 +23,8 @@ ssc0: ssc@fffbc000 { compatible = "atmel,at91rm9200-ssc"; reg = <0xfffbc000 0x4000>; interrupts = <14 4 5>; + clocks = <&ssc0_clk>; + clock-names = "pclk"; }; - DMA transfer: diff --git a/Documentation/devicetree/bindings/misc/bmp085.txt b/Documentation/devicetree/bindings/misc/bmp085.txt index 91dfda2e4e11..d7a6deb6b21e 100644 --- a/Documentation/devicetree/bindings/misc/bmp085.txt +++ b/Documentation/devicetree/bindings/misc/bmp085.txt @@ -8,6 +8,8 @@ Optional properties: - temp-measurement-period: temperature measurement period (milliseconds) - default-oversampling: default oversampling value to be used at startup, value range is 0-3 with rising sensitivity. +- interrupt-parent: should be the phandle for the interrupt controller +- interrupts: interrupt mapping for IRQ Example: @@ -17,4 +19,6 @@ pressure@77 { chip-id = <10>; temp-measurement-period = <100>; default-oversampling = <2>; + interrupt-parent = <&gpio0>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; }; diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt new file mode 100644 index 000000000000..98ee2abbe138 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -0,0 +1,27 @@ +Device Tree Bindings for the Arasan SDHCI Controller + + The bindings follow the mmc[1], clock[2] and interrupt[3] bindings. Only + deviations are documented here. + + [1] Documentation/devicetree/bindings/mmc/mmc.txt + [2] Documentation/devicetree/bindings/clock/clock-bindings.txt + [3] Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + +Required Properties: + - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' + - reg: From mmc bindings: Register location and length. + - clocks: From clock bindings: Handles to clock inputs. + - clock-names: From clock bindings: Tuple including "clk_xin" and "clk_ahb" + - interrupts: Interrupt specifier + - interrupt-parent: Phandle for the interrupt controller that services + interrupts for this device. + +Example: + sdhci@e0100000 { + compatible = "arasan,sdhci-8.9a"; + reg = <0xe0100000 0x1000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&clkc 21>, <&clkc 32>; + interrupt-parent = <&gic>; + interrupts = <0 24 4>; + } ; diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt index c67b975c8906..532b1d440abc 100644 --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt @@ -16,6 +16,8 @@ Required Properties: specific extensions. - "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250 specific extensions. + - "samsung,exynos5420-dw-mshc": for controllers with Samsung Exynos5420 + specific extensions. * samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface unit (ciu) clock. This property is applicable only for Exynos5 SoC's and diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index 000000000000..b8653ea97957 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,46 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - "hisilicon,hi4511-dw-mshc": for controllers with hi4511 specific extentions. + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = "hisilicon,hi4511-dw-mshc"; + reg = <0xfcd03000 0x1000>; + interrupts = <0 16 4>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&mmc_clock HI3620_SD_CIUCLK>, <&clock HI3620_DDRC_PER_CLK>; + clock-names = "ciu", "biu"; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = <1>; + vmmc-supply = <&ldo12>; + fifo-depth = <0x100>; + supports-highspeed; + pinctrl-names = "default"; + pinctrl-0 = <&sd_pmx_pins &sd_cfg_func1 &sd_cfg_func2>; + slot@0 { + reg = <0>; + bus-width = <4>; + disable-wp; + cd-gpios = <&gpio10 3 0>; + }; + }; diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt index c6d7b11db9eb..f357c16ea815 100644 --- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt @@ -8,6 +8,12 @@ by mmc.txt and the properties used by the sdhci-tegra driver. Required properties: - compatible : Should be "nvidia,-sdhci" +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - sdhci Optional properties: - power-gpios : Specify GPIOs for power control @@ -18,6 +24,9 @@ sdhci@c8000200 { compatible = "nvidia,tegra20-sdhci"; reg = <0xc8000200 0x200>; interrupts = <47>; + clocks = <&tegra_car 14>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; cd-gpios = <&gpio 69 0>; /* gpio PI5 */ wp-gpios = <&gpio 57 0>; /* gpio PH1 */ power-gpios = <&gpio 155 0>; /* gpio PT3 */ diff --git a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt new file mode 100644 index 000000000000..ea4d752389a2 --- /dev/null +++ b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt @@ -0,0 +1,27 @@ +* Allwinner GMAC ethernet controller + +This device is a platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +Required properties: + - compatible: Should be "allwinner,sun7i-a20-gmac" + - clocks: Should contain the GMAC main clock, and tx clock + The tx clock type should be "allwinner,sun7i-a20-gmac-clk" + - clock-names: Should contain the clock names "stmmaceth", + and "allwinner_gmac_tx" + +Optional properties: +- phy-supply: phandle to a regulator if the PHY needs one + +Examples: + + gmac: ethernet@01c50000 { + compatible = "allwinner,sun7i-a20-gmac"; + reg = <0x01c50000 0x10000>, + <0x01c20164 0x4>; + interrupts = <0 85 1>; + interrupt-names = "macirq"; + clocks = <&ahb_gates 49>, <&gmac_tx>; + clock-names = "stmmaceth", "allwinner_gmac_tx"; + phy-mode = "mii"; + }; diff --git a/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt new file mode 100644 index 000000000000..ee3723beb701 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt @@ -0,0 +1,25 @@ +* Microchip MCP251X stand-alone CAN controller device tree bindings + +Required properties: + - compatible: Should be one of the following: + - "microchip,mcp2510" for MCP2510. + - "microchip,mcp2515" for MCP2515. + - reg: SPI chip select. + - clocks: The clock feeding the CAN controller. + - interrupt-parent: The parent interrupt controller. + - interrupts: Should contain IRQ line for the CAN controller. + +Optional properties: + - vdd-supply: Regulator that powers the CAN controller. + - xceiver-supply: Regulator that powers the CAN transceiver. + +Example: + can0: can@1 { + compatible = "microchip,mcp2515"; + reg = <1>; + clocks = <&clk24m>; + interrupt-parent = <&gpio4>; + interrupts = <13 0x2>; + vdd-supply = <®5v0>; + xceiver-supply = <®5v0>; + }; diff --git a/Documentation/devicetree/bindings/net/davinci_emac.txt b/Documentation/devicetree/bindings/net/davinci_emac.txt index bad381faf036..ca0911a20e8b 100644 --- a/Documentation/devicetree/bindings/net/davinci_emac.txt +++ b/Documentation/devicetree/bindings/net/davinci_emac.txt @@ -12,8 +12,6 @@ Required properties: - ti,davinci-ctrl-ram-size: size of control module ram - ti,davinci-rmii-en: use RMII - ti,davinci-no-bd-ram: has the emac controller BD RAM -- phy-handle: Contains a phandle to an Ethernet PHY. - if not, davinci_emac driver defaults to 100/FULL - interrupts: interrupt mapping for the davinci emac interrupts sources: 4 sources: Optional properties: +- phy-handle: Contains a phandle to an Ethernet PHY. + If absent, davinci_emac driver defaults to 100/FULL. - local-mac-address : 6 bytes, mac address Example (enbw_cmc board): diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index 4ff65047bb9a..70af2ec12b09 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -10,6 +10,10 @@ Required properties: - interrupts: Should contain macb interrupt - phy-mode: String, operation mode of the PHY interface. Supported values are: "mii", "rmii", "gmii", "rgmii". +- clock-names: Tuple listing input clock names. + Required elements: 'pclk', 'hclk' + Optional elements: 'tx_clk' +- clocks: Phandles to input clocks. Optional properties: - local-mac-address: 6 bytes, mac address @@ -22,4 +26,6 @@ Examples: interrupts = <21>; phy-mode = "rmii"; local-mac-address = [3a 0e 03 04 05 06]; + clock-names = "pclk", "hclk", "tx_clk"; + clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>; }; diff --git a/Documentation/devicetree/bindings/net/marvell-orion-net.txt b/Documentation/devicetree/bindings/net/marvell-orion-net.txt index a73b79f227e1..c233b6114242 100644 --- a/Documentation/devicetree/bindings/net/marvell-orion-net.txt +++ b/Documentation/devicetree/bindings/net/marvell-orion-net.txt @@ -32,7 +32,6 @@ Optional controller properties: * Ethernet port node Required port properties: - - device_type: shall be "network". - compatible: shall be one of "marvell,orion-eth-port", "marvell,kirkwood-eth-port". - reg: port number relative to ethernet controller, shall be 0, 1, or 2. @@ -61,7 +60,6 @@ or mdio-bus { ... ethphy: ethernet-phy@8 { - device_type = "ethernet-phy"; ... }; }; @@ -75,7 +73,6 @@ eth: ethernet-controller@72000 { marvell,tx-checksum-limit = <1600>; ethernet@0 { - device_type = "network"; compatible = "marvell,orion-eth-port"; reg = <0>; interrupts = <29>; diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index 7cd18fbfcf71..58307d0931c8 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -2,7 +2,6 @@ PHY nodes Required properties: - - device_type : Should be "ethernet-phy" - interrupts : where a is the interrupt number and b is a field that represents an encoding of the sense and level information for the interrupt. This should be encoded based on @@ -11,8 +10,6 @@ Required properties: - interrupt-parent : the phandle for the interrupt controller that services interrupts for this device. - reg : The ID number for the phy, usually a small integer - - linux,phandle : phandle for this node; likely referenced by an - ethernet controller node. Optional Properties: @@ -22,14 +19,13 @@ Optional Properties: specifications. If neither of these are specified, the default is to assume clause 22. The compatible list may also contain other elements. +- max-speed: Maximum PHY supported speed (10, 100, 1000...) Example: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; - linux,phandle = <2452000>; interrupt-parent = <40000>; interrupts = <35 1>; reg = <0>; - device_type = "ethernet-phy"; }; diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index eba0e5e59ebe..9d92d42140f2 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -12,7 +12,6 @@ Required properties: property - phy-mode: String, operation mode of the PHY interface. Supported values are: "mii", "rmii", "gmii", "rgmii". -- snps,phy-addr phy address to connect to. - snps,reset-gpio gpio number for phy reset. - snps,reset-active-low boolean flag to indicate if phy reset is active low. - snps,reset-delays-us is triplet of delays @@ -30,6 +29,11 @@ Required properties: Optional properties: - mac-address: 6 bytes, mac address +- resets: Should contain a phandle to the STMMAC reset signal, if any +- reset-names: Should contain the reset signal name "stmmaceth", if a + reset phandle is given +- max-frame-size: Maximum Transfer Unit (IEEE defined MTU), rather + than the maximum frame size. Examples: @@ -40,5 +44,6 @@ Examples: interrupts = <24 23>; interrupt-names = "macirq", "eth_wake_irq"; mac-address = [000000000000]; /* Filled in by U-Boot */ + max-frame-size = <3800>; phy-mode = "gmii"; }; diff --git a/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt b/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt index 5aeee53ff9f4..5ae601e7f51f 100644 --- a/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt +++ b/Documentation/devicetree/bindings/nvec/nvidia,nvec.txt @@ -7,3 +7,15 @@ Required properties: - clock-frequency : the frequency of the i2c bus - gpios : the gpio used for ec request - slave-addr: the i2c address of the slave controller +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names : Must include the following entries: + Tegra20/Tegra30: + - div-clk + - fast-clk + Tegra114: + - div-clk +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - i2c diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index d5d26d443693..d6fae13ff062 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt @@ -19,6 +19,8 @@ Required properties: to define the mapping of the PCIe interface to interrupt numbers. - num-lanes: number of lanes to use + +Optional properties: - reset-gpio: gpio pin number of power good signal Optional properties for fsl,imx6q-pcie diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt index 6b7510775c50..24cee06915c9 100644 --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt @@ -42,14 +42,19 @@ Required properties: - 0xc2000000: prefetchable memory region Please refer to the standard PCI bus binding document for a more detailed explanation. -- clocks: List of clock inputs of the controller. Must contain an entry for - each entry in the clock-names property. +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names: Must include the following entries: - "pex": The Tegra clock of that name - "afi": The Tegra clock of that name - "pcie_xclk": The Tegra clock of that name - "pll_e": The Tegra clock of that name - "cml": The Tegra clock of that name (not required for Tegra20) + - pex + - afi + - pll_e + - cml (not required for Tegra20) +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - pex + - afi + - pcie_x Root ports are defined as subnodes of the PCIe controller node. @@ -91,9 +96,10 @@ SoC DTSI: 0x82000000 0 0xa0000000 0xa0000000 0 0x10000000 /* non-prefetchable memory */ 0xc2000000 0 0xb0000000 0xb0000000 0 0x10000000>; /* prefetchable memory */ - clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>, - <&tegra_car 118>; - clock-names = "pex", "afi", "pcie_xclk", "pll_e"; + clocks = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 118>; + clock-names = "pex", "afi", "pll_e"; + resets = <&tegra_car 70>, <&tegra_car 72>, <&tegra_car 74>; + reset-names = "pex", "afi", "pcie_x"; status = "disabled"; pci@1,0 { diff --git a/Documentation/devicetree/bindings/phy/bcm-phy.txt b/Documentation/devicetree/bindings/phy/bcm-phy.txt new file mode 100644 index 000000000000..3dc8b3d2ffbb --- /dev/null +++ b/Documentation/devicetree/bindings/phy/bcm-phy.txt @@ -0,0 +1,15 @@ +BROADCOM KONA USB2 PHY + +Required properties: + - compatible: brcm,kona-usb2-phy + - reg: offset and length of the PHY registers + - #phy-cells: must be 0 +Refer to phy/phy-bindings.txt for the generic PHY binding properties + +Example: + + usbphy: usb-phy@3f130000 { + compatible = "brcm,kona-usb2-phy"; + reg = <0x3f130000 0x28>; + #phy-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt new file mode 100644 index 000000000000..9e9e9ef9f852 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/brcm,capri-pinctrl.txt @@ -0,0 +1,461 @@ +Broadcom Capri Pin Controller + +This is a pin controller for the Broadcom BCM281xx SoC family, which includes +BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs. + +=== Pin Controller Node === + +Required Properties: + +- compatible: Must be "brcm,capri-pinctrl". +- reg: Base address of the PAD Controller register block and the size + of the block. + +For example, the following is the bare minimum node: + + pinctrl@35004800 { + compatible = "brcm,capri-pinctrl"; + reg = <0x35004800 0x430>; + }; + +As a pin controller device, in addition to the required properties, this node +should also contain the pin configuration nodes that client devices reference, +if any. + +=== Pin Configuration Node === + +Each pin configuration node is a sub-node of the pin controller node and is a +container of an arbitrary number of subnodes, called pin group nodes in this +document. + +Please refer to the pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the definition of a +"pin configuration node". + +=== Pin Group Node === + +A pin group node specifies the desired pin mux and/or pin configuration for an +arbitrary number of pins. The name of the pin group node is optional and not +used. + +A pin group node only affects the properties specified in the node, and has no +effect on any properties that are omitted. + +The pin group node accepts a subset of the generic pin config properties. For +details generic pin config properties, please refer to pinctrl-bindings.txt +and . + +Each pin controlled by this pin controller belong to one of three types: +Standard, I2C, and HDMI. Each type accepts a different set of pin config +properties. A list of pins and their types is provided below. + +Required Properties (applicable to all pins): + +- pins: Multiple strings. Specifies the name(s) of one or more pins to + be configured by this node. + +Optional Properties (for standard pins): + +- function: String. Specifies the pin mux selection. Values + must be one of: "alt1", "alt2", "alt3", "alt4" +- input-schmitt-enable: No arguments. Enable schmitt-trigger mode. +- input-schmitt-disable: No arguments. Disable schmitt-trigger mode. +- bias-pull-up: No arguments. Pull up on pin. +- bias-pull-down: No arguments. Pull down on pin. +- bias-disable: No arguments. Disable pin bias. +- slew-rate: Integer. Meaning depends on configured pin mux: + *_SCL or *_SDA: + 0: Standard(100kbps)& Fast(400kbps) mode + 1: Highspeed (3.4Mbps) mode + IC_DM or IC_DP: + 0: normal slew rate + 1: fast slew rate + Otherwise: + 0: fast slew rate + 1: normal slew rate +- input-enable: No arguements. Enable input (does not affect + output.) +- input-disable: No arguements. Disable input (does not affect + output.) +- drive-strength: Integer. Drive strength in mA. Valid values are + 2, 4, 6, 8, 10, 12, 14, 16 mA. + +Optional Properties (for I2C pins): + +- function: String. Specifies the pin mux selection. Values + must be one of: "alt1", "alt2", "alt3", "alt4" +- bias-pull-up: Integer. Pull up strength in Ohm. There are 3 + pull-up resisitors (1.2k, 1.8k, 2.7k) available + in parallel for I2C pins, so the valid values + are: 568, 720, 831, 1080, 1200, 1800, 2700 Ohm. +- bias-disable: No arguments. Disable pin bias. +- slew-rate: Integer. Meaning depends on configured pin mux: + *_SCL or *_SDA: + 0: Standard(100kbps)& Fast(400kbps) mode + 1: Highspeed (3.4Mbps) mode + IC_DM or IC_DP: + 0: normal slew rate + 1: fast slew rate + Otherwise: + 0: fast slew rate + 1: normal slew rate +- input-enable: No arguements. Enable input (does not affect + output.) +- input-disable: No arguements. Disable input (does not affect + output.) + +Optional Properties (for HDMI pins): + +- function: String. Specifies the pin mux selection. Values + must be one of: "alt1", "alt2", "alt3", "alt4" +- slew-rate: Integer. Controls slew rate. + 0: Standard(100kbps)& Fast(400kbps) mode + 1: Highspeed (3.4Mbps) mode +- input-enable: No arguements. Enable input (does not affect + output.) +- input-disable: No arguements. Disable input (does not affect + output.) + +Example: +// pin controller node +pinctrl@35004800 { + compatible = "brcm,capri-pinctrl"; + reg = <0x35004800 0x430>; + + // pin configuration node + dev_a_default: dev_a_active { + //group node defining 1 standard pin + grp_1 { + pins = "std_pin1"; + function = "alt1"; + input-schmitt-enable; + bias-disable; + slew-rate = <1>; + drive-strength = <4>; + }; + + // group node defining 2 I2C pins + grp_2 { + pins = "i2c_pin1", "i2c_pin2"; + function = "alt2"; + bias-pull-up = <720>; + input-enable; + }; + + // group node defining 2 HDMI pins + grp_3 { + pins = "hdmi_pin1", "hdmi_pin2"; + function = "alt3"; + slew-rate = <1>; + }; + + // other pin group nodes + ... + }; + + // other pin configuration nodes + ... +}; + +In the example above, "dev_a_active" is a pin configuration node with a number +of sub-nodes. In the pin group node "grp_1", one pin, "std_pin1", is defined in +the "pins" property. Thus, the remaining properties in the "grp_1" node applies +only to this pin, including the following settings: + - setting pinmux to "alt1" + - enabling schmitt-trigger (hystersis) mode + - disabling pin bias + - setting the slew-rate to 1 + - setting the drive strength to 4 mA +Note that neither "input-enable" nor "input-disable" was specified - the pinctrl +subsystem will therefore leave this property unchanged from whatever state it +was in before applying these changes. + +The "pins" property in the pin group node "grp_2" specifies two pins - +"i2c_pin1" and "i2c_pin2"; the remaining properties in this pin group node, +therefore, applies to both of these pins. The properties include: + - setting pinmux to "alt2" + - setting pull-up resistance to 720 Ohm (ie. enabling 1.2k and 1.8k resistors + in parallel) + - enabling both pins' input +"slew-rate" is not specified in this pin group node, so the slew-rate for these +pins are left as-is. + +Finally, "grp_3" defines two HDMI pins. The following properties are applied to +both pins: + - setting pinmux to "alt3" + - setting slew-rate to 1; for HDMI pins, this corresponds to the 3.4 Mbps + Highspeed mode +The input is neither enabled or disabled, and is left untouched. + +=== Pin Names and Type === + +The following are valid pin names and their pin types: + + "adcsync", Standard + "bat_rm", Standard + "bsc1_scl", I2C + "bsc1_sda", I2C + "bsc2_scl", I2C + "bsc2_sda", I2C + "classgpwr", Standard + "clk_cx8", Standard + "clkout_0", Standard + "clkout_1", Standard + "clkout_2", Standard + "clkout_3", Standard + "clkreq_in_0", Standard + "clkreq_in_1", Standard + "cws_sys_req1", Standard + "cws_sys_req2", Standard + "cws_sys_req3", Standard + "digmic1_clk", Standard + "digmic1_dq", Standard + "digmic2_clk", Standard + "digmic2_dq", Standard + "gpen13", Standard + "gpen14", Standard + "gpen15", Standard + "gpio00", Standard + "gpio01", Standard + "gpio02", Standard + "gpio03", Standard + "gpio04", Standard + "gpio05", Standard + "gpio06", Standard + "gpio07", Standard + "gpio08", Standard + "gpio09", Standard + "gpio10", Standard + "gpio11", Standard + "gpio12", Standard + "gpio13", Standard + "gpio14", Standard + "gps_pablank", Standard + "gps_tmark", Standard + "hdmi_scl", HDMI + "hdmi_sda", HDMI + "ic_dm", Standard + "ic_dp", Standard + "kp_col_ip_0", Standard + "kp_col_ip_1", Standard + "kp_col_ip_2", Standard + "kp_col_ip_3", Standard + "kp_row_op_0", Standard + "kp_row_op_1", Standard + "kp_row_op_2", Standard + "kp_row_op_3", Standard + "lcd_b_0", Standard + "lcd_b_1", Standard + "lcd_b_2", Standard + "lcd_b_3", Standard + "lcd_b_4", Standard + "lcd_b_5", Standard + "lcd_b_6", Standard + "lcd_b_7", Standard + "lcd_g_0", Standard + "lcd_g_1", Standard + "lcd_g_2", Standard + "lcd_g_3", Standard + "lcd_g_4", Standard + "lcd_g_5", Standard + "lcd_g_6", Standard + "lcd_g_7", Standard + "lcd_hsync", Standard + "lcd_oe", Standard + "lcd_pclk", Standard + "lcd_r_0", Standard + "lcd_r_1", Standard + "lcd_r_2", Standard + "lcd_r_3", Standard + "lcd_r_4", Standard + "lcd_r_5", Standard + "lcd_r_6", Standard + "lcd_r_7", Standard + "lcd_vsync", Standard + "mdmgpio0", Standard + "mdmgpio1", Standard + "mdmgpio2", Standard + "mdmgpio3", Standard + "mdmgpio4", Standard + "mdmgpio5", Standard + "mdmgpio6", Standard + "mdmgpio7", Standard + "mdmgpio8", Standard + "mphi_data_0", Standard + "mphi_data_1", Standard + "mphi_data_2", Standard + "mphi_data_3", Standard + "mphi_data_4", Standard + "mphi_data_5", Standard + "mphi_data_6", Standard + "mphi_data_7", Standard + "mphi_data_8", Standard + "mphi_data_9", Standard + "mphi_data_10", Standard + "mphi_data_11", Standard + "mphi_data_12", Standard + "mphi_data_13", Standard + "mphi_data_14", Standard + "mphi_data_15", Standard + "mphi_ha0", Standard + "mphi_hat0", Standard + "mphi_hat1", Standard + "mphi_hce0_n", Standard + "mphi_hce1_n", Standard + "mphi_hrd_n", Standard + "mphi_hwr_n", Standard + "mphi_run0", Standard + "mphi_run1", Standard + "mtx_scan_clk", Standard + "mtx_scan_data", Standard + "nand_ad_0", Standard + "nand_ad_1", Standard + "nand_ad_2", Standard + "nand_ad_3", Standard + "nand_ad_4", Standard + "nand_ad_5", Standard + "nand_ad_6", Standard + "nand_ad_7", Standard + "nand_ale", Standard + "nand_cen_0", Standard + "nand_cen_1", Standard + "nand_cle", Standard + "nand_oen", Standard + "nand_rdy_0", Standard + "nand_rdy_1", Standard + "nand_wen", Standard + "nand_wp", Standard + "pc1", Standard + "pc2", Standard + "pmu_int", Standard + "pmu_scl", I2C + "pmu_sda", I2C + "rfst2g_mtsloten3g", Standard + "rgmii_0_rx_ctl", Standard + "rgmii_0_rxc", Standard + "rgmii_0_rxd_0", Standard + "rgmii_0_rxd_1", Standard + "rgmii_0_rxd_2", Standard + "rgmii_0_rxd_3", Standard + "rgmii_0_tx_ctl", Standard + "rgmii_0_txc", Standard + "rgmii_0_txd_0", Standard + "rgmii_0_txd_1", Standard + "rgmii_0_txd_2", Standard + "rgmii_0_txd_3", Standard + "rgmii_1_rx_ctl", Standard + "rgmii_1_rxc", Standard + "rgmii_1_rxd_0", Standard + "rgmii_1_rxd_1", Standard + "rgmii_1_rxd_2", Standard + "rgmii_1_rxd_3", Standard + "rgmii_1_tx_ctl", Standard + "rgmii_1_txc", Standard + "rgmii_1_txd_0", Standard + "rgmii_1_txd_1", Standard + "rgmii_1_txd_2", Standard + "rgmii_1_txd_3", Standard + "rgmii_gpio_0", Standard + "rgmii_gpio_1", Standard + "rgmii_gpio_2", Standard + "rgmii_gpio_3", Standard + "rtxdata2g_txdata3g1", Standard + "rtxen2g_txdata3g2", Standard + "rxdata3g0", Standard + "rxdata3g1", Standard + "rxdata3g2", Standard + "sdio1_clk", Standard + "sdio1_cmd", Standard + "sdio1_data_0", Standard + "sdio1_data_1", Standard + "sdio1_data_2", Standard + "sdio1_data_3", Standard + "sdio4_clk", Standard + "sdio4_cmd", Standard + "sdio4_data_0", Standard + "sdio4_data_1", Standard + "sdio4_data_2", Standard + "sdio4_data_3", Standard + "sim_clk", Standard + "sim_data", Standard + "sim_det", Standard + "sim_resetn", Standard + "sim2_clk", Standard + "sim2_data", Standard + "sim2_det", Standard + "sim2_resetn", Standard + "sri_c", Standard + "sri_d", Standard + "sri_e", Standard + "ssp_extclk", Standard + "ssp0_clk", Standard + "ssp0_fs", Standard + "ssp0_rxd", Standard + "ssp0_txd", Standard + "ssp2_clk", Standard + "ssp2_fs_0", Standard + "ssp2_fs_1", Standard + "ssp2_fs_2", Standard + "ssp2_fs_3", Standard + "ssp2_rxd_0", Standard + "ssp2_rxd_1", Standard + "ssp2_txd_0", Standard + "ssp2_txd_1", Standard + "ssp3_clk", Standard + "ssp3_fs", Standard + "ssp3_rxd", Standard + "ssp3_txd", Standard + "ssp4_clk", Standard + "ssp4_fs", Standard + "ssp4_rxd", Standard + "ssp4_txd", Standard + "ssp5_clk", Standard + "ssp5_fs", Standard + "ssp5_rxd", Standard + "ssp5_txd", Standard + "ssp6_clk", Standard + "ssp6_fs", Standard + "ssp6_rxd", Standard + "ssp6_txd", Standard + "stat_1", Standard + "stat_2", Standard + "sysclken", Standard + "traceclk", Standard + "tracedt00", Standard + "tracedt01", Standard + "tracedt02", Standard + "tracedt03", Standard + "tracedt04", Standard + "tracedt05", Standard + "tracedt06", Standard + "tracedt07", Standard + "tracedt08", Standard + "tracedt09", Standard + "tracedt10", Standard + "tracedt11", Standard + "tracedt12", Standard + "tracedt13", Standard + "tracedt14", Standard + "tracedt15", Standard + "txdata3g0", Standard + "txpwrind", Standard + "uartb1_ucts", Standard + "uartb1_urts", Standard + "uartb1_urxd", Standard + "uartb1_utxd", Standard + "uartb2_urxd", Standard + "uartb2_utxd", Standard + "uartb3_ucts", Standard + "uartb3_urts", Standard + "uartb3_urxd", Standard + "uartb3_utxd", Standard + "uartb4_ucts", Standard + "uartb4_urts", Standard + "uartb4_urxd", Standard + "uartb4_utxd", Standard + "vc_cam1_scl", I2C + "vc_cam1_sda", I2C + "vc_cam2_scl", I2C + "vc_cam2_sda", I2C + "vc_cam3_scl", I2C + "vc_cam3_sda", I2C diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx25-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx25-pinctrl.txt new file mode 100644 index 000000000000..fd653bde18d5 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx25-pinctrl.txt @@ -0,0 +1,23 @@ +* Freescale IMX25 IOMUX Controller + +Please refer to fsl,imx-pinctrl.txt in this directory for common binding part +and usage. + +CONFIG bits definition: +PAD_CTL_HYS (1 << 8) +PAD_CTL_PKE (1 << 7) +PAD_CTL_PUE (1 << 6) +PAD_CTL_PUS_100K_DOWN (0 << 4) +PAD_CTL_PUS_47K_UP (1 << 4) +PAD_CTL_PUS_100K_UP (2 << 4) +PAD_CTL_PUS_22K_UP (3 << 4) +PAD_CTL_ODE_CMOS (0 << 3) +PAD_CTL_ODE_OPENDRAIN (1 << 3) +PAD_CTL_DSE_NOMINAL (0 << 1) +PAD_CTL_DSE_HIGH (1 << 1) +PAD_CTL_DSE_MAX (2 << 1) +PAD_CTL_SRE_FAST (1 << 0) +PAD_CTL_SRE_SLOW (0 << 0) + +Refer to imx25-pinfunc.h in device tree source folder for all available +imx25 PIN_FUNC_ID. diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt index 353eca0efbf8..d1706ea82572 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt @@ -52,12 +52,25 @@ Required properties for pin configuration node: CONFIG can be 0 or 1, meaning Pullup disable/enable. +The iomux controller has gpio child nodes which are embedded in the iomux +control registers. They have to be defined as child nodes of the iomux device +node. If gpio subnodes are defined "#address-cells", "#size-cells" and "ranges" +properties for the iomux device node are required. Example: iomuxc: iomuxc@10015000 { compatible = "fsl,imx27-iomuxc"; reg = <0x10015000 0x600>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio1: gpio@10015000 { + ... + }; + + ... uart { pinctrl_uart1: uart-1 { @@ -83,6 +96,15 @@ The above example using macros: iomuxc: iomuxc@10015000 { compatible = "fsl,imx27-iomuxc"; reg = <0x10015000 0x600>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio1: gpio@10015000 { + ... + }; + + ... uart { pinctrl_uart1: uart-1 { diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-pinmux.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-pinmux.txt new file mode 100644 index 000000000000..6464bf769460 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-pinmux.txt @@ -0,0 +1,144 @@ +NVIDIA Tegra124 pinmux controller + +The Tegra124 pinctrl binding is very similar to the Tegra20 and Tegra30 +pinctrl binding, as described in nvidia,tegra20-pinmux.txt and +nvidia,tegra30-pinmux.txt. In fact, this document assumes that binding as +a baseline, and only documents the differences between the two bindings. + +Required properties: +- compatible: "nvidia,tegra124-pinmux" +- reg: Should contain a list of base address and size pairs for: + -- first entry - the drive strength and pad control registers. + -- second entry - the pinmux registers + +Tegra124 adds the following optional properties for pin configuration subnodes. +The macros for options are defined in the + include/dt-binding/pinctrl/pinctrl-tegra.h. +- nvidia,enable-input: Integer. Enable the pin's input path. + enable :TEGRA_PIN_ENABLE0 and + disable or output only: TEGRA_PIN_DISABLE. +- nvidia,open-drain: Integer. + enable: TEGRA_PIN_ENABLE. + disable: TEGRA_PIN_DISABLE. +- nvidia,lock: Integer. Lock the pin configuration against further changes + until reset. + enable: TEGRA_PIN_ENABLE. + disable: TEGRA_PIN_DISABLE. +- nvidia,io-reset: Integer. Reset the IO path. + enable: TEGRA_PIN_ENABLE. + disable: TEGRA_PIN_DISABLE. +- nvidia,rcv-sel: Integer. Select VIL/VIH receivers. + normal: TEGRA_PIN_DISABLE + high: TEGRA_PIN_ENABLE + +Please refer the Tegra TRM for complete details regarding which groups +support which functionality. + +Valid values for pin and group names are: + + per-pin mux groups: + + These all support nvidia,function, nvidia,tristate, nvidia,pull, + nvidia,enable-input. Some support nvidia,lock nvidia,open-drain, + nvidia,io-reset and nvidia,rcv-sel. + + ulpi_data0_po1, ulpi_data1_po2, ulpi_data2_po3, ulpi_data3_po4, + ulpi_data4_po5, ulpi_data5_po6, ulpi_data6_po7, ulpi_data7_po0, + ulpi_clk_py0, ulpi_dir_py1, ulpi_nxt_py2, ulpi_stp_py3, dap3_fs_pp0, + dap3_din_pp1, dap3_dout_pp2, dap3_sclk_pp3, pv0, pv1, sdmmc1_clk_pz0, + sdmmc1_cmd_pz1, sdmmc1_dat3_py4, sdmmc1_dat2_py5, sdmmc1_dat1_py6, + sdmmc1_dat0_py7, clk2_out_pw5, clk2_req_pcc5, hdmi_int_pn7, ddc_scl_pv4, + ddc_sda_pv5, uart2_rxd_pc3, uart2_txd_pc2, uart2_rts_n_pj6, + uart2_cts_n_pj5, uart3_txd_pw6, uart3_rxd_pw7, uart3_cts_n_pa1, + uart3_rts_n_pc0, pu0, pu1, pu2, pu3, pu4, pu5, pu6, gen1_i2c_scl_pc4, + gen1_i2c_sda_pc5, dap4_fs_pp4, dap4_din_pp5, dap4_dout_pp6, + dap4_sclk_pp7, clk3_out_pee0, clk3_req_pee1, pc7, pi5, pi7, pk0, pk1, + pj0, pj2, pk3, pk4, pk2, pi3, pi6, pg0, pg1, pg2, pg3, pg4, pg5, pg6, + pg7, ph0, ph1, ph2, ph3, ph4, ph5, ph6, ph7, pj7, pb0, pb1, pk7, pi0, + pi1, pi2, pi4, gen2_i2c_scl_pt5, gen2_i2c_sda_pt6, sdmmc4_clk_pcc4, + sdmmc4_cmd_pt7, sdmmc4_dat0_paa0, sdmmc4_dat1_paa1, sdmmc4_dat2_paa2, + sdmmc4_dat3_paa3, sdmmc4_dat4_paa4, sdmmc4_dat5_paa5, sdmmc4_dat6_paa6, + sdmmc4_dat7_paa7, cam_mclk_pcc0, pcc1, pbb0, cam_i2c_scl_pbb1, + cam_i2c_sda_pbb2, pbb3, pbb4, pbb5, pbb6, pbb7, pcc2, jtag_rtck, + pwr_i2c_scl_pz6, pwr_i2c_sda_pz7, kb_row0_pr0, kb_row1_pr1, kb_row2_pr2, + kb_row3_pr3, kb_row4_pr4, kb_row5_pr5, kb_row6_pr6, kb_row7_pr7, + kb_row8_ps0, kb_row9_ps1, kb_row10_ps2, kb_row11_ps3, kb_row12_ps4, + kb_row13_ps5, kb_row14_ps6, kb_row15_ps7, kb_col0_pq0, kb_col1_pq1, + kb_col2_pq2, kb_col3_pq3, kb_col4_pq4, kb_col5_pq5, kb_col6_pq6, + kb_col7_pq7, clk_32k_out_pa0, core_pwr_req, cpu_pwr_req, pwr_int_n, + clk_32k_in, owr, dap1_fs_pn0, dap1_din_pn1, dap1_dout_pn2, + dap1_sclk_pn3, dap_mclk1_req_pee2, dap_mclk1_pw4, spdif_in_pk6, + spdif_out_pk5, dap2_fs_pa2, dap2_din_pa4, dap2_dout_pa5, dap2_sclk_pa3, + dvfs_pwm_px0, gpio_x1_aud_px1, gpio_x3_aud_px3, dvfs_clk_px2, + gpio_x4_aud_px4, gpio_x5_aud_px5, gpio_x6_aud_px6, gpio_x7_aud_px7, + sdmmc3_clk_pa6, sdmmc3_cmd_pa7, sdmmc3_dat0_pb7, sdmmc3_dat1_pb6, + sdmmc3_dat2_pb5, sdmmc3_dat3_pb4, pex_l0_rst_n_pdd1, + pex_l0_clkreq_n_pdd2, pex_wake_n_pdd3, pex_l1_rst_n_pdd5, + pex_l1_clkreq_n_pdd6, hdmi_cec_pee3, sdmmc1_wp_n_pv3, + sdmmc3_cd_n_pv2, gpio_w2_aud_pw2, gpio_w3_aud_pw3, usb_vbus_en0_pn4, + usb_vbus_en1_pn5, sdmmc3_clk_lb_out_pee4, sdmmc3_clk_lb_in_pee5, + gmi_clk_lb, reset_out_n, kb_row16_pt0, kb_row17_pt1, usb_vbus_en2_pff1, + pff2, dp_hpd_pff0, + + drive groups: + + These all support nvidia,pull-down-strength, nvidia,pull-up-strength, + nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all + support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode + and nvidia,drive-type. + + ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, dap1, dap2, dap3, dap4, + dbg, sdio3, spi, uaa, uab, uart2, uart3, sdio1, ddc, gma, gme, gmf, gmg, + gmh, owr, uda, gpv, dev3, cec, usb_vbus_en, ao3, ao0, hv0, sdio4, ao4. + +Valid values for nvidia,functions are: + + blink, cec, cldvfs, clk12, cpu, dap, dap1, dap2, dev3, displaya, + displaya_alt, displayb, dtv, extperiph1, extperiph2, extperiph3, + gmi, gmi_alt, hda, hsi, i2c1, i2c2, i2c3, i2c4, i2cpwr, i2s0, + i2s1, i2s2, i2s3, i2s4, irda, kbc, owr, pmi, pwm0, pwm1, pwm2, pwm3, + pwron, reset_out_n, rsvd1, rsvd2, rsvd3, rsvd4, sdmmc1, sdmmc2, sdmmc3, + sdmmc4, soc, spdif, spi1, spi2, spi3, spi4, spi5, spi6, trace, uarta, + uartb, uartc, uartd, ulpi, usb, vgp1, vgp2, vgp3, vgp4, vgp5, vgp6, + vi, vi_alt1, vi_alt3, vimclk2, vimclk2_alt, sata, ccla, pe0, pe, pe1, + dp, rtck, sys, clk tmds. + +Example: + + pinmux: pinmux { + compatible = "nvidia,tegra124-pinmux"; + reg = <0x70000868 0x164 /* Pad control registers */ + 0x70003000 0x434>; /* PinMux registers */ + }; + +Example pinmux entries: + + pinctrl { + sdmmc4_default: pinmux { + sdmmc4_clk_pcc4 { + nvidia,pins = "sdmmc4_clk_pcc4", + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + sdmmc4_dat0_paa0 { + nvidia,pins = "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,pull = ; + nvidia,tristate = ; + }; + }; + }; + + sdhci@78000400 { + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc4_default>; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index 1958ca9f9e5c..4414163e76d2 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -151,6 +151,8 @@ drive-push-pull - drive actively high and low drive-open-drain - drive with open drain drive-open-source - drive with open source drive-strength - sink or source at most X mA +input-enable - enable input on pin (no effect on output) +input-disable - disable input on pin (no effect on output) input-schmitt-enable - enable schmitt-trigger mode input-schmitt-disable - disable schmitt-trigger mode input-debounce - debounce mode with debound time X @@ -158,6 +160,7 @@ low-power-enable - enable low power mode low-power-disable - disable low power mode output-low - set the pin to output mode with low level output-high - set the pin to output mode with high level +slew-rate - set the slew rate Some of the generic properties take arguments. For those that do, the arguments are described below. diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt index 7069a0b84e3a..bc0dfdfdb148 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt @@ -98,7 +98,7 @@ below for more information. In case when one register changes more than one pin's mux the pinctrl-single,bits need to be used which takes three parameters: - pinctrl-single,bits = <0xdc 0x18, 0xff>; + pinctrl-single,bits = <0xdc 0x18 0xff>; Where 0xdc is the offset from the pinctrl register base address for the device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt new file mode 100644 index 000000000000..4c352be5dd61 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8974-pinctrl.txt @@ -0,0 +1,92 @@ +Qualcomm MSM8974 TLMM block + +Required properties: +- compatible: "qcom,msm8x74-pinctrl" +- reg: Should be the base address and length of the TLMM block. +- interrupts: Should be the parent IRQ of the TLMM block. +- interrupt-controller: Marks the device node as an interrupt controller. +- #interrupt-cells: Should be two. +- gpio-controller: Marks the device node as a GPIO controller. +- #gpio-cells : Should be two. + The first cell is the gpio pin number and the + second cell is used for optional parameters. + +Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for +a general description of GPIO and interrupt bindings. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +Qualcomm's pin configuration nodes act as a container for an abitrary number of +subnodes. Each of these subnodes represents some desired configuration for a +pin, a group, or a list of pins or groups. This configuration can include the +mux function to select on those pin(s)/group(s), and various pin configuration +parameters, such as pull-up, drive strength, etc. + +The name of each subnode is not important; all subnodes should be enumerated +and processed purely based on their content. + +Each subnode only affects those parameters that are explicitly listed. In +other words, a subnode that lists a mux function but no pin configuration +parameters implies no information about any pin configuration parameters. +Similarly, a pin subnode that describes a pullup parameter implies no +information about e.g. the mux function. + + +The following generic properties as defined in pinctrl-bindings.txt are valid +to specify in a pin configuration subnode: + pins, function, bias-disable, bias-pull-down, bias-pull,up, drive-strength. + +Non-empty subnodes must specify the 'pins' property. +Note that not all properties are valid for all pins. + + +Valid values for qcom,pins are: + gpio0-gpio145 + Supports mux, bias and drive-strength + + sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, sdc2_data + Supports bias and drive-strength + +Valid values for qcom,function are: + blsp_i2c2, blsp_i2c6, blsp_i2c11, blsp_spi1, blsp_uart2, blsp_uart8, slimbus + + (Note that this is not yet the complete list of functions) + + + +Example: + + msmgpio: pinctrl@fd510000 { + compatible = "qcom,msm8974-pinctrl"; + reg = <0xfd510000 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 208 0>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart2_default>; + + uart2_default: uart2_default { + mux { + qcom,pins = "gpio4", "gpio5"; + qcom,function = "blsp_uart2"; + }; + + tx { + qcom,pins = "gpio4"; + drive-strength = <4>; + bias-disable; + }; + + rx { + qcom,pins = "gpio5"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index d5dac7b843a9..35d2e1f186f0 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -26,6 +26,11 @@ Optional properties: - #gpio-range-cells: Mandatory when the PFC doesn't handle GPIO, forbidden otherwise. Should be 3. + - interrupts-extended: Specify the interrupts associated with external + IRQ pins. This property is mandatory when the PFC handles GPIOs and + forbidden otherwise. When specified, it must contain one interrupt per + external IRQ, sorted by external IRQ number. + The PFC node also acts as a container for pin configuration nodes. Please refer to pinctrl-bindings.txt in this directory for the definition of the term "pin configuration node" and for the common pinctrl bindings used by client devices. @@ -103,6 +108,15 @@ Example 1: SH73A0 (SH-Mobile AG5) pin controller node <0xe605801c 0x1c>; gpio-controller; #gpio-cells = <2>; + interrupts-extended = + <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>, + <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>, + <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>, + <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>, + <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>, + <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>, + <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>, + <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>; }; Example 2: A GPIO LED node that references a GPIO diff --git a/Documentation/devicetree/bindings/power/isp1704.txt b/Documentation/devicetree/bindings/power/isp1704.txt new file mode 100644 index 000000000000..fa3596907967 --- /dev/null +++ b/Documentation/devicetree/bindings/power/isp1704.txt @@ -0,0 +1,17 @@ +Binding for NXP ISP1704 USB Charger Detection + +Required properties: +- compatible: Should contain one of the following: + * "nxp,isp1704" +- nxp,enable-gpio: Should contain a phandle + gpio-specifier + to the GPIO pin connected to the chip's enable pin. +- usb-phy: Should contain a phandle to the USB PHY + the ISP1704 is connected to. + +Example: + +isp1704 { + compatible = "nxp,isp1704"; + nxp,enable-gpio = <&gpio3 3 GPIO_ACTIVE_LOW>; + usb-phy = <&usb2_phy>; +}; diff --git a/Documentation/devicetree/bindings/power_supply/charger-manager.txt b/Documentation/devicetree/bindings/power_supply/charger-manager.txt new file mode 100644 index 000000000000..2b33750e3db2 --- /dev/null +++ b/Documentation/devicetree/bindings/power_supply/charger-manager.txt @@ -0,0 +1,81 @@ +charger-manager bindings +~~~~~~~~~~~~~~~~~~~~~~~~ + +Required properties : + - compatible : "charger-manager" + - <>-supply : for regulator consumer + - cm-num-chargers : number of chargers + - cm-chargers : name of chargers + - cm-fuel-gauge : name of battery fuel gauge + - subnode : + - cm-regulator-name : name of charger regulator + - subnode : + - cm-cable-name : name of charger cable + - cm-cable-extcon : name of extcon dev +(optional) - cm-cable-min : minimum current of cable +(optional) - cm-cable-max : maximum current of cable + +Optional properties : + - cm-name : charger manager's name (default : "battery") + - cm-poll-mode : polling mode (enum polling_modes) + - cm-poll-interval : polling interval + - cm-battery-stat : battery status (enum data_source) + - cm-fullbatt-* : data for full battery checking + - cm-thermal-zone : name of external thermometer's thermal zone + - cm-battery-* : threshold battery temperature for charging + -cold : critical cold temperature of battery for charging + -cold-in-minus : flag that cold temerature is in minus degree + -hot : critical hot temperature of battery for charging + -temp-diff : temperature difference to allow recharging + - cm-dis/charging-max = limits of charging duration + +Example : + charger-manager@0 { + compatible = "charger-manager"; + chg-reg-supply = <&charger_regulator>; + + cm-name = "battery"; + /* Always polling ON : 30s */ + cm-poll-mode = <1>; + cm-poll-interval = <30000>; + + cm-fullbatt-vchkdrop-ms = <30000>; + cm-fullbatt-vchkdrop-volt = <150000>; + cm-fullbatt-soc = <100>; + + cm-battery-stat = <3>; + + cm-num-chargers = <3>; + cm-chargers = "charger0", "charger1", "charger2"; + + cm-fuel-gauge = "fuelgauge0"; + + cm-thermal-zone = "thermal_zone.1" + /* in deci centigrade */ + cm-battery-cold = <50>; + cm-battery-cold-in-minus; + cm-battery-hot = <800>; + cm-battery-temp-diff = <100>; + + /* Allow charging for 5hr */ + cm-charging-max = <18000000>; + /* Allow discharging for 2hr */ + cm-discharging-max = <7200000>; + + regulator@0 { + cm-regulator-name = "chg-reg"; + cable@0 { + cm-cable-name = "USB"; + cm-cable-extcon = "extcon-dev.0"; + cm-cable-min = <475000>; + cm-cable-max = <500000>; + }; + cable@1 { + cm-cable-name = "TA"; + cm-cable-extcon = "extcon-dev.0"; + cm-cable-min = <650000>; + cm-cable-max = <675000>; + }; + }; + + }; diff --git a/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt index 0e4269446580..29b28b8f9a89 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/network.txt @@ -10,7 +10,6 @@ Currently defined compatibles: Example: ethernet@11300 { - device_type = "network"; compatible = "fsl,mpc8272-fcc-enet", "fsl,cpm2-fcc-enet"; reg = <11300 20 8400 100 11390 1>; @@ -33,7 +32,6 @@ fsl,mdc-pin : pin of port C controlling mdio clock Example: mdio@10d40 { - device_type = "mdio"; compatible = "fsl,mpc8272ads-mdio-bitbang", "fsl,mpc8272-mdio-bitbang", "fsl,cpm2-mdio-bitbang"; diff --git a/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt index c5b43061db3a..ec6ee2e864a2 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/cpm_qe/qe/pincfg.txt @@ -1,8 +1,6 @@ * Pin configuration nodes Required properties: -- linux,phandle : phandle of this node; likely referenced by a QE - device. - pio-map : array of pin configurations. Each pin is defined by 6 integers. The six numbers are respectively: port, pin, dir, open_drain, assignment, has_irq. @@ -29,7 +27,6 @@ Required properties: Example: ucc_pin@01 { - linux,phandle = <140001>; pio-map = < /* port pin dir open_drain assignment has_irq */ 0 3 1 0 1 0 /* TxD0 */ diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt index c3fc57af8772..c7ea9d4a988b 100644 --- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt @@ -7,6 +7,12 @@ Required properties: - reg: physical base address and length of the controller's registers - #pwm-cells: should be 2. See pwm.txt in this directory for a description of the cells format. +- clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the following entries: + - pwm Example: @@ -14,4 +20,7 @@ Example: compatible = "nvidia,tegra20-pwm"; reg = <0x7000a000 0x100>; #pwm-cells = <2>; + clocks = <&tegra_car 17>; + resets = <&tegra_car 17>; + reset-names = "pwm"; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt new file mode 100644 index 000000000000..7bd9d3b12ce1 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-lp3943.txt @@ -0,0 +1,58 @@ +TI/National Semiconductor LP3943 PWM controller + +Required properties: + - compatible: "ti,lp3943-pwm" + - #pwm-cells: Should be 2. See pwm.txt in this directory for a + description of the cells format. + Note that this hardware limits the period length to the + range 6250~1600000. + - ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1. + 0 = output 0 + 1 = output 1 + . + . + 15 = output 15 + +Example: +PWM 0 is for RGB LED brightness control +PWM 1 is for brightness control of LP8557 backlight device + +&i2c3 { + lp3943@60 { + compatible = "ti,lp3943"; + reg = <0x60>; + + /* + * PWM 0 : output 8, 9 and 10 + * PWM 1 : output 15 + */ + pwm3943: pwm { + compatible = "ti,lp3943-pwm"; + #pwm-cells = <2>; + ti,pwm0 = <8 9 10>; + ti,pwm1 = <15>; + }; + }; + +}; + +/* LEDs control with PWM 0 of LP3943 */ +pwmleds { + compatible = "pwm-leds"; + rgb { + label = "indi::rgb"; + pwms = <&pwm3943 0 10000>; + max-brightness = <255>; + }; +}; + +&i2c4 { + /* Backlight control with PWM 1 of LP3943 */ + backlight@2c { + compatible = "ti,lp8557"; + reg = <0x2c>; + + pwms = <&pwm3943 1 10000>; + pwm-names = "lp8557"; + }; +}; diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt new file mode 100644 index 000000000000..bef1fbb647ca --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt @@ -0,0 +1,60 @@ +ACT8865 regulator +------------------- + +Required properties: +- compatible: "active-semi,act8865" +- reg: I2C slave address + +Any standard regulator properties can be used to configure the single regulator. + +The valid names for regulators are: + DCDC_REG1, DCDC_REG2, DCDC_REG3, LDO_REG1, LDO_REG2, LDO_REG3, LDO_REG4. + +Example: +-------- + + i2c1: i2c@f0018000 { + pmic: act8865@5b { + compatible = "active-semi,act8865"; + reg = <0x5b>; + status = "disabled"; + + regulators { + vcc_1v8_reg: DCDC_REG1 { + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vcc_1v2_reg: DCDC_REG2 { + regulator-name = "VCC_1V2"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-suspend-mem-microvolt = <1150000>; + regulator-suspend-standby-microvolt = <1150000>; + regulator-always-on; + }; + + vcc_3v3_reg: DCDC_REG3 { + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vddana_reg: LDO_REG1 { + regulator-name = "VDDANA"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vddfuse_reg: LDO_REG2 { + regulator-name = "FUSE_2V5"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt b/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt index d1660a90fc06..fc6b38f035bd 100644 --- a/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt @@ -83,7 +83,7 @@ as per the datasheet of s5m8767. - LDOn - valid values for n are 1 to 28 - - Example: LDO0, LD01, LDO28 + - Example: LDO1, LD02, LDO28 - BUCKn - valid values for n are 1 to 9. - Example: BUCK1, BUCK2, BUCK9 diff --git a/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt b/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt new file mode 100644 index 000000000000..31406fd4a43e --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/haoyu,hym8563.txt @@ -0,0 +1,27 @@ +Haoyu Microelectronics HYM8563 Real Time Clock + +The HYM8563 provides basic rtc and alarm functionality +as well as a clock output of up to 32kHz. + +Required properties: +- compatible: should be: "haoyu,hym8563" +- reg: i2c address +- interrupts: rtc alarm/event interrupt +- #clock-cells: the value should be 0 + +Example: + +hym8563: hym8563@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + + interrupts = <13 IRQ_TYPE_EDGE_FALLING>; + + #clock-cells = <0>; +}; + +device { +... + clocks = <&hym8563>; +... +}; diff --git a/Documentation/devicetree/bindings/rtc/maxim,ds1742.txt b/Documentation/devicetree/bindings/rtc/maxim,ds1742.txt new file mode 100644 index 000000000000..d0f937c355b5 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/maxim,ds1742.txt @@ -0,0 +1,12 @@ +* Maxim (Dallas) DS1742/DS1743 Real Time Clock + +Required properties: +- compatible: Should contain "maxim,ds1742". +- reg: Physical base address of the RTC and length of memory + mapped region. + +Example: + rtc: rtc@10000000 { + compatible = "maxim,ds1742"; + reg = <0x10000000 0x800>; + }; diff --git a/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt b/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt index 93f45e9dce7c..652d1ff2e8be 100644 --- a/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt @@ -9,6 +9,8 @@ Required properties: - compatible : should be "nvidia,tegra20-rtc". - reg : Specifies base physical address and size of the registers. - interrupts : A single interrupt specifier. +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. Example: @@ -16,4 +18,5 @@ timer { compatible = "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = <0 2 0x04>; + clocks = <&tegra_car 4>; }; diff --git a/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt b/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt new file mode 100644 index 000000000000..7cb9dbf34878 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt @@ -0,0 +1,17 @@ +* sun4i/sun7i Real Time Clock + +RTC controller for the Allwinner A10/A20 + +Required properties: +- compatible : Should be "allwinner,sun4i-rtc" or "allwinner,sun7i-a20-rtc" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: IRQ line for the RTC. + +Example: + +rtc: rtc@01c20d00 { + compatible = "allwinner,sun4i-rtc"; + reg = <0x01c20d00 0x20>; + interrupts = <24>; +}; diff --git a/Documentation/devicetree/bindings/serial/atmel-usart.txt b/Documentation/devicetree/bindings/serial/atmel-usart.txt index 2191dcb9f1da..9c5d19ac935c 100644 --- a/Documentation/devicetree/bindings/serial/atmel-usart.txt +++ b/Documentation/devicetree/bindings/serial/atmel-usart.txt @@ -6,6 +6,9 @@ Required properties: additional mode or an USART new feature. - reg: Should contain registers location and length - interrupts: Should contain interrupt +- clock-names: tuple listing input clock names. + Required elements: "usart" +- clocks: phandles to input clocks. Optional properties: - atmel,use-dma-rx: use of PDC or DMA for receiving data @@ -26,6 +29,8 @@ Example: compatible = "atmel,at91sam9260-usart"; reg = <0xfff8c000 0x4000>; interrupts = <7>; + clocks = <&usart0_clk>; + clock-names = "usart"; atmel,use-dma-rx; atmel,use-dma-tx; }; @@ -35,6 +40,8 @@ Example: compatible = "atmel,at91sam9260-usart"; reg = <0xf001c000 0x100>; interrupts = <12 4 5>; + clocks = <&usart0_clk>; + clock-names = "usart"; atmel,use-dma-rx; atmel,use-dma-tx; dmas = <&dma0 2 0x3>, diff --git a/Documentation/devicetree/bindings/serial/cirrus,clps711x-uart.txt b/Documentation/devicetree/bindings/serial/cirrus,clps711x-uart.txt new file mode 100644 index 000000000000..12f3cf834deb --- /dev/null +++ b/Documentation/devicetree/bindings/serial/cirrus,clps711x-uart.txt @@ -0,0 +1,28 @@ +* Cirrus Logic CLPS711X Universal Asynchronous Receiver/Transmitter (UART) + +Required properties: +- compatible: Should be "cirrus,clps711x-uart". +- reg: Address and length of the register set for the device. +- interrupts: Should contain UART TX and RX interrupt. +- clocks: Should contain UART core clock number. +- syscon: Phandle to SYSCON node, which contain UART control bits. + +Optional properties: +- uart-use-ms: Indicate the UART has modem signal (DCD, DSR, CTS). + +Note: Each UART port should have an alias correctly numbered +in "aliases" node. + +Example: + aliases { + serial0 = &uart1; + }; + + uart1: uart@80000480 { + compatible = "cirrus,clps711x-uart"; + reg = <0x80000480 0x80>; + interrupts = <12 13>; + clocks = <&clks 11>; + syscon = <&syscon1>; + uart-use-ms; + }; diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt index 392a4493eebd..845850caf088 100644 --- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt @@ -4,8 +4,17 @@ Required properties: - compatible : should be "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart". - reg: Should contain UART controller registers location and length. - interrupts: Should contain UART controller interrupts. -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for this UART controller. +- clocks: Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - serial +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx + - tx Optional properties: - nvidia,enable-modem-interrupt: Enable modem interrupts. Should be enable @@ -18,7 +27,11 @@ serial@70006000 { reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = <0 36 0x04>; - nvidia,dma-request-selector = <&apbdma 8>; nvidia,enable-modem-interrupt; + clocks = <&tegra_car 6>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt new file mode 100644 index 000000000000..f372cf29068d --- /dev/null +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -0,0 +1,46 @@ +* Renesas SH-Mobile Serial Communication Interface + +Required properties: + + - compatible: Must contain one of the following: + + - "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART. + - "renesas,scifa-r8a7790" for R8A7790 (R-Car H2) SCIFA compatible UART. + - "renesas,scifb-r8a7790" for R8A7790 (R-Car H2) SCIFB compatible UART. + - "renesas,hscif-r8a7790" for R8A7790 (R-Car H2) HSCIF compatible UART. + - "renesas,scif-r8a7791" for R8A7791 (R-Car M2) SCIF compatible UART. + - "renesas,scifa-r8a7791" for R8A7791 (R-Car M2) SCIFA compatible UART. + - "renesas,scifb-r8a7791" for R8A7791 (R-Car M2) SCIFB compatible UART. + - "renesas,hscif-r8a7791" for R8A7791 (R-Car M2) HSCIF compatible UART. + - "renesas,scif" for generic SCIF compatible UART. + - "renesas,scifa" for generic SCIFA compatible UART. + - "renesas,scifb" for generic SCIFB compatible UART. + - "renesas,hscif" for generic HSCIF compatible UART. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first followed by the + generic version. + + - reg: Base address and length of the I/O registers used by the UART. + - interrupts: Must contain an interrupt-specifier for the SCIx interrupt. + + - clocks: Must contain a phandle and clock-specifier pair for each entry + in clock-names. + - clock-names: Must contain "sci_ick" for the SCIx UART interface clock. + +Note: Each enabled SCIx UART should have an alias correctly numbered in the +"aliases" node. + +Example: + aliases { + serial0 = &scifa0; + }; + + scifa0: serial@e6c40000 { + compatible = "renesas,scifa-r8a7790", "renesas,scifa-generic"; + reg = <0 0xe6c40000 0 64>; + interrupt-parent = <&gic>; + interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; + clock-names = "sci_ick"; + }; diff --git a/Documentation/devicetree/bindings/serial/vt8500-uart.txt b/Documentation/devicetree/bindings/serial/vt8500-uart.txt new file mode 100644 index 000000000000..795c393d09c4 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/vt8500-uart.txt @@ -0,0 +1,26 @@ +* VIA VT8500 and WonderMedia WM8xxx UART Controller + +Required properties: +- compatible: should be "via,vt8500-uart" + +- reg: base physical address of the controller and length of memory mapped + region. + +- interrupts: hardware interrupt number + +- clocks: shall be the input parent clock phandle for the clock. This should + be the 24Mhz reference clock. + +Aliases may be defined to ensure the correct ordering of the uarts. + +Example: + aliases { + serial0 = &uart0; + }; + + uart0: serial@d8200000 { + compatible = "via,vt8500-uart"; + reg = <0xd8200000 0x1040>; + interrupts = <32>; + clocks = <&clkuart0>; + }; diff --git a/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt b/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt new file mode 100644 index 000000000000..5875ca459ed1 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,axi-i2s.txt @@ -0,0 +1,31 @@ +ADI AXI-I2S controller + +Required properties: + - compatible : Must be "adi,axi-i2s-1.00.a" + - reg : Must contain I2S core's registers location and length + - clocks : Pairs of phandle and specifier referencing the controller's clocks. + The controller expects two clocks, the clock used for the AXI interface and + the clock used as the sampling rate reference clock sample. + - clock-names : "axi" for the clock to the AXI interface, "ref" for the sample + rate reference clock. + - dmas: Pairs of phandle and specifier for the DMA channels that are used by + the core. The core expects two dma channels, one for transmit and one for + receive. + - dma-names : "tx" for the transmit channel, "rx" for the receive channel. + +For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties +please check: + * resource-names.txt + * clock/clock-bindings.txt + * dma/dma.txt + +Example: + + i2s: i2s@0x77600000 { + compatible = "adi,axi-i2s-1.00.a"; + reg = <0x77600000 0x1000>; + clocks = <&clk 15>, <&audio_clock>; + clock-names = "axi", "ref"; + dmas = <&ps7_dma 0>, <&ps7_dma 1>; + dma-names = "tx", "rx"; + }; diff --git a/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt b/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt new file mode 100644 index 000000000000..46f344965313 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt @@ -0,0 +1,30 @@ +ADI AXI-SPDIF controller + +Required properties: + - compatible : Must be "adi,axi-spdif-1.00.a" + - reg : Must contain SPDIF core's registers location and length + - clocks : Pairs of phandle and specifier referencing the controller's clocks. + The controller expects two clocks, the clock used for the AXI interface and + the clock used as the sampling rate reference clock sample. + - clock-names: "axi" for the clock to the AXI interface, "ref" for the sample + rate reference clock. + - dmas: Pairs of phandle and specifier for the DMA channel that is used by + the core. The core expects one dma channel for transmit. + - dma-names : Must be "tx" + +For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties +please check: + * resource-names.txt + * clock/clock-bindings.txt + * dma/dma.txt + +Example: + + spdif: spdif@0x77400000 { + compatible = "adi,axi-spdif-tx-1.00.a"; + reg = <0x77600000 0x1000>; + clocks = <&clk 15>, <&audio_clock>; + clock-names = "axi", "ref"; + dmas = <&ps7_dma 0>; + dma-names = "tx"; + }; diff --git a/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt b/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt new file mode 100644 index 000000000000..65783de0aedf --- /dev/null +++ b/Documentation/devicetree/bindings/sound/bcm2835-i2s.txt @@ -0,0 +1,25 @@ +* Broadcom BCM2835 SoC I2S/PCM module + +Required properties: +- compatible: "brcm,bcm2835-i2s" +- reg: A list of base address and size entries: + * The first entry should cover the PCM registers + * The second entry should cover the PCM clock registers +- dmas: List of DMA controller phandle and DMA request line ordered pairs. +- dma-names: Identifier string for each DMA request line in the dmas property. + These strings correspond 1:1 with the ordered pairs in dmas. + + One of the DMA channels will be responsible for transmission (should be + named "tx") and one for reception (should be named "rx"). + +Example: + +bcm2835_i2s: i2s@7e203000 { + compatible = "brcm,bcm2835-i2s"; + reg = <0x7e203000 0x20>, + <0x7e101098 0x02>; + + dmas = <&dma 2>, + <&dma 3>; + dma-names = "tx", "rx"; +}; diff --git a/Documentation/devicetree/bindings/sound/cs42l52.txt b/Documentation/devicetree/bindings/sound/cs42l52.txt new file mode 100644 index 000000000000..bc03c9312a19 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs42l52.txt @@ -0,0 +1,46 @@ +CS42L52 audio CODEC + +Required properties: + + - compatible : "cirrus,cs42l52" + + - reg : the I2C address of the device for I2C + +Optional properties: + + - cirrus,reset-gpio : GPIO controller's phandle and the number + of the GPIO used to reset the codec. + + - cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency. + Allowable values of 0x00 through 0x0F. These are raw values written to the + register, not the actual frequency. The frequency is determined by the following. + Frequency = (64xFs)/(N+2) + N = chgfreq_val + Fs = Sample Rate (variable) + + - cirrus,mica-differential-cfg : boolean, If present, then the MICA input is configured + as a differential input. If not present then the MICA input is configured as + Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input. + + - cirrus,micb-differential-cfg : boolean, If present, then the MICB input is configured + as a differential input. If not present then the MICB input is configured as + Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input. + + - cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin + 0 = 0.5 x VA + 1 = 0.6 x VA + 2 = 0.7 x VA + 3 = 0.8 x VA + 4 = 0.83 x VA + 5 = 0.91 x VA + +Example: + +codec: codec@4a { + compatible = "cirrus,cs42l52"; + reg = <0x4a>; + reset-gpio = <&gpio 10 0>; + cirrus,chgfreq-divisor = <0x05>; + cirrus.mica-differential-cfg; + cirrus,micbias-lvl = <5>; +}; diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index ed785b3f67be..569b26c4a81e 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt @@ -4,7 +4,8 @@ Required properties: - compatible : "ti,dm646x-mcasp-audio" : for DM646x platforms "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms - "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx) + "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx) + "ti,dra7-mcasp-audio" : for DRA7xx platforms - reg : Should contain reg specifiers for the entries in the reg-names property. - reg-names : Should contain: @@ -36,7 +37,8 @@ Optional properties: - pinctrl-0: Should specify pin control group used for this controller. - pinctrl-names: Should contain only one value - "default", for more details please refer to pinctrl-bindings.txt - +- fck_parent : Should contain a valid clock name which will be used as parent + for the McASP fck Example: diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt new file mode 100644 index 000000000000..d7b99fa637b5 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt @@ -0,0 +1,50 @@ +Freescale Enhanced Serial Audio Interface (ESAI) Controller + +The Enhanced Serial Audio Interface (ESAI) provides a full-duplex serial port +for serial communication with a variety of serial devices, including industry +standard codecs, Sony/Phillips Digital Interface (S/PDIF) transceivers, and +other DSPs. It has up to six transmitters and four receivers. + +Required properties: + + - compatible : Compatible list, must contain "fsl,imx35-esai". + + - reg : Offset and length of the register set for the device. + + - interrupts : Contains the spdif interrupt. + + - dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. + + - dma-names : Two dmas have to be defined, "tx" and "rx". + + - clocks: Contains an entry for each entry in clock-names. + + - clock-names : Includes the following entries: + "core" The core clock used to access registers + "extal" The esai baud clock for esai controller used to derive + HCK, SCK and FS. + "fsys" The system clock derived from ahb clock used to derive + HCK, SCK and FS. + + - fsl,fifo-depth: The number of elements in the transmit and receive FIFOs. + This number is the maximum allowed value for TFCR[TFWM] or RFCR[RFWM]. + + - fsl,esai-synchronous: This is a boolean property. If present, indicating + that ESAI would work in the synchronous mode, which means all the settings + for Receiving would be duplicated from Transmition related registers. + +Example: + +esai: esai@02024000 { + compatible = "fsl,imx35-esai"; + reg = <0x02024000 0x4000>; + interrupts = <0 51 0x04>; + clocks = <&clks 208>, <&clks 118>, <&clks 208>; + clock-names = "core", "extal", "fsys"; + dmas = <&sdma 23 21 0>, <&sdma 24 21 0>; + dma-names = "rx", "tx"; + fsl,fifo-depth = <128>; + fsl,esai-synchronous; + status = "disabled"; +}; diff --git a/Documentation/devicetree/bindings/sound/fsl,ssi.txt b/Documentation/devicetree/bindings/sound/fsl,ssi.txt index 4303b6ab6208..b93e9a91e30e 100644 --- a/Documentation/devicetree/bindings/sound/fsl,ssi.txt +++ b/Documentation/devicetree/bindings/sound/fsl,ssi.txt @@ -4,7 +4,12 @@ The SSI is a serial device that communicates with audio codecs. It can be programmed in AC97, I2S, left-justified, or right-justified modes. Required properties: -- compatible: Compatible list, contains "fsl,ssi". +- compatible: Compatible list, should contain one of the following + compatibles: + fsl,mpc8610-ssi + fsl,imx51-ssi + fsl,imx35-ssi + fsl,imx21-ssi - cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on. - reg: Offset and length of the register set for the device. - interrupts: where a is the interrupt number and b is a diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt new file mode 100644 index 000000000000..98611a6761c0 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -0,0 +1,40 @@ +Freescale Synchronous Audio Interface (SAI). + +The SAI is based on I2S module that used communicating with audio codecs, +which provides a synchronous audio interface that supports fullduplex +serial interfaces with frame synchronization such as I2S, AC97, TDM, and +codec/DSP interfaces. + + +Required properties: +- compatible: Compatible list, contains "fsl,vf610-sai". +- reg: Offset and length of the register set for the device. +- clocks: Must contain an entry for each entry in clock-names. +- clock-names : Must include the "sai" entry. +- dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. +- dma-names : Two dmas have to be defined, "tx" and "rx". +- pinctrl-names: Must contain a "default" entry. +- pinctrl-NNN: One property must exist for each entry in pinctrl-names. + See ../pinctrl/pinctrl-bindings.txt for details of the property values. +- big-endian-regs: If this property is absent, the little endian mode will + be in use as default, or the big endian mode will be in use for all the + device registers. +- big-endian-data: If this property is absent, the little endian mode will + be in use as default, or the big endian mode will be in use for all the + fifo data. + +Example: +sai2: sai@40031000 { + compatible = "fsl,vf610-sai"; + reg = <0x40031000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2_1>; + clocks = <&clks VF610_CLK_SAI2>; + clock-names = "sai"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, + <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; + big-endian-regs; + big-endian-data; +}; diff --git a/Documentation/devicetree/bindings/sound/hdmi.txt b/Documentation/devicetree/bindings/sound/hdmi.txt new file mode 100644 index 000000000000..31af7bca3099 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/hdmi.txt @@ -0,0 +1,17 @@ +Device-Tree bindings for dummy HDMI codec + +Required properties: + - compatible: should be "linux,hdmi-audio". + +CODEC output pins: + * TX + +CODEC input pins: + * RX + +Example node: + + hdmi_audio: hdmi_audio@0 { + compatible = "linux,hdmi-audio"; + status = "okay"; + }; diff --git a/Documentation/devicetree/bindings/sound/max98090.txt b/Documentation/devicetree/bindings/sound/max98090.txt new file mode 100644 index 000000000000..e4c8b36dcf89 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98090.txt @@ -0,0 +1,43 @@ +MAX98090 audio CODEC + +This device supports I2C only. + +Required properties: + +- compatible : "maxim,max98090". + +- reg : The I2C address of the device. + +- interrupts : The CODEC's interrupt output. + +Pins on the device (for linking into audio routes): + + * MIC1 + * MIC2 + * DMICL + * DMICR + * IN1 + * IN2 + * IN3 + * IN4 + * IN5 + * IN6 + * IN12 + * IN34 + * IN56 + * HPL + * HPR + * SPKL + * SPKR + * RCVL + * RCVR + * MICBIAS + +Example: + +audio-codec@10 { + compatible = "maxim,max98090"; + reg = <0x10>; + interrupt-parent = <&gpio>; + interrupts = ; +}; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt index 8b8903ef0800..57f40f93453e 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt @@ -3,10 +3,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-alc5632" - clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: - "pll_a" (The Tegra clock of that name), - "pll_a_out0" (The Tegra clock of that name), - "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt new file mode 100644 index 000000000000..9c7c55c71370 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt @@ -0,0 +1,51 @@ +NVIDIA Tegra audio complex, with MAX98090 CODEC + +Required properties: +- compatible : "nvidia,tegra-audio-max98090" +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names : Must include the following entries: + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) +- nvidia,model : The user-visible name of this sound complex. +- nvidia,audio-routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the connection's sink, + the second being the connection's source. Valid names for sources and + sinks are the MAX98090's pins (as documented in its binding), and the jacks + on the board: + + * Headphones + * Speakers + * Mic Jack + +- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's + connected to the CODEC. +- nvidia,audio-codec : The phandle of the MAX98090 audio codec. + +Optional properties: +- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in + +Example: + +sound { + compatible = "nvidia,tegra-audio-max98090-venice2", + "nvidia,tegra-audio-max98090"; + nvidia,model = "NVIDIA Tegra Venice2"; + + nvidia,audio-routing = + "Headphones", "HPR", + "Headphones", "HPL", + "Speakers", "SPKR", + "Speakers", "SPKL", + "Mic Jack", "MICBIAS", + "IN34", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&acodec>; + + clocks = <&tegra_car TEGRA124_CLK_PLL_A>, + <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; +}; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt index dc6224994d69..7788808dcd0b 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-rt5640.txt @@ -3,10 +3,11 @@ NVIDIA Tegra audio complex, with RT5640 CODEC Required properties: - compatible : "nvidia,tegra-audio-rt5640" - clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: - "pll_a" (The Tegra clock of that name), - "pll_a_out0" (The Tegra clock of that name), - "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt index aab6ce0ad2fc..96f6a57dd6b4 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt @@ -3,10 +3,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-wm8753" - clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: - "pll_a" (The Tegra clock of that name), - "pll_a_out0" (The Tegra clock of that name), - "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt index 4b44dfb6ca0d..b795d282818d 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt @@ -3,10 +3,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-wm8903" - clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: - "pll_a" (The Tegra clock of that name), - "pll_a_out0" (The Tegra clock of that name), - "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt index ad589b163639..436f6cd9d07c 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt @@ -3,10 +3,11 @@ NVIDIA Tegra audio complex Required properties: - compatible : "nvidia,tegra-audio-wm9712" - clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: - "pll_a" (The Tegra clock of that name), - "pll_a_out0" (The Tegra clock of that name), - "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) + - pll_a + - pll_a_out0 + - mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk) - nvidia,model : The user-visible name of this sound complex. - nvidia,audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt index c1454979c1ef..eaf00102d92c 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra20-ac97.txt @@ -4,19 +4,33 @@ Required properties: - compatible : "nvidia,tegra20-ac97" - reg : Should contain AC97 controller registers location and length - interrupts : Should contain AC97 interrupt -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for the AC97 controller +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - ac97 +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx + - tx +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. - nvidia,codec-reset-gpio : The Tegra GPIO controller's phandle and the number of the GPIO used to reset the external AC97 codec - nvidia,codec-sync-gpio : The Tegra GPIO controller's phandle and the number of the GPIO corresponding with the AC97 DAP _FS line + Example: ac97@70002000 { compatible = "nvidia,tegra20-ac97"; reg = <0x70002000 0x200>; interrupts = <0 81 0x04>; - nvidia,dma-request-selector = <&apbdma 12>; nvidia,codec-reset-gpio = <&gpio 170 0>; nvidia,codec-sync-gpio = <&gpio 120 0>; + clocks = <&tegra_car 3>; + resets = <&tegra_car 3>; + reset-names = "ac97"; + dmas = <&apbdma 12>, <&apbdma 12>; + dma-names = "rx", "tx"; }; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt index 0df2b5c816e3..dc30c6bfbe95 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt @@ -4,8 +4,17 @@ Required properties: - compatible : "nvidia,tegra20-i2s" - reg : Should contain I2S registers location and length - interrupts : Should contain I2S interrupt -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for this I2S controller +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - i2s +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx + - tx +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. Example: @@ -13,5 +22,9 @@ i2s@70002800 { compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; interrupts = < 45 >; - nvidia,dma-request-selector = < &apbdma 2 >; + clocks = <&tegra_car 11>; + resets = <&tegra_car 11>; + reset-names = "i2s"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; }; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt index 0e5c12c66523..946e2ac46091 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt @@ -7,18 +7,48 @@ Required properties: - Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks. - Tegra114 requires an additional entry, for the APBIF2 register block. - interrupts : Should contain AHUB interrupt -- nvidia,dma-request-selector : A list of the DMA channel specifiers. Each - entry contains the Tegra DMA controller's phandle and request selector. - If a single entry is present, the request selectors for the channels are - assumed to be contiguous, and increment from this value. - If multiple values are given, one value must be given per channel. -- clocks : Must contain an entry for each required entry in clock-names. +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. - clock-names : Must include the following entries: - - Tegra30: Requires d_audio, apbif, i2s0, i2s1, i2s2, i2s3, i2s4, dam0, - dam1, dam2, spdif_in. - - Tegra114: Additionally requires amx, adx. + - d_audio + - apbif +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + Tegra30 and later: + - d_audio + - apbif + - i2s0 + - i2s1 + - i2s2 + - i2s3 + - i2s4 + - dam0 + - dam1 + - dam2 + - spdif + Tegra114 and later additionally require: + - amx + - adx + Tegra124 and later additionally require: + - amx1 + - adx1 + - afc0 + - afc1 + - afc2 + - afc3 + - afc4 + - afc5 - ranges : The bus address mapping for the configlink register bus. Can be empty since the mapping is 1:1. +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx0 .. rx + - tx0 .. tx + ... where n is: + Tegra30: 3 + Tegra114, Tegra124: 9 - #address-cells : For the configlink bus. Should be <1>; - #size-cells : For the configlink bus. Should be <1>. @@ -35,13 +65,20 @@ ahub@70080000 { reg = <0x70080000 0x200 0x70080200 0x100>; interrupts = < 0 103 0x04 >; nvidia,dma-request-selector = <&apbdma 1>; - clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>, + clocks = <&tegra_car 106>, <&tegra_car 107>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>, <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>, <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>, - <&tegra_car 110>, <&tegra_car 162>; - clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + <&tegra_car 110>, <&tegra_car 10>; + reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", "i2s3", "i2s4", "dam0", "dam1", "dam2", - "spdif_in"; + "spdif"; + dmas = <&apbdma 1>, <&apbdma 1>; + <&apbdma 2>, <&apbdma 2>; + <&apbdma 3>, <&apbdma 3>; + <&apbdma 4>, <&apbdma 4>; + dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", "rx3", "tx3"; ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt index dfa6c037124a..0c113ffe3814 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt @@ -3,13 +3,22 @@ NVIDIA Tegra30 I2S controller Required properties: - compatible : "nvidia,tegra30-i2s" - reg : Should contain I2S registers location and length +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - i2s - nvidia,ahub-cif-ids : The list of AHUB CIF IDs for this port, rx (playback) first, tx (capture) second. See nvidia,tegra30-ahub.txt for values. Example: -i2s@70002800 { +i2s@70080300 { compatible = "nvidia,tegra30-i2s"; reg = <0x70080300 0x100>; nvidia,ahub-cif-ids = <4 4>; + clocks = <&tegra_car 11>; + resets = <&tegra_car 11>; + reset-names = "i2s"; }; diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt new file mode 100644 index 000000000000..e9e20ec67d62 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -0,0 +1,77 @@ +Simple-Card: + +Simple-Card specifies audio DAI connection of SoC <-> codec. + +Required properties: + +- compatible : "simple-audio-card" + +Optional properties: + +- simple-audio-card,format : CPU/CODEC common audio format. + "i2s", "right_j", "left_j" , "dsp_a" + "dsp_b", "ac97", "pdm", "msb", "lsb" +- simple-audio-card,routing : A list of the connections between audio components. + Each entry is a pair of strings, the first being the + connection's sink, the second being the connection's + source. + +Required subnodes: + +- simple-audio-card,cpu : CPU sub-node +- simple-audio-card,codec : CODEC sub-node + +Required CPU/CODEC subnodes properties: + +- sound-dai : phandle and port of CPU/CODEC + +Optional CPU/CODEC subnodes properties: + +- format : CPU/CODEC specific audio format if needed. + see simple-audio-card,format +- frame-master : bool property. add this if subnode is frame master +- bitclock-master : bool property. add this if subnode is bitclock master +- bitclock-inversion : bool property. add this if subnode has clock inversion +- frame-inversion : bool property. add this if subnode has frame inversion +- clocks / system-clock-frequency : specify subnode's clock if needed. + it can be specified via "clocks" if system has + clock node (= common clock), or "system-clock-frequency" + (if system doens't support common clock) + +Example: + +sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "left_j"; + simple-audio-routing = + "MIC_IN", "Mic Jack", + "Headphone Jack", "HP_OUT", + "Ext Spk", "LINE_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sh_fsi2 0>; + }; + + simple-audio-card,codec { + sound-dai = <&ak4648>; + bitclock-master; + frame-master; + clocks = <&osc>; + }; +}; + +&i2c0 { + ak4648: ak4648@12 { + #sound-dai-cells = <0>; + compatible = "asahi-kasei,ak4648"; + reg = <0x12>; + }; +}; + +sh_fsi2: sh_fsi2@ec230000 { + #sound-dai-cells = <1>; + compatible = "renesas,sh_fsi2"; + reg = <0xec230000 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 146 0x4>; +}; diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index 5e6040c2c2e9..9d8ea14db490 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt @@ -6,6 +6,7 @@ Required properties: - compatible - "string" - One of: "ti,tlv320aic3x" - Generic TLV320AIC3x device + "ti,tlv320aic32x4" - TLV320AIC32x4 "ti,tlv320aic33" - TLV320AIC33 "ti,tlv320aic3007" - TLV320AIC3007 "ti,tlv320aic3106" - TLV320AIC3106 diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt index 91ff771c7e77..7ea701e07dc2 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt @@ -4,10 +4,19 @@ Required properties: - compatible : should be "nvidia,tegra114-spi". - reg: Should contain SPI registers location and length. - interrupts: Should contain SPI interrupts. -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for this SPI controller. -- This is also require clock named "spi" as per binding document - Documentation/devicetree/bindings/clock/clock-bindings.txt +- clock-names : Must include the following entries: + - spi +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - spi +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx + - tx +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. Recommended properties: - spi-max-frequency: Definition as per @@ -18,9 +27,14 @@ spi@7000d600 { compatible = "nvidia,tegra114-spi"; reg = <0x7000d600 0x200>; interrupts = <0 82 0x04>; - nvidia,dma-request-selector = <&apbdma 16>; spi-max-frequency = <25000000>; #address-cells = <1>; #size-cells = <0>; + clocks = <&tegra_car 44>; + clock-names = "spi"; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt index 7b53da5cb75b..bdf08e6dec9b 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt @@ -4,8 +4,17 @@ Required properties: - compatible : should be "nvidia,tegra20-sflash". - reg: Should contain SFLASH registers location and length. - interrupts: Should contain SFLASH interrupts. -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for this SFLASH controller. +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - spi +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx + - tx Recommended properties: - spi-max-frequency: Definition as per @@ -17,10 +26,13 @@ spi@7000c380 { compatible = "nvidia,tegra20-sflash"; reg = <0x7000c380 0x80>; interrupts = <0 39 0x04>; - nvidia,dma-request-selector = <&apbdma 16>; spi-max-frequency = <25000000>; #address-cells = <1>; #size-cells = <0>; + clocks = <&tegra_car 43>; + resets = <&tegra_car 43>; + reset-names = "spi"; + dmas = <&apbdma 11>, <&apbdma 11>; + dma-names = "rx", "tx"; status = "disabled"; }; - diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt index eefe15e3d95e..5db9144a33c8 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt @@ -4,8 +4,17 @@ Required properties: - compatible : should be "nvidia,tegra20-slink", "nvidia,tegra30-slink". - reg: Should contain SLINK registers location and length. - interrupts: Should contain SLINK interrupts. -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for this SLINK controller. +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the following entries: + - spi +- dmas : Must contain an entry for each entry in clock-names. + See ../dma/dma.txt for details. +- dma-names : Must include the following entries: + - rx + - tx Recommended properties: - spi-max-frequency: Definition as per @@ -17,10 +26,13 @@ spi@7000d600 { compatible = "nvidia,tegra20-slink"; reg = <0x7000d600 0x200>; interrupts = <0 82 0x04>; - nvidia,dma-request-selector = <&apbdma 16>; spi-max-frequency = <25000000>; #address-cells = <1>; #size-cells = <0>; + clocks = <&tegra_car 44>; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; - diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index 800dafe5b01b..e5a4d1b4acfe 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt @@ -67,7 +67,7 @@ only 1(SINGLE), 2(DUAL) and 4(QUAD). Dual/Quad mode is not allowed when 3-wire mode is used. If a gpio chipselect is used for the SPI slave the gpio number will be passed -via the cs_gpio +via the SPI master node cs-gpios property. SPI example for an MPC5200 SPI bus: spi@f00 { diff --git a/Documentation/devicetree/bindings/spi/ti_qspi.txt b/Documentation/devicetree/bindings/spi/ti_qspi.txt index 1f9641ade0b5..601a360531a5 100644 --- a/Documentation/devicetree/bindings/spi/ti_qspi.txt +++ b/Documentation/devicetree/bindings/spi/ti_qspi.txt @@ -3,6 +3,11 @@ TI QSPI controller. Required properties: - compatible : should be "ti,dra7xxx-qspi" or "ti,am4372-qspi". - reg: Should contain QSPI registers location and length. +- reg-names: Should contain the resource reg names. + - qspi_base: Qspi configuration register Address space + - qspi_mmap: Memory mapped Address space + - (optional) qspi_ctrlmod: Control module Address space +- interrupts: should contain the qspi interrupt number. - #address-cells, #size-cells : Must be present if the device has sub-nodes - ti,hwmods: Name of the hwmod associated to the QSPI @@ -14,7 +19,8 @@ Example: qspi: qspi@4b300000 { compatible = "ti,dra7xxx-qspi"; - reg = <0x4b300000 0x100>; + reg = <0x47900000 0x100>, <0x30000000 0x3ffffff>; + reg-names = "qspi_base", "qspi_mmap"; #address-cells = <1>; #size-cells = <0>; spi-max-frequency = <25000000>; diff --git a/Documentation/devicetree/bindings/submitting-patches.txt b/Documentation/devicetree/bindings/submitting-patches.txt new file mode 100644 index 000000000000..042a0273b8ba --- /dev/null +++ b/Documentation/devicetree/bindings/submitting-patches.txt @@ -0,0 +1,38 @@ + + Submitting devicetree (DT) binding patches + +I. For patch submitters + + 0) Normal patch submission rules from Documentation/SubmittingPatches + applies. + + 1) The Documentation/ portion of the patch should be a separate patch. + + 2) Submit the entire series to the devicetree mailinglist at + + devicetree@vger.kernel.org + +II. For kernel maintainers + + 1) If you aren't comfortable reviewing a given binding, reply to it and ask + the devicetree maintainers for guidance. This will help them prioritize + which ones to review and which ones are ok to let go. + + 2) For driver (not subsystem) bindings: If you are comfortable with the + binding, and it hasn't received an Acked-by from the devicetree + maintainers after a few weeks, go ahead and take it. + + Subsystem bindings (anything affecting more than a single device) + then getting a devicetree maintainer to review it is required. + + 3) For a series going though multiple trees, the binding patch should be + kept with the driver using the binding. + +III. Notes + + 0) Please see ...bindings/ABI.txt for details regarding devicetree ABI. + + 1) This document is intended as a general familiarization with the process as + decided at the 2013 Kernel Summit. When in doubt, the current word of the + devicetree maintainers overrules this document. In that situation, a patch + updating this document would be appreciated. diff --git a/Documentation/devicetree/bindings/thermal/imx-thermal.txt b/Documentation/devicetree/bindings/thermal/imx-thermal.txt index 541c25e49abf..1f0f67234a91 100644 --- a/Documentation/devicetree/bindings/thermal/imx-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/imx-thermal.txt @@ -8,10 +8,14 @@ Required properties: calibration data, e.g. OCOTP on imx6q. The details about calibration data can be found in SoC Reference Manual. +Optional properties: +- clocks : thermal sensor's clock source. + Example: tempmon { compatible = "fsl,imx6q-tempmon"; fsl,tempmon = <&anatop>; fsl,tempmon-data = <&ocotp>; + clocks = <&clks 172>; }; diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt b/Documentation/devicetree/bindings/thermal/thermal.txt new file mode 100644 index 000000000000..f5db6b72a36f --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/thermal.txt @@ -0,0 +1,595 @@ +* Thermal Framework Device Tree descriptor + +This file describes a generic binding to provide a way of +defining hardware thermal structure using device tree. +A thermal structure includes thermal zones and their components, +such as trip points, polling intervals, sensors and cooling devices +binding descriptors. + +The target of device tree thermal descriptors is to describe only +the hardware thermal aspects. The thermal device tree bindings are +not about how the system must control or which algorithm or policy +must be taken in place. + +There are five types of nodes involved to describe thermal bindings: +- thermal sensors: devices which may be used to take temperature + measurements. +- cooling devices: devices which may be used to dissipate heat. +- trip points: describe key temperatures at which cooling is recommended. The + set of points should be chosen based on hardware limits. +- cooling maps: used to describe links between trip points and cooling devices; +- thermal zones: used to describe thermal data within the hardware; + +The following is a description of each of these node types. + +* Thermal sensor devices + +Thermal sensor devices are nodes providing temperature sensing capabilities on +thermal zones. Typical devices are I2C ADC converters and bandgaps. These are +nodes providing temperature data to thermal zones. Thermal sensor devices may +control one or more internal sensors. + +Required property: +- #thermal-sensor-cells: Used to provide sensor device specific information + Type: unsigned while referring to it. Typically 0 on thermal sensor + Size: one cell nodes with only one sensor, and at least 1 on nodes + with several internal sensors, in order + to identify uniquely the sensor instances within + the IC. See thermal zone binding for more details + on how consumers refer to sensor devices. + +* Cooling device nodes + +Cooling devices are nodes providing control on power dissipation. There +are essentially two ways to provide control on power dissipation. First +is by means of regulating device performance, which is known as passive +cooling. A typical passive cooling is a CPU that has dynamic voltage and +frequency scaling (DVFS), and uses lower frequencies as cooling states. +Second is by means of activating devices in order to remove +the dissipated heat, which is known as active cooling, e.g. regulating +fan speeds. In both cases, cooling devices shall have a way to determine +the state of cooling in which the device is. + +Any cooling device has a range of cooling states (i.e. different levels +of heat dissipation). For example a fan's cooling states correspond to +the different fan speeds possible. Cooling states are referred to by +single unsigned integers, where larger numbers mean greater heat +dissipation. The precise set of cooling states associated with a device +(as referred to be the cooling-min-state and cooling-max-state +properties) should be defined in a particular device's binding. +For more examples of cooling devices, refer to the example sections below. + +Required properties: +- cooling-min-state: An integer indicating the smallest + Type: unsigned cooling state accepted. Typically 0. + Size: one cell + +- cooling-max-state: An integer indicating the largest + Type: unsigned cooling state accepted. + Size: one cell + +- #cooling-cells: Used to provide cooling device specific information + Type: unsigned while referring to it. Must be at least 2, in order + Size: one cell to specify minimum and maximum cooling state used + in the reference. The first cell is the minimum + cooling state requested and the second cell is + the maximum cooling state requested in the reference. + See Cooling device maps section below for more details + on how consumers refer to cooling devices. + +* Trip points + +The trip node is a node to describe a point in the temperature domain +in which the system takes an action. This node describes just the point, +not the action. + +Required properties: +- temperature: An integer indicating the trip temperature level, + Type: signed in millicelsius. + Size: one cell + +- hysteresis: A low hysteresis value on temperature property (above). + Type: unsigned This is a relative value, in millicelsius. + Size: one cell + +- type: a string containing the trip type. Expected values are: + "active": A trip point to enable active cooling + "passive": A trip point to enable passive cooling + "hot": A trip point to notify emergency + "critical": Hardware not reliable. + Type: string + +* Cooling device maps + +The cooling device maps node is a node to describe how cooling devices +get assigned to trip points of the zone. The cooling devices are expected +to be loaded in the target system. + +Required properties: +- cooling-device: A phandle of a cooling device with its specifier, + Type: phandle + referring to which cooling device is used in this + cooling specifier binding. In the cooling specifier, the first cell + is the minimum cooling state and the second cell + is the maximum cooling state used in this map. +- trip: A phandle of a trip point node within the same thermal + Type: phandle of zone. + trip point node + +Optional property: +- contribution: The cooling contribution to the thermal zone of the + Type: unsigned referred cooling device at the referred trip point. + Size: one cell The contribution is a ratio of the sum + of all cooling contributions within a thermal zone. + +Note: Using the THERMAL_NO_LIMIT (-1UL) constant in the cooling-device phandle +limit specifier means: +(i) - minimum state allowed for minimum cooling state used in the reference. +(ii) - maximum state allowed for maximum cooling state used in the reference. +Refer to include/dt-bindings/thermal/thermal.h for definition of this constant. + +* Thermal zone nodes + +The thermal zone node is the node containing all the required info +for describing a thermal zone, including its cooling device bindings. The +thermal zone node must contain, apart from its own properties, one sub-node +containing trip nodes and one sub-node containing all the zone cooling maps. + +Required properties: +- polling-delay: The maximum number of milliseconds to wait between polls + Type: unsigned when checking this thermal zone. + Size: one cell + +- polling-delay-passive: The maximum number of milliseconds to wait + Type: unsigned between polls when performing passive cooling. + Size: one cell + +- thermal-sensors: A list of thermal sensor phandles and sensor specifier + Type: list of used while monitoring the thermal zone. + phandles + sensor + specifier + +- trips: A sub-node which is a container of only trip point nodes + Type: sub-node required to describe the thermal zone. + +- cooling-maps: A sub-node which is a container of only cooling device + Type: sub-node map nodes, used to describe the relation between trips + and cooling devices. + +Optional property: +- coefficients: An array of integers (one signed cell) containing + Type: array coefficients to compose a linear relation between + Elem size: one cell the sensors listed in the thermal-sensors property. + Elem type: signed Coefficients defaults to 1, in case this property + is not specified. A simple linear polynomial is used: + Z = c0 * x0 + c1 + x1 + ... + c(n-1) * x(n-1) + cn. + + The coefficients are ordered and they match with sensors + by means of sensor ID. Additional coefficients are + interpreted as constant offset. + +Note: The delay properties are bound to the maximum dT/dt (temperature +derivative over time) in two situations for a thermal zone: +(i) - when passive cooling is activated (polling-delay-passive); and +(ii) - when the zone just needs to be monitored (polling-delay) or +when active cooling is activated. + +The maximum dT/dt is highly bound to hardware power consumption and dissipation +capability. The delays should be chosen to account for said max dT/dt, +such that a device does not cross several trip boundaries unexpectedly +between polls. Choosing the right polling delays shall avoid having the +device in temperature ranges that may damage the silicon structures and +reduce silicon lifetime. + +* The thermal-zones node + +The "thermal-zones" node is a container for all thermal zone nodes. It shall +contain only sub-nodes describing thermal zones as in the section +"Thermal zone nodes". The "thermal-zones" node appears under "/". + +* Examples + +Below are several examples on how to use thermal data descriptors +using device tree bindings: + +(a) - CPU thermal zone + +The CPU thermal zone example below describes how to setup one thermal zone +using one single sensor as temperature source and many cooling devices and +power dissipation control sources. + +#include + +cpus { + /* + * Here is an example of describing a cooling device for a DVFS + * capable CPU. The CPU node describes its four OPPs. + * The cooling states possible are 0..3, and they are + * used as OPP indexes. The minimum cooling state is 0, which means + * all four OPPs can be available to the system. The maximum + * cooling state is 3, which means only the lowest OPPs (198MHz@0.85V) + * can be available in the system. + */ + cpu0: cpu@0 { + ... + operating-points = < + /* kHz uV */ + 970000 1200000 + 792000 1100000 + 396000 950000 + 198000 850000 + >; + cooling-min-state = <0>; + cooling-max-state = <3>; + #cooling-cells = <2>; /* min followed by max */ + }; + ... +}; + +&i2c1 { + ... + /* + * A simple fan controller which supports 10 speeds of operation + * (represented as 0-9). + */ + fan0: fan@0x48 { + ... + cooling-min-state = <0>; + cooling-max-state = <9>; + #cooling-cells = <2>; /* min followed by max */ + }; +}; + +ocp { + ... + /* + * A simple IC with a single bandgap temperature sensor. + */ + bandgap0: bandgap@0x0000ED00 { + ... + #thermal-sensor-cells = <0>; + }; +}; + +thermal-zones { + cpu-thermal: cpu-thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = <&bandgap0>; + + trips { + cpu-alert0: cpu-alert { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "active"; + }; + cpu-alert1: cpu-alert { + temperature = <100000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu-crit: cpu-crit { + temperature = <125000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu-alert0>; + cooling-device = <&fan0 THERMAL_NO_LIMITS 4>; + }; + map1 { + trip = <&cpu-alert1>; + cooling-device = <&fan0 5 THERMAL_NO_LIMITS>; + }; + map2 { + trip = <&cpu-alert1>; + cooling-device = + <&cpu0 THERMAL_NO_LIMITS THERMAL_NO_LIMITS>; + }; + }; + }; +}; + +In the example above, the ADC sensor (bandgap0) at address 0x0000ED00 is +used to monitor the zone 'cpu-thermal' using its sole sensor. A fan +device (fan0) is controlled via I2C bus 1, at address 0x48, and has ten +different cooling states 0-9. It is used to remove the heat out of +the thermal zone 'cpu-thermal' using its cooling states +from its minimum to 4, when it reaches trip point 'cpu-alert0' +at 90C, as an example of active cooling. The same cooling device is used at +'cpu-alert1', but from 5 to its maximum state. The cpu@0 device is also +linked to the same thermal zone, 'cpu-thermal', as a passive cooling device, +using all its cooling states at trip point 'cpu-alert1', +which is a trip point at 100C. On the thermal zone 'cpu-thermal', at the +temperature of 125C, represented by the trip point 'cpu-crit', the silicon +is not reliable anymore. + +(b) - IC with several internal sensors + +The example below describes how to deploy several thermal zones based off a +single sensor IC, assuming it has several internal sensors. This is a common +case on SoC designs with several internal IPs that may need different thermal +requirements, and thus may have their own sensor to monitor or detect internal +hotspots in their silicon. + +#include + +ocp { + ... + /* + * A simple IC with several bandgap temperature sensors. + */ + bandgap0: bandgap@0x0000ED00 { + ... + #thermal-sensor-cells = <1>; + }; +}; + +thermal-zones { + cpu-thermal: cpu-thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap0 0>; + + trips { + /* each zone within the SoC may have its own trips */ + cpu-alert: cpu-alert { + temperature = <100000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu-crit: cpu-crit { + temperature = <125000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + /* each zone within the SoC may have its own cooling */ + ... + }; + }; + + gpu-thermal: gpu-thermal { + polling-delay-passive = <120>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap0 1>; + + trips { + /* each zone within the SoC may have its own trips */ + gpu-alert: gpu-alert { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + gpu-crit: gpu-crit { + temperature = <105000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + /* each zone within the SoC may have its own cooling */ + ... + }; + }; + + dsp-thermal: dsp-thermal { + polling-delay-passive = <50>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap0 2>; + + trips { + /* each zone within the SoC may have its own trips */ + dsp-alert: gpu-alert { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + dsp-crit: gpu-crit { + temperature = <135000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + /* each zone within the SoC may have its own cooling */ + ... + }; + }; +}; + +In the example above, there is one bandgap IC which has the capability to +monitor three sensors. The hardware has been designed so that sensors are +placed on different places in the DIE to monitor different temperature +hotspots: one for CPU thermal zone, one for GPU thermal zone and the +other to monitor a DSP thermal zone. + +Thus, there is a need to assign each sensor provided by the bandgap IC +to different thermal zones. This is achieved by means of using the +#thermal-sensor-cells property and using the first cell of the sensor +specifier as sensor ID. In the example, then, is used to +monitor CPU thermal zone, is used to monitor GPU thermal +zone and is used to monitor DSP thermal zone. Each zone +may be uncorrelated, having its own dT/dt requirements, trips +and cooling maps. + + +(c) - Several sensors within one single thermal zone + +The example below illustrates how to use more than one sensor within +one thermal zone. + +#include + +&i2c1 { + ... + /* + * A simple IC with a single temperature sensor. + */ + adc: sensor@0x49 { + ... + #thermal-sensor-cells = <0>; + }; +}; + +ocp { + ... + /* + * A simple IC with a single bandgap temperature sensor. + */ + bandgap0: bandgap@0x0000ED00 { + ... + #thermal-sensor-cells = <0>; + }; +}; + +thermal-zones { + cpu-thermal: cpu-thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + thermal-sensors = <&bandgap0>, /* cpu */ + <&adc>; /* pcb north */ + + /* hotspot = 100 * bandgap - 120 * adc + 484 */ + coefficients = <100 -120 484>; + + trips { + ... + }; + + cooling-maps { + ... + }; + }; +}; + +In some cases, there is a need to use more than one sensor to extrapolate +a thermal hotspot in the silicon. The above example illustrates this situation. +For instance, it may be the case that a sensor external to CPU IP may be placed +close to CPU hotspot and together with internal CPU sensor, it is used +to determine the hotspot. Assuming this is the case for the above example, +the hypothetical extrapolation rule would be: + hotspot = 100 * bandgap - 120 * adc + 484 + +In other context, the same idea can be used to add fixed offset. For instance, +consider the hotspot extrapolation rule below: + hotspot = 1 * adc + 6000 + +In the above equation, the hotspot is always 6C higher than what is read +from the ADC sensor. The binding would be then: + thermal-sensors = <&adc>; + + /* hotspot = 1 * adc + 6000 */ + coefficients = <1 6000>; + +(d) - Board thermal + +The board thermal example below illustrates how to setup one thermal zone +with many sensors and many cooling devices. + +#include + +&i2c1 { + ... + /* + * An IC with several temperature sensor. + */ + adc-dummy: sensor@0x50 { + ... + #thermal-sensor-cells = <1>; /* sensor internal ID */ + }; +}; + +thermal-zones { + batt-thermal { + polling-delay-passive = <500>; /* milliseconds */ + polling-delay = <2500>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&adc-dummy 4>; + + trips { + ... + }; + + cooling-maps { + ... + }; + }; + + board-thermal: board-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <2500>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&adc-dummy 0>, /* pcb top edge */ + <&adc-dummy 1>, /* lcd */ + <&adc-dymmy 2>; /* back cover */ + /* + * An array of coefficients describing the sensor + * linear relation. E.g.: + * z = c1*x1 + c2*x2 + c3*x3 + */ + coefficients = <1200 -345 890>; + + trips { + /* Trips are based on resulting linear equation */ + cpu-trip: cpu-trip { + temperature = <60000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + gpu-trip: gpu-trip { + temperature = <55000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + } + lcd-trip: lcp-trip { + temperature = <53000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + crit-trip: crit-trip { + temperature = <68000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu-trip>; + cooling-device = <&cpu0 0 2>; + contribution = <55>; + }; + map1 { + trip = <&gpu-trip>; + cooling-device = <&gpu0 0 2>; + contribution = <20>; + }; + map2 { + trip = <&lcd-trip>; + cooling-device = <&lcd0 5 10>; + contribution = <15>; + }; + }; + }; +}; + +The above example is a mix of previous examples, a sensor IP with several internal +sensors used to monitor different zones, one of them is composed by several sensors and +with different cooling devices. diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt new file mode 100644 index 000000000000..7c26154b8bbb --- /dev/null +++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt @@ -0,0 +1,22 @@ +Allwinner SoCs High Speed Timer Controller + +Required properties: + +- compatible : should be "allwinner,sun5i-a13-hstimer" or + "allwinner,sun7i-a20-hstimer" +- reg : Specifies base physical address and size of the registers. +- interrupts : The interrupts of these timers (2 for the sun5i IP, 4 for the sun7i + one) +- clocks: phandle to the source clock (usually the AHB clock) + +Example: + +timer@01c60000 { + compatible = "allwinner,sun7i-a20-hstimer"; + reg = <0x01c60000 0x1000>; + interrupts = <0 51 1>, + <0 52 1>, + <0 53 1>, + <0 54 1>; + clocks = <&ahb1_gates 19>; +}; diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt index e019fdc38773..4a864bd10d3d 100644 --- a/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt +++ b/Documentation/devicetree/bindings/timer/nvidia,tegra20-timer.txt @@ -8,6 +8,8 @@ Required properties: - compatible : should be "nvidia,tegra20-timer". - reg : Specifies base physical address and size of the registers. - interrupts : A list of 4 interrupts; one per timer channel. +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. Example: @@ -18,4 +20,5 @@ timer { 0 1 0x04 0 41 0x04 0 42 0x04>; + clocks = <&tegra_car 132>; }; diff --git a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt index 906109d4c593..b5082a1cf461 100644 --- a/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt +++ b/Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt @@ -10,6 +10,8 @@ Required properties: - reg : Specifies base physical address and size of the registers. - interrupts : A list of 6 interrupts; one per each of timer channels 1 through 5, and one for the shared interrupt for the remaining channels. +- clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. timer { compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer"; @@ -20,4 +22,5 @@ timer { 0 42 0x04 0 121 0x04 0 122 0x04>; + clocks = <&tegra_car 214>; }; diff --git a/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt b/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt index b5a86d20ee36..167d5dab9f64 100644 --- a/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt +++ b/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt @@ -31,38 +31,58 @@ Required properties: 7: .. i: Local Timer Interrupt n -Example 1: In this example, the system uses only the first global timer - interrupt generated by MCT and the remaining three global timer - interrupts are unused. Two local timer interrupts have been - specified. + For MCT block that uses a per-processor interrupt for local timers, such + as ones compatible with "samsung,exynos4412-mct", only one local timer + interrupt might be specified, meaning that all local timers use the same + per processor interrupt. + +Example 1: In this example, the IP contains two local timers, using separate + interrupts, so two local timer interrupts have been specified, + in addition to four global timer interrupts. mct@10050000 { compatible = "samsung,exynos4210-mct"; reg = <0x10050000 0x800>; - interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>, + interrupts = <0 57 0>, <0 69 0>, <0 70 0>, <0 71 0>, <0 42 0>, <0 48 0>; }; -Example 2: In this example, the MCT global and local timer interrupts are - connected to two separate interrupt controllers. Hence, an - interrupt-map is created to map the interrupts to the respective - interrupt controllers. +Example 2: In this example, the timer interrupts are connected to two separate + interrupt controllers. Hence, an interrupt-map is created to map + the interrupts to the respective interrupt controllers. mct@101C0000 { compatible = "samsung,exynos4210-mct"; reg = <0x101C0000 0x800>; - interrupt-controller; - #interrups-cells = <2>; interrupt-parent = <&mct_map>; - interrupts = <0 0>, <1 0>, <2 0>, <3 0>, - <4 0>, <5 0>; + interrupts = <0>, <1>, <2>, <3>, <4>, <5>; mct_map: mct-map { - #interrupt-cells = <2>; + #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = <0x0 0 &combiner 23 3>, - <0x4 0 &gic 0 120 0>, - <0x5 0 &gic 0 121 0>; + interrupt-map = <0 &gic 0 57 0>, + <1 &gic 0 69 0>, + <2 &combiner 12 6>, + <3 &combiner 12 7>, + <4 &gic 0 42 0>, + <5 &gic 0 48 0>; }; }; + +Example 3: In this example, the IP contains four local timers, but using + a per-processor interrupt to handle them. Either all the local + timer interrupts can be specified, with the same interrupt specifier + value or just the first one. + + mct@10050000 { + compatible = "samsung,exynos4412-mct"; + reg = <0x10050000 0x800>; + + /* Both ways are possible in this case. Either: */ + interrupts = <0 57 0>, <0 69 0>, <0 70 0>, <0 71 0>, + <0 42 0>; + /* or: */ + interrupts = <0 57 0>, <0 69 0>, <0 70 0>, <0 71 0>, + <0 42 0>, <0 42 0>, <0 42 0>, <0 42 0>; + }; diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt similarity index 100% rename from Documentation/devicetree/bindings/usb/ci13xxx-imx.txt rename to Documentation/devicetree/bindings/usb/ci-hdrc-imx.txt diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 8b60e90efe33..b8b6871f116f 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -7,6 +7,14 @@ Required properties: - snps,dwc2: A generic DWC2 USB controller with default parameters. - reg : Should contain 1 register range (address and length) - interrupts : Should contain 1 interrupt +- clocks: clock provider specifier +- clock-names: shall be "otg" +Refer to clk/clock-bindings.txt for generic clock consumer properties + +Optional properties: +- phys: phy provider specifier +- phy-names: shall be "device" +Refer to phy/phy-bindings.txt for generic phy consumer properties Example: @@ -14,4 +22,8 @@ Example: compatible = "ralink,rt3050-usb, snps,dwc2"; reg = <0x101c0000 40000>; interrupts = <18>; + clocks = <&usb_otg_ahb_clk>; + clock-names = "otg"; + phys = <&usbphy>; + phy-names = "usb2-phy"; }; diff --git a/Documentation/devicetree/bindings/usb/gr-udc.txt b/Documentation/devicetree/bindings/usb/gr-udc.txt new file mode 100644 index 000000000000..0c5118f7a916 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/gr-udc.txt @@ -0,0 +1,28 @@ +USB Peripheral Controller driver for Aeroflex Gaisler GRUSBDC. + +The GRUSBDC USB Device Controller core is available in the GRLIB VHDL +IP core library. + +Note: In the ordinary environment for the core, a Leon SPARC system, +these properties are built from information in the AMBA plug&play. + +Required properties: + +- name : Should be "GAISLER_USBDC" or "01_021" + +- reg : Address and length of the register set for the device + +- interrupts : Interrupt numbers for this device + +Optional properties: + +- epobufsizes : An array of buffer sizes for OUT endpoints. If the property is + not present, or for endpoints outside of the array, 1024 is assumed by + the driver. + +- epibufsizes : An array of buffer sizes for IN endpoints. If the property is + not present, or for endpoints outside of the array, 1024 is assumed by + the driver. + +For further information look in the documentation for the GLIB IP core library: +http://www.gaisler.com/products/grlib/grip.pdf diff --git a/Documentation/devicetree/bindings/usb/keystone-phy.txt b/Documentation/devicetree/bindings/usb/keystone-phy.txt new file mode 100644 index 000000000000..f37b3a86341d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/keystone-phy.txt @@ -0,0 +1,20 @@ +TI Keystone USB PHY + +Required properties: + - compatible: should be "ti,keystone-usbphy". + - #address-cells, #size-cells : should be '1' if the device has sub-nodes + with 'reg' property. + - reg : Address and length of the usb phy control register set. + +The main purpose of this PHY driver is to enable the USB PHY reference clock +gate on the Keystone SOC for both the USB2 and USB3 PHY. Otherwise it is just +an NOP PHY driver. Hence this node is referenced as both the usb2 and usb3 +phy node in the USB Glue layer driver node. + +usb_phy: usb_phy@2620738 { + compatible = "ti,keystone-usbphy"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2620738 32>; + status = "disabled"; +}; diff --git a/Documentation/devicetree/bindings/usb/keystone-usb.txt b/Documentation/devicetree/bindings/usb/keystone-usb.txt new file mode 100644 index 000000000000..60527d335b58 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/keystone-usb.txt @@ -0,0 +1,42 @@ +TI Keystone Soc USB Controller + +DWC3 GLUE + +Required properties: + - compatible: should be "ti,keystone-dwc3". + - #address-cells, #size-cells : should be '1' if the device has sub-nodes + with 'reg' property. + - reg : Address and length of the register set for the USB subsystem on + the SOC. + - interrupts : The irq number of this device that is used to interrupt the + MPU. + - ranges: allows valid 1:1 translation between child's address space and + parent's address space. + - clocks: Clock IDs array as required by the controller. + - clock-names: names of clocks correseponding to IDs in the clock property. + +Sub-nodes: +The dwc3 core should be added as subnode to Keystone DWC3 glue. +- dwc3 : + The binding details of dwc3 can be found in: + Documentation/devicetree/bindings/usb/dwc3.txt + +Example: + usb: usb@2680000 { + compatible = "ti,keystone-dwc3"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2680000 0x10000>; + clocks = <&clkusb>; + clock-names = "usb"; + interrupts = ; + ranges; + status = "disabled"; + + dwc3@2690000 { + compatible = "synopsys,dwc3"; + reg = <0x2690000 0x70000>; + interrupts = ; + usb-phy = <&usb_phy>, <&usb_phy>; + }; + }; diff --git a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt index df0933043a5b..3dc9140e3dfb 100644 --- a/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt +++ b/Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt @@ -8,7 +8,12 @@ and additions : Required properties : - compatible : Should be "nvidia,tegra20-ehci". - nvidia,phy : phandle of the PHY that the controller is connected to. - - clocks : Contains a single entry which defines the USB controller's clock. + - clocks : Must contain one entry, for the module clock. + See ../clocks/clock-bindings.txt for details. + - resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names : Must include the following entries: + - usb Optional properties: - nvidia,needs-double-reset : boolean is to be set for some of the Tegra20 diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt index 090e5e22bd2b..c495135115cb 100644 --- a/Documentation/devicetree/bindings/usb/omap-usb.txt +++ b/Documentation/devicetree/bindings/usb/omap-usb.txt @@ -87,6 +87,8 @@ Required properties: e.g. USB3 PHY and SATA PHY on OMAP5. "ti,control-phy-dra7usb2" - if it has power down register like USB2 PHY on DRA7 platform. + "ti,control-phy-am437usb2" - if it has power down register like USB2 PHY on + AM437 platform. - reg : Address and length of the register set for the device. It contains the address of "otghs_control" for control-phy-otghs or "power" register for other types. diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index f29cd78b6698..3f900cd51bf0 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -3,6 +3,7 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. This isn't an exhaustive list, but you should add new prefixes to it before using them to avoid name-space collisions. +active-semi Active-Semi International Inc ad Avionic Design GmbH adi Analog Devices, Inc. aeroflexgaisler Aeroflex Gaisler AB @@ -27,19 +28,25 @@ cortina Cortina Systems, Inc. dallas Maxim Integrated Products (formerly Dallas Semiconductor) davicom DAVICOM Semiconductor, Inc. denx Denx Software Engineering +edt Emerging Display Technologies emmicro EM Microelectronic +epfl Ecole Polytechnique Fédérale de Lausanne epson Seiko Epson Corp. est ESTeem Wireless Modems fsl Freescale Semiconductor GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. gmt Global Mixed-mode Technology, Inc. +gumstix Gumstix, Inc. +haoyu Haoyu Microelectronic Co. Ltd. hisilicon Hisilicon Limited. hp Hewlett Packard ibm International Business Machines (IBM) idt Integrated Device Technologies, Inc. img Imagination Technologies Ltd. intercontrol Inter Control Group +isl Intersil +karo Ka-Ro electronics GmbH lg LG Corporation linux Linux-specific binding lsi LSI Corp. (LSI Logic) @@ -62,6 +69,7 @@ ralink Mediatek/Ralink Technology Corp. ramtron Ramtron International realtek Realtek Semiconductor Corp. renesas Renesas Electronics Corporation +rockchip Fuzhou Rockchip Electronics Co., Ltd samsung Samsung Semiconductor sbs Smart Battery System schindler Schindler @@ -74,6 +82,7 @@ st STMicroelectronics ste ST-Ericsson stericsson ST-Ericsson ti Texas Instruments +tlm Trusted Logic Mobility toshiba Toshiba Corporation toumaz Toumaz v3 V3 Semiconductor diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index b2fb2f5e1922..1f013bd0d320 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt @@ -1364,19 +1364,16 @@ Appendix A - Sample SOC node for MPC8540 phy0: ethernet-phy@0 { interrupts = <5 1>; reg = <0>; - device_type = "ethernet-phy"; }; phy1: ethernet-phy@1 { interrupts = <5 1>; reg = <1>; - device_type = "ethernet-phy"; }; phy3: ethernet-phy@3 { interrupts = <7 1>; reg = <3>; - device_type = "ethernet-phy"; }; }; }; diff --git a/Documentation/driver-model/design-patterns.txt b/Documentation/driver-model/design-patterns.txt new file mode 100644 index 000000000000..ba7b2df64904 --- /dev/null +++ b/Documentation/driver-model/design-patterns.txt @@ -0,0 +1,116 @@ + +Device Driver Design Patterns +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This document describes a few common design patterns found in device drivers. +It is likely that subsystem maintainers will ask driver developers to +conform to these design patterns. + +1. State Container +2. container_of() + + +1. State Container +~~~~~~~~~~~~~~~~~~ + +While the kernel contains a few device drivers that assume that they will +only be probed() once on a certain system (singletons), it is custom to assume +that the device the driver binds to will appear in several instances. This +means that the probe() function and all callbacks need to be reentrant. + +The most common way to achieve this is to use the state container design +pattern. It usually has this form: + +struct foo { + spinlock_t lock; /* Example member */ + (...) +}; + +static int foo_probe(...) +{ + struct foo *foo; + + foo = devm_kzalloc(dev, sizeof(*foo), GFP_KERNEL); + if (!foo) + return -ENOMEM; + spin_lock_init(&foo->lock); + (...) +} + +This will create an instance of struct foo in memory every time probe() is +called. This is our state container for this instance of the device driver. +Of course it is then necessary to always pass this instance of the +state around to all functions that need access to the state and its members. + +For example, if the driver is registering an interrupt handler, you would +pass around a pointer to struct foo like this: + +static irqreturn_t foo_handler(int irq, void *arg) +{ + struct foo *foo = arg; + (...) +} + +static int foo_probe(...) +{ + struct foo *foo; + + (...) + ret = request_irq(irq, foo_handler, 0, "foo", foo); +} + +This way you always get a pointer back to the correct instance of foo in +your interrupt handler. + + +2. container_of() +~~~~~~~~~~~~~~~~~ + +Continuing on the above example we add an offloaded work: + +struct foo { + spinlock_t lock; + struct workqueue_struct *wq; + struct work_struct offload; + (...) +}; + +static void foo_work(struct work_struct *work) +{ + struct foo *foo = container_of(work, struct foo, offload); + + (...) +} + +static irqreturn_t foo_handler(int irq, void *arg) +{ + struct foo *foo = arg; + + queue_work(foo->wq, &foo->offload); + (...) +} + +static int foo_probe(...) +{ + struct foo *foo; + + foo->wq = create_singlethread_workqueue("foo-wq"); + INIT_WORK(&foo->offload, foo_work); + (...) +} + +The design pattern is the same for an hrtimer or something similar that will +return a single argument which is a pointer to a struct member in the +callback. + +container_of() is a macro defined in + +What container_of() does is to obtain a pointer to the containing struct from +a pointer to a member by a simple subtraction using the offsetof() macro from +standard C, which allows something similar to object oriented behaviours. +Notice that the contained member must not be a pointer, but an actual member +for this to work. + +We can see here that we avoid having global pointers to our struct foo * +instance this way, while still keeping the number of parameters passed to the +work function to a single pointer. diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt index 41f41632ee55..07795ec51cde 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.txt @@ -48,7 +48,7 @@ struct platform_driver { struct device_driver driver; }; -Note that probe() should general verify that the specified device hardware +Note that probe() should in general verify that the specified device hardware actually exists; sometimes platform setup code can't be sure. The probing can use device resources, including clocks, and device platform_data. diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt index 1bbdcfcf1f13..46325eb2ea76 100644 --- a/Documentation/dynamic-debug-howto.txt +++ b/Documentation/dynamic-debug-howto.txt @@ -108,6 +108,12 @@ If your query set is big, you can batch them too: ~# cat query-batch-file > /dynamic_debug/control +A another way is to use wildcard. The match rule support '*' (matches +zero or more characters) and '?' (matches exactly one character).For +example, you can match all usb drivers: + + ~# echo "file drivers/usb/* +p" > /dynamic_debug/control + At the syntactical level, a command comprises a sequence of match specifications, followed by a flags change specification. @@ -315,6 +321,9 @@ nullarbor:~ # echo -n 'func svc_process -p' > nullarbor:~ # echo -n 'format "nfsd: READ" +p' > /dynamic_debug/control +// enable messages in files of which the pathes include string "usb" +nullarbor:~ # echo -n '*usb* +p' > /dynamic_debug/control + // enable all messages nullarbor:~ # echo -n '+p' > /dynamic_debug/control diff --git a/Documentation/efi-stub.txt b/Documentation/efi-stub.txt index 44e6bb6ead10..c628788d5b47 100644 --- a/Documentation/efi-stub.txt +++ b/Documentation/efi-stub.txt @@ -20,7 +20,7 @@ The EFI boot stub is enabled with the CONFIG_EFI_STUB kernel option. **** How to install bzImage.efi The bzImage located in arch/x86/boot/bzImage must be copied to the EFI -System Partiion (ESP) and renamed with the extension ".efi". Without +System Partition (ESP) and renamed with the extension ".efi". Without the extension the EFI firmware loader will refuse to execute it. It's not possible to execute bzImage.efi from the usual Linux file systems because EFI firmware doesn't have support for them. diff --git a/Documentation/email-clients.txt b/Documentation/email-clients.txt index 860c29a472ad..e9f5daccbd02 100644 --- a/Documentation/email-clients.txt +++ b/Documentation/email-clients.txt @@ -104,7 +104,7 @@ Then from the "Message" menu item, select insert file and choose your patch. As an added bonus you can customise the message creation toolbar menu and put the "insert file" icon there. -Make the the composer window wide enough so that no lines wrap. As of +Make the composer window wide enough so that no lines wrap. As of KMail 1.13.5 (KDE 4.5.4), KMail will apply word wrapping when sending the email if the lines wrap in the composer window. Having word wrapping disabled in the Options menu isn't enough. Thus, if your patch has very diff --git a/Documentation/extcon/porting-android-switch-class b/Documentation/extcon/porting-android-switch-class index 5377f6317961..49c81caef84d 100644 --- a/Documentation/extcon/porting-android-switch-class +++ b/Documentation/extcon/porting-android-switch-class @@ -50,7 +50,7 @@ so that they are still compatible with legacy userspace processes. Extcon's extended features for switch device drivers with complex features usually required magic numbers in state value of switch_dev. With extcon, such magic numbers that - support multiple cables ( + support multiple cables are no more required or supported. 1. Define cable names at edev->supported_cable. 2. (Recommended) remove print_state callback. @@ -114,11 +114,8 @@ exclusive, the two cables cannot be in ATTACHED state simulteneously. ****** ABI Location - If "CONFIG_ANDROID" is enabled and "CONFIG_ANDROID_SWITCH" is -disabled, /sys/class/switch/* are created as symbolic links to -/sys/class/extcon/*. Because CONFIG_ANDROID_SWITCH creates -/sys/class/switch directory, we disable symboling linking if -CONFIG_ANDROID_SWITCH is enabled. + If "CONFIG_ANDROID" is enabled, /sys/class/switch/* are created +as symbolic links to /sys/class/extcon/*. The two files of switch class, name and state, are provided with extcon, too. When the multistate support (STEP 2 of CHAPTER 1.) is diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index 8042050eb265..632211cbdd56 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX @@ -10,24 +10,32 @@ afs.txt - info and examples for the distributed AFS (Andrew File System) fs. affs.txt - info and mount options for the Amiga Fast File System. +autofs4-mount-control.txt + - info on device control operations for autofs4 module. automount-support.txt - information about filesystem automount support. befs.txt - information about the BeOS filesystem for Linux. bfs.txt - info for the SCO UnixWare Boot Filesystem (BFS). +btrfs.txt + - info for the BTRFS filesystem. +caching/ + - directory containing filesystem cache documentation. ceph.txt - - info for the Ceph Distributed File System -cifs.txt - - description of the CIFS filesystem. + - info for the Ceph Distributed File System. +cifs/ + - directory containing CIFS filesystem documentation and example code. coda.txt - description of the CODA filesystem. configfs/ - directory containing configfs documentation and example code. cramfs.txt - info on the cram filesystem for small storage (ROMs etc). -dentry-locking.txt - - info on the RCU-based dcache locking model. +debugfs.txt + - info on the debugfs filesystem. +devpts.txt + - info on the devpts filesystem. directory-locking - info about the locking scheme used for directory operations. dlmfs.txt @@ -35,7 +43,7 @@ dlmfs.txt dnotify.txt - info about directory notification in Linux. dnotify_test.c - - example program for dnotify + - example program for dnotify. ecryptfs.txt - docs on eCryptfs: stacked cryptographic filesystem for Linux. efivarfs.txt @@ -48,12 +56,18 @@ ext3.txt - info, mount options and specifications for the Ext3 filesystem. ext4.txt - info, mount options and specifications for the Ext4 filesystem. -files.txt - - info on file management in the Linux kernel. f2fs.txt - info and mount options for the F2FS filesystem. +fiemap.txt + - info on fiemap ioctl. +files.txt + - info on file management in the Linux kernel. fuse.txt - info on the Filesystem in User SpacE including mount options. +gfs2-glocks.txt + - info on the Global File System 2 - Glock internal locking rules. +gfs2-uevents.txt + - info on the Global File System 2 - uevents. gfs2.txt - info on the Global File System 2. hfs.txt @@ -84,40 +98,58 @@ ntfs.txt - info and mount options for the NTFS filesystem (Windows NT). ocfs2.txt - info and mount options for the OCFS2 clustered filesystem. +omfs.txt + - info on the Optimized MPEG FileSystem. +path-lookup.txt + - info on path walking and name lookup locking. +pohmelfs/ + - directory containing pohmelfs filesystem documentation. porting - various information on filesystem porting. proc.txt - info on Linux's /proc filesystem. +qnx6.txt + - info on the QNX6 filesystem. +quota.txt + - info on Quota subsystem. ramfs-rootfs-initramfs.txt - info on the 'in memory' filesystems ramfs, rootfs and initramfs. -reiser4.txt - - info on the Reiser4 filesystem based on dancing tree algorithms. relay.txt - info on relay, for efficient streaming from kernel to user space. romfs.txt - description of the ROMFS filesystem. seq_file.txt - - how to use the seq_file API + - how to use the seq_file API. sharedsubtree.txt - a description of shared subtrees for namespaces. spufs.txt - info and mount options for the SPU filesystem used on Cell. +squashfs.txt + - info on the squashfs filesystem. sysfs-pci.txt - info on accessing PCI device resources through sysfs. +sysfs-tagging.txt + - info on sysfs tagging to avoid duplicates. sysfs.txt - info on sysfs, a ram-based filesystem for exporting kernel objects. sysv-fs.txt - info on the SystemV/V7/Xenix/Coherent filesystem. tmpfs.txt - info on tmpfs, a filesystem that holds all files in virtual memory. +ubifs.txt + - info on the Unsorted Block Images FileSystem. udf.txt - info and mount options for the UDF filesystem. ufs.txt - info on the ufs filesystem. vfat.txt - - info on using the VFAT filesystem used in Windows NT and Windows 95 + - info on using the VFAT filesystem used in Windows NT and Windows 95. vfs.txt - - overview of the Virtual File System + - overview of the Virtual File System. +xfs-delayed-logging-design.txt + - info on the XFS Delayed Logging Design. +xfs-self-describing-metadata.txt + - info on XFS Self Describing Metadata. xfs.txt - info and mount options for the XFS filesystem. xip.txt diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt index 2c0321442845..fec7144e817c 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt @@ -69,10 +69,14 @@ OPTIONS offering several exported file systems. cache=mode specifies a caching policy. By default, no caches are used. + none = default no cache policy, metadata and data + alike are synchronous. loose = no attempts are made at consistency, intended for exclusive, read-only mounts - fscache = use FS-Cache for a persistent, read-only + fscache = use FS-Cache for a persistent, read-only cache backend. + mmap = minimal cache that is only used for read-write + mmap. Northing else is cached, like cache=none debug=n specifies debug level. The debug level is a bitmask. 0x01 = display verbose error messages @@ -147,8 +151,7 @@ on sourceforge (http://sourceforge.net/projects/v9fs). News and other information is maintained on a Wiki. (http://sf.net/apps/mediawiki/v9fs/index.php). -Bug reports may be issued through the kernel.org bugzilla -(http://bugzilla.kernel.org) +Bug reports are best issued via the mailing list. For more information on the Plan 9 Operating System check out http://plan9.bell-labs.com/plan9 @@ -156,11 +159,3 @@ http://plan9.bell-labs.com/plan9 For information on Plan 9 from User Space (Plan 9 applications and libraries ported to Linux/BSD/OSX/etc) check out http://swtch.com/plan9 - -STATUS -====== - -The 2.6 kernel support is working on PPC and x86. - -PLEASE USE THE KERNEL BUGZILLA TO REPORT PROBLEMS. (http://bugzilla.kernel.org) - diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index fe7afe225381..5b0c083d7c0e 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -544,7 +544,7 @@ like the ->fault() handler, but simply return with VM_FAULT_NOPAGE, which will cause the VM to retry the fault. ->access() is called when get_user_pages() fails in -acces_process_vm(), typically used to debug a process through +access_process_vm(), typically used to debug a process through /proc/pid/mem or ptrace. This function is needed only for VM_IO | VM_PFNMAP VMAs. diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index a3fe811bbdbc..b8d284975f0f 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -120,6 +120,8 @@ active_logs=%u Support configuring the number of active logs. In the disable_ext_identify Disable the extension list configured by mkfs, so f2fs does not aware of cold files such as media files. inline_xattr Enable the inline xattrs feature. +inline_data Enable the inline data feature: New created small(<~3.4k) + files can be written into inode block. ================================================================================ DEBUGFS ENTRIES @@ -171,6 +173,28 @@ Files in /sys/fs/f2fs/ conduct checkpoint to reclaim the prefree segments to free segments. By default, 100 segments, 200MB. + max_small_discards This parameter controls the number of discard + commands that consist small blocks less than 2MB. + The candidates to be discarded are cached until + checkpoint is triggered, and issued during the + checkpoint. By default, it is disabled with 0. + + ipu_policy This parameter controls the policy of in-place + updates in f2fs. There are five policies: + 0: F2FS_IPU_FORCE, 1: F2FS_IPU_SSR, + 2: F2FS_IPU_UTIL, 3: F2FS_IPU_SSR_UTIL, + 4: F2FS_IPU_DISABLE. + + min_ipu_util This parameter controls the threshold to trigger + in-place-updates. The number indicates percentage + of the filesystem utilization, and used by + F2FS_IPU_UTIL and F2FS_IPU_SSR_UTIL policies. + + max_victim_search This parameter controls the number of trials to + find a victim segment when conducting SSR and + cleaning operations. The default value is 4096 + which covers 8GB block address range. + ================================================================================ USAGE ================================================================================ diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt index 873a2ab2e9f8..06887d46ccf2 100644 --- a/Documentation/filesystems/nilfs2.txt +++ b/Documentation/filesystems/nilfs2.txt @@ -81,6 +81,62 @@ nodiscard(*) The discard/TRIM commands are sent to the underlying block device when blocks are freed. This is useful for SSD devices and sparse/thinly-provisioned LUNs. +Ioctls +====== + +There is some NILFS2 specific functionality which can be accessed by applications +through the system call interfaces. The list of all NILFS2 specific ioctls are +shown in the table below. + +Table of NILFS2 specific ioctls +.............................................................................. + Ioctl Description + NILFS_IOCTL_CHANGE_CPMODE Change mode of given checkpoint between + checkpoint and snapshot state. This ioctl is + used in chcp and mkcp utilities. + + NILFS_IOCTL_DELETE_CHECKPOINT Remove checkpoint from NILFS2 file system. + This ioctl is used in rmcp utility. + + NILFS_IOCTL_GET_CPINFO Return info about requested checkpoints. This + ioctl is used in lscp utility and by + nilfs_cleanerd daemon. + + NILFS_IOCTL_GET_CPSTAT Return checkpoints statistics. This ioctl is + used by lscp, rmcp utilities and by + nilfs_cleanerd daemon. + + NILFS_IOCTL_GET_SUINFO Return segment usage info about requested + segments. This ioctl is used in lssu, + nilfs_resize utilities and by nilfs_cleanerd + daemon. + + NILFS_IOCTL_GET_SUSTAT Return segment usage statistics. This ioctl + is used in lssu, nilfs_resize utilities and + by nilfs_cleanerd daemon. + + NILFS_IOCTL_GET_VINFO Return information on virtual block addresses. + This ioctl is used by nilfs_cleanerd daemon. + + NILFS_IOCTL_GET_BDESCS Return information about descriptors of disk + block numbers. This ioctl is used by + nilfs_cleanerd daemon. + + NILFS_IOCTL_CLEAN_SEGMENTS Do garbage collection operation in the + environment of requested parameters from + userspace. This ioctl is used by + nilfs_cleanerd daemon. + + NILFS_IOCTL_SYNC Make a checkpoint. This ioctl is used in + mkcp utility. + + NILFS_IOCTL_RESIZE Resize NILFS2 volume. This ioctl is used + by nilfs_resize utility. + + NILFS_IOCTL_SET_ALLOC_RANGE Define lower limit of segments in bytes and + upper limit of segments in bytes. This ioctl + is used by nilfs_resize utility. + NILFS2 usage ============ diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 22d89aa37218..31f76178c987 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -547,7 +547,7 @@ Table 1-5: Kernel info in /proc sys See chapter 2 sysvipc Info of SysVIPC Resources (msg, sem, shm) (2.4) tty Info of tty drivers - uptime System uptime + uptime Wall clock since boot, combined idle time of all cpus version Kernel version video bttv info of video resources (2.4) vmallocinfo Show vmalloced areas @@ -767,6 +767,7 @@ The "Locked" indicates whether the mapping is locked in memory or not. MemTotal: 16344972 kB MemFree: 13634064 kB +MemAvailable: 14836172 kB Buffers: 3656 kB Cached: 1195708 kB SwapCached: 0 kB @@ -799,6 +800,14 @@ AnonHugePages: 49152 kB MemTotal: Total usable ram (i.e. physical ram minus a few reserved bits and the kernel binary code) MemFree: The sum of LowFree+HighFree +MemAvailable: An estimate of how much memory is available for starting new + applications, without swapping. Calculated from MemFree, + SReclaimable, the size of the file LRU lists, and the low + watermarks in each zone. + The estimate takes into account that the system needs some + page cache to function well, and that not all reclaimable + slab will be reclaimable, due to items being in use. The + impact of those factors will vary from system to system. Buffers: Relatively temporary storage for raw disk blocks shouldn't get tremendously large (20MB or so) Cached: in-memory cache for files read from the disk (the diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index a6619b7064b9..b35a64b82f9e 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -108,12 +108,12 @@ static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo); is equivalent to doing: static struct device_attribute dev_attr_foo = { - .attr = { + .attr = { .name = "foo", .mode = S_IWUSR | S_IRUGO, - .show = show_foo, - .store = store_foo, }, + .show = show_foo, + .store = store_foo, }; diff --git a/Documentation/gpio/board.txt b/Documentation/gpio/board.txt index 0d03506f2cc5..ba169faad5c6 100644 --- a/Documentation/gpio/board.txt +++ b/Documentation/gpio/board.txt @@ -72,10 +72,11 @@ where - chip_label is the label of the gpiod_chip instance providing the GPIO - chip_hwnum is the hardware number of the GPIO within the chip - - dev_id is the identifier of the device that will make use of this GPIO. If - NULL, the GPIO will be available to all devices. + - dev_id is the identifier of the device that will make use of this GPIO. It + can be NULL, in which case it will be matched for calls to gpiod_get() + with a NULL device. - con_id is the name of the GPIO function from the device point of view. It - can be NULL. + can be NULL, in which case it will match any function. - idx is the index of the GPIO within the function. - flags is defined to specify the following properties: * GPIOF_ACTIVE_LOW - to configure the GPIO as active-low @@ -86,18 +87,23 @@ In the future, these flags might be extended to support more properties. Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0. -A lookup table can then be defined as follows: +A lookup table can then be defined as follows, with an empty entry defining its +end: - struct gpiod_lookup gpios_table[] = { - GPIO_LOOKUP_IDX("gpio.0", 15, "foo.0", "led", 0, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX("gpio.0", 16, "foo.0", "led", 1, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP_IDX("gpio.0", 17, "foo.0", "led", 2, GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio.0", 1, "foo.0", "power", GPIO_ACTIVE_LOW), - }; +struct gpiod_lookup_table gpios_table = { + .dev_id = "foo.0", + .table = { + GPIO_LOOKUP_IDX("gpio.0", 15, "led", 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio.0", 16, "led", 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio.0", 17, "led", 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio.0", 1, "power", GPIO_ACTIVE_LOW), + { }, + }, +}; And the table can be added by the board code as follows: - gpiod_add_table(gpios_table, ARRAY_SIZE(gpios_table)); + gpiod_add_lookup_table(&gpios_table); The driver controlling "foo.0" will then be able to obtain its GPIOs as follows: diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index 07c74a3765a0..e42f77d8d4ca 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt @@ -38,7 +38,11 @@ device that displays digits), an additional index argument can be specified: const char *con_id, unsigned int idx) Both functions return either a valid GPIO descriptor, or an error code checkable -with IS_ERR(). They will never return a NULL pointer. +with IS_ERR() (they will never return a NULL pointer). -ENOENT will be returned +if and only if no GPIO has been assigned to the device/function/index triplet, +other error codes are used for cases where a GPIO has been assigned but an error +occured while trying to acquire it. This is useful to discriminate between mere +errors and an absence of GPIO for optional GPIO parameters. Device-managed variants of these functions are also defined: diff --git a/Documentation/i2c/fault-codes b/Documentation/i2c/fault-codes index 045765c0b9b5..47c25abb7d52 100644 --- a/Documentation/i2c/fault-codes +++ b/Documentation/i2c/fault-codes @@ -64,9 +64,6 @@ EINVAL detected before any I/O operation was started. Use a more specific fault code when you can. - One example would be a driver trying an SMBus Block Write - with block size outside the range of 1-32 bytes. - EIO This rather vague error means something went wrong when performing an I/O operation. Use a more specific fault diff --git a/Documentation/input/gamepad.txt b/Documentation/input/gamepad.txt index 31bb6a4029ef..3f6d8a5e9cdc 100644 --- a/Documentation/input/gamepad.txt +++ b/Documentation/input/gamepad.txt @@ -68,7 +68,7 @@ features that you need, first. How each feature is mapped is described below. Legacy drivers often don't comply to these rules. As we cannot change them for backwards-compatibility reasons, you need to provide fixup mappings in user-space yourself. Some of them might also provide module-options that -change the mappings so you can adivce users to set these. +change the mappings so you can advise users to set these. All new gamepads are supposed to comply with this mapping. Please report any bugs, if they don't. @@ -150,10 +150,10 @@ Menu-Pad: BTN_START Many pads also have a third button which is branded or has a special symbol and meaning. Such buttons are mapped as BTN_MODE. Examples are the Nintendo - "HOME" button, the XBox "X"-button or Sony "P" button. + "HOME" button, the XBox "X"-button or Sony "PS" button. Rumble: - Rumble is adverticed as FF_RUMBLE. + Rumble is advertised as FF_RUMBLE. ---------------------------------------------------------------------------- Written 2013 by David Herrmann diff --git a/Documentation/input/joystick-api.txt b/Documentation/input/joystick-api.txt index c507330740cd..943b18eac918 100644 --- a/Documentation/input/joystick-api.txt +++ b/Documentation/input/joystick-api.txt @@ -16,14 +16,14 @@ joystick. By default, the device is opened in blocking mode. - int fd = open ("/dev/js0", O_RDONLY); + int fd = open ("/dev/input/js0", O_RDONLY); 2. Event Reading ~~~~~~~~~~~~~~~~ struct js_event e; - read (fd, &e, sizeof(struct js_event)); + read (fd, &e, sizeof(e)); where js_event is defined as @@ -34,8 +34,8 @@ where js_event is defined as __u8 number; /* axis/button number */ }; -If the read is successful, it will return sizeof(struct js_event), unless -you wanted to read more than one event per read as described in section 3.1. +If the read is successful, it will return sizeof(e), unless you wanted to read +more than one event per read as described in section 3.1. 2.1 js_event.type @@ -99,9 +99,9 @@ may work well if you handle JS_EVENT_INIT events separately, if ((js_event.type & ~JS_EVENT_INIT) == JS_EVENT_BUTTON) { if (js_event.value) - buttons_state |= (1 << js_event.number); - else - buttons_state &= ~(1 << js_event.number); + buttons_state |= (1 << js_event.number); + else + buttons_state &= ~(1 << js_event.number); } is much safer since it can't lose sync with the driver. As you would @@ -144,14 +144,14 @@ all events on the queue (that is, until you get a -1). For example, while (1) { - while (read (fd, &e, sizeof(struct js_event)) > 0) { - process_event (e); - } - /* EAGAIN is returned when the queue is empty */ - if (errno != EAGAIN) { - /* error */ - } - /* do something interesting with processed events */ + while (read (fd, &e, sizeof(e)) > 0) { + process_event (e); + } + /* EAGAIN is returned when the queue is empty */ + if (errno != EAGAIN) { + /* error */ + } + /* do something interesting with processed events */ } One reason for emptying the queue is that if it gets full you'll start @@ -181,7 +181,7 @@ at a time using the typical read(2) functionality. For that, you would replace the read above with something like struct js_event mybuffer[0xff]; - int i = read (fd, mybuffer, sizeof(struct mybuffer)); + int i = read (fd, mybuffer, sizeof(mybuffer)); In this case, read would return -1 if the queue was empty, or some other value in which the number of events read would be i / @@ -269,9 +269,9 @@ The driver offers backward compatibility, though. Here's a quick summary: struct JS_DATA_TYPE js; while (1) { if (read (fd, &js, JS_RETURN) != JS_RETURN) { - /* error */ - } - usleep (1000); + /* error */ + } + usleep (1000); } As you can figure out from the example, the read returns immediately, diff --git a/Documentation/input/joystick.txt b/Documentation/input/joystick.txt index 304262bb661a..8d027dc86c1f 100644 --- a/Documentation/input/joystick.txt +++ b/Documentation/input/joystick.txt @@ -116,7 +116,7 @@ your needs: For testing the joystick driver functionality, there is the jstest program in the utilities package. You run it by typing: - jstest /dev/js0 + jstest /dev/input/js0 And it should show a line with the joystick values, which update as you move the stick, and press its buttons. The axes should all be zero when the @@ -136,7 +136,7 @@ joystick should be autocalibrated by the driver automagically. However, with some analog joysticks, that either do not use linear resistors, or if you want better precision, you can use the jscal program - jscal -c /dev/js0 + jscal -c /dev/input/js0 included in the joystick package to set better correction coefficients than what the driver would choose itself. @@ -145,7 +145,7 @@ what the driver would choose itself. calibration using the jstest command, and if you do, you then can save the correction coefficients into a file - jscal -p /dev/js0 > /etc/joystick.cal + jscal -p /dev/input/js0 > /etc/joystick.cal And add a line to your rc script executing that file @@ -556,7 +556,7 @@ interface, and "old" for the "0.x" interface. You run it by typing: 5. FAQ ~~~~~~ -Q: Running 'jstest /dev/js0' results in "File not found" error. What's the +Q: Running 'jstest /dev/input/js0' results in "File not found" error. What's the cause? A: The device files don't exist. Create them (see section 2.2). diff --git a/Documentation/io-mapping.txt b/Documentation/io-mapping.txt index 473e43b2d588..5ca78426f54c 100644 --- a/Documentation/io-mapping.txt +++ b/Documentation/io-mapping.txt @@ -38,7 +38,7 @@ maps are more efficient: void io_mapping_unmap_atomic(void *vaddr) - 'vaddr' must be the the value returned by the last + 'vaddr' must be the value returned by the last io_mapping_map_atomic_wc call. This unmaps the specified page and allows the task to sleep once again. diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO index 8148a47fc70e..0091a8215ac1 100644 --- a/Documentation/ja_JP/HOWTO +++ b/Documentation/ja_JP/HOWTO @@ -149,7 +149,7 @@ linux-api@ver.kernel.org に送ることを勧めます。 この他にパッチを作る方法についてのよくできた記述は- "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt "Linux kernel patch submission format" http://linux.yyz.us/patch-format.html @@ -622,7 +622,7 @@ Linux カーネルコミュニティは、一度に大量のコードの塊を これについて全てがどのようにあるべきかについての詳細は、以下のドキュメ ントの ChangeLog セクションを見てください- "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt これらのどれもが、時にはとても困難です。これらの慣例を完璧に実施するに は数年かかるかもしれません。これは継続的な改善のプロセスであり、そのた diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 50680a59a2ff..be6ba33d4ff1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -343,6 +343,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. no: ACPI OperationRegions are not marked as reserved, no further checks are performed. + acpi_no_memhotplug [ACPI] Disable memory hotplug. Useful for kdump + kernels. + add_efi_memmap [EFI; X86] Include EFI memory map in kernel's map of available physical RAM. @@ -463,6 +466,22 @@ bytes respectively. Such letter suffixes can also be entirely omitted. atkbd.softrepeat= [HW] Use software keyboard repeat + audit= [KNL] Enable the audit sub-system + Format: { "0" | "1" } (0 = disabled, 1 = enabled) + 0 - kernel audit is disabled and can not be enabled + until the next reboot + unset - kernel audit is initialized but disabled and + will be fully enabled by the userspace auditd. + 1 - kernel audit is initialized and partially enabled, + storing at most audit_backlog_limit messages in + RAM until it is fully enabled by the userspace + auditd. + Default: unset + + audit_backlog_limit= [KNL] Set the audit queue size limit. + Format: (must be >=0) + Default: 64 + baycom_epp= [HW,AX25] Format: , @@ -515,7 +534,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. cgroup_disable= [KNL] Disable a particular controller Format: {name of the controller(s) to disable} - {Currently supported controllers - "memory"} + The effects of cgroup_disable=foo are: + - foo isn't auto-mounted if you mount all cgroups in + a single hierarchy + - foo isn't visible as an individually mountable + subsystem + {Currently only "memory" controller deal with this and + cut the overhead, others just disable the usage. So + only cgroup_disable=memory is actually worthy} checkreqprot [SELINUX] Set initial checkreqprot flag value. Format: { "0" | "1" } @@ -774,6 +800,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted. disable= [IPV6] See Documentation/networking/ipv6.txt. + disable_cpu_apicid= [X86,APIC,SMP] + Format: + The number of initial APIC ID for the + corresponding CPU to be disabled at boot, + mostly used for the kdump 2nd kernel to + disable BSP to wake up multiple CPUs without + causing system reset or hang due to sending + INIT from AP to BSP. + disable_ddw [PPC/PSERIES] Disable Dynamic DMA Window support. Use this if to workaround buggy firmware. @@ -881,6 +916,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. The xen output can only be used by Xen PV guests. + edac_report= [HW,EDAC] Control how to report EDAC event + Format: {"on" | "off" | "force"} + on: enable EDAC to report H/W event. May be overridden + by other higher priority error reporting module. + off: disable H/W event reporting through EDAC. + force: enforce the use of EDAC to report H/W event. + default: on. + ekgdboc= [X86,KGDB] Allow early kernel console debugging ekgdboc=kbd @@ -890,6 +933,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. edd= [EDD] Format: {"off" | "on" | "skip[mbr]"} + efi= [EFI] + Format: { "old_map" } + old_map [X86-64]: switch to the old ioremap-based EFI + runtime services mapping. 32-bit still uses this one by + default. + efi_no_storage_paranoia [EFI; X86] Using this parameter you can use more than 50% of your efi variable storage. Use this parameter only if @@ -1013,7 +1062,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. debugfs files are removed at module unload time. gpt [EFI] Forces disk with valid GPT signature but - invalid Protective MBR to be treated as GPT. + invalid Protective MBR to be treated as GPT. If the + primary GPT is corrupted, it enables the backup/alternate + GPT to be used instead. grcan.enable0= [HW] Configuration of physical interface 0. Determines the "Enable 0" bit of the configuration register. @@ -1415,6 +1466,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Valid arguments: on, off Default: on + kmemcheck= [X86] Boot-time kmemcheck enable/disable/one-shot mode + Valid arguments: 0, 1, 2 + kmemcheck=0 (disabled) + kmemcheck=1 (enabled) + kmemcheck=2 (one-shot mode) + Default: 2 (one-shot mode) + kstack=N [X86] Print N words from the kernel stack in oops dumps. @@ -1529,6 +1587,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. * atapi_dmadir: Enable ATAPI DMADIR bridge support + * disable: Disable this device. + If there are multiple matching configurations changing the same attribute, the last one is used. @@ -1992,6 +2052,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. noapic [SMP,APIC] Tells the kernel to not make use of any IOAPICs that may be present in the system. + nokaslr [X86] + Disable kernel base offset ASLR (Address Space + Layout Randomization) if built into the kernel. + noautogroup Disable scheduler automatic task group creation. nobats [PPC] Do not use BATs for mapping kernel lowmem @@ -2625,7 +2689,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. for RCU-preempt, and "s" for RCU-sched, and "N" is the CPU number. This reduces OS jitter on the offloaded CPUs, which can be useful for HPC and - real-time workloads. It can also improve energy efficiency for asymmetric multiprocessors. @@ -2641,8 +2704,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. periodically wake up to do the polling. rcutree.blimit= [KNL] - Set maximum number of finished RCU callbacks to process - in one batch. + Set maximum number of finished RCU callbacks to + process in one batch. rcutree.rcu_fanout_leaf= [KNL] Increase the number of CPUs assigned to each @@ -2661,8 +2724,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. value is one, and maximum value is HZ. rcutree.qhimark= [KNL] - Set threshold of queued - RCU callbacks over which batch limiting is disabled. + Set threshold of queued RCU callbacks beyond which + batch limiting is disabled. rcutree.qlowmark= [KNL] Set threshold of queued RCU callbacks below which diff --git a/Documentation/kmsg/s390/zcrypt b/Documentation/kmsg/s390/zcrypt new file mode 100644 index 000000000000..7fb2087409d6 --- /dev/null +++ b/Documentation/kmsg/s390/zcrypt @@ -0,0 +1,20 @@ +/*? + * Text: "Cryptographic device %x failed and was set offline\n" + * Severity: Error + * Parameter: + * @1: device index + * Description: + * A cryptographic device failed to process a cryptographic request. + * The cryptographic device driver could not correct the error and + * set the device offline. The application that issued the + * request received an indication that the request has failed. + * User action: + * Use the lszcrypt command to confirm that the cryptographic + * hardware is still configured to your LPAR or z/VM guest virtual + * machine. If the device is available to your Linux instance the + * command output contains a line that begins with 'card', + * where is the two-digit decimal number in the message text. + * After ensuring that the device is available, use the chzcrypt command to + * set it online again. + * If the error persists, contact your support organization. + */ diff --git a/Documentation/ko_KR/HOWTO b/Documentation/ko_KR/HOWTO index 680e64635958..dc2ff8f611e0 100644 --- a/Documentation/ko_KR/HOWTO +++ b/Documentation/ko_KR/HOWTO @@ -122,7 +122,7 @@ mtk.manpages@gmail.com의 메인테이너에게 보낼 것을 권장한다. 올바른 패치들을 만드는 법에 관한 훌륭한 다른 문서들이 있다. "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt "Linux kernel patch submission format" http://linux.yyz.us/patch-format.html @@ -213,7 +213,7 @@ Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, H 것은 Linux Cross-Reference project이며 그것은 자기 참조 방식이며 소스코드를 인덱스된 웹 페이지들의 형태로 보여준다. 최신의 멋진 커널 코드 저장소는 다음을 통하여 참조할 수 있다. - http://users.sosdg.org/~qiyong/lxr/ + http://lxr.linux.no/+trees 개발 프로세스 @@ -222,20 +222,20 @@ Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, H 리눅스 커널 개발 프로세스는 현재 몇몇 다른 메인 커널 "브랜치들"과 서브시스템에 특화된 커널 브랜치들로 구성된다. 몇몇 다른 메인 브랜치들은 다음과 같다. - - main 2.6.x 커널 트리 - - 2.6.x.y - 안정된 커널 트리 - - 2.6.x -git 커널 패치들 - - 2.6.x -mm 커널 패치들 + - main 3.x 커널 트리 + - 3.x.y - 안정된 커널 트리 + - 3.x -git 커널 패치들 - 서브시스템을 위한 커널 트리들과 패치들 + - 3.x - 통합 테스트를 위한 next 커널 트리 -2.6.x 커널 트리 +3.x 커널 트리 --------------- -2.6.x 커널들은 Linux Torvalds가 관리하며 kernel.org의 pub/linux/kernel/v2.6/ +3.x 커널들은 Linux Torvalds가 관리하며 kernel.org의 pub/linux/kernel/v3.x/ 디렉토리에서 참조될 수 있다.개발 프로세스는 다음과 같다. - 새로운 커널이 배포되자마자 2주의 시간이 주어진다. 이 기간동은 메인테이너들은 큰 diff들을 Linus에게 제출할 수 있다. 대개 이 패치들은 - 몇 주 동안 -mm 커널내에 이미 있었던 것들이다. 큰 변경들을 제출하는 데 + 몇 주 동안 -next 커널내에 이미 있었던 것들이다. 큰 변경들을 제출하는 데 선호되는 방법은 git(커널의 소스 관리 툴, 더 많은 정보들은 http://git.or.cz/ 에서 참조할 수 있다)를 사용하는 것이지만 순수한 패치파일의 형식으로 보내는 것도 무관하다. @@ -262,20 +262,20 @@ Andrew Morton의 글이 있다. 버그의 상황에 따라 배포되는 것이지 미리정해 놓은 시간에 따라 배포되는 것은 아니기 때문이다." -2.6.x.y - 안정 커널 트리 +3.x.y - 안정 커널 트리 ------------------------ -4 자리 숫자로 이루어진 버젼의 커널들은 -stable 커널들이다. 그것들은 2.6.x +3 자리 숫자로 이루어진 버젼의 커널들은 -stable 커널들이다. 그것들은 3.x 커널에서 발견된 큰 회귀들이나 보안 문제들 중 비교적 작고 중요한 수정들을 포함한다. 이것은 가장 최근의 안정적인 커널을 원하는 사용자에게 추천되는 브랜치이며, 개발/실험적 버젼을 테스트하는 것을 돕고자 하는 사용자들과는 별로 관련이 없다. -어떤 2.6.x.y 커널도 사용할 수 없다면 그때는 가장 높은 숫자의 2.6.x +어떤 3.x.y 커널도 사용할 수 없다면 그때는 가장 높은 숫자의 3.x 커널이 현재의 안정 커널이다. -2.6.x.y는 "stable" 팀에 의해 관리되며 거의 매번 격주로 +3.x.y는 "stable" 팀에 의해 관리되며 거의 매번 격주로 배포된다. 커널 트리 문서들 내에 Documentation/stable_kernel_rules.txt 파일은 어떤 @@ -283,84 +283,46 @@ Andrew Morton의 글이 있다. 진행되는지를 설명한다. -2.6.x -git 패치들 +3.x -git 패치들 ------------------ git 저장소(그러므로 -git이라는 이름이 붙음)에는 날마다 관리되는 Linus의 커널 트리의 snapshot 들이 있다. 이 패치들은 일반적으로 날마다 배포되며 Linus의 트리의 현재 상태를 나타낸다. 이 패치들은 정상적인지 조금도 살펴보지 않고 자동적으로 생성된 것이므로 -rc 커널들 보다도 더 실험적이다. -2.6.x -mm 커널 패치들 ---------------------- -Andrew Morton에 의해 배포된 실험적인 커널 패치들이다. Andrew는 모든 다른 -서브시스템 커널 트리와 패치들을 가져와서 리눅스 커널 메일링 리스트로 -온 많은 패치들과 한데 묶는다. 이 트리는 새로운 기능들과 패치들을 위한 -장소를 제공하는 역할을 한다. 하나의 패치가 -mm에 한동안 있으면서 그 가치가 -증명되게 되면 Andrew나 서브시스템 메인테이너는 그것을 메인라인에 포함시키기 -위하여 Linus에게 보낸다. - -커널 트리에 포함하고 싶은 모든 새로운 패치들은 Linus에게 보내지기 전에 --mm 트리에서 테스트를 하는 것을 적극 추천한다. - -이 커널들은 안정되게 사용할 시스템에서에 실행하는 것은 적합하지 않으며 -다른 브랜치들의 어떤 것들보다 위험하다. - -여러분이 커널 개발 프로세스를 돕길 원한다면 이 커널 배포들을 사용하고 -테스트한 후 어떤 문제를 발견하거나 또는 모든 것이 잘 동작한다면 리눅스 -커널 메일링 리스트로 피드백을 해달라. - -이 커널들은 일반적으로 모든 다른 실험적인 패치들과 배포될 당시의 -사용가능한 메인라인 -git 커널들의 몇몇 변경을 포함한다. - --mm 커널들은 정해진 일정대로 배포되지 않는다. 하지만 대개 몇몇 -mm 커널들은 -각 -rc 커널(1부터 3이 흔함) 사이에서 배포된다. - 서브시스템 커널 트리들과 패치들 ------------------------------- -많은 다른 커널 서브시스템 개발자들은 커널의 다른 부분들에서 무슨 일이 -일어나고 있는지를 볼수 있도록 그들의 개발 트리를 공개한다. 이 트리들은 -위에서 설명하였던 것 처럼 -mm 커널 배포들로 합쳐진다. +다양한 커널 서브시스템의 메인테이너들 --- 그리고 많은 커널 서브시스템 개발자들 +--- 은 그들의 현재 개발 상태를 소스 저장소로 노출한다. 이를 통해 다른 사람들도 +커널의 다른 영역에 어떤 변화가 이루어지고 있는지 알 수 있다. 급속히 개발이 +진행되는 영역이 있고 그렇지 않은 영역이 있으므로, 개발자는 다른 개발자가 제출한 +수정 사항과 자신의 수정사항의 충돌이나 동일한 일을 동시에 두사람이 따로 +진행하는 사태를 방지하기 위해 급속히 개발이 진행되고 있는 영역에 작업의 +베이스를 맞춰줄 것이 요구된다. -다음은 활용가능한 커널 트리들을 나열한다. - git trees: - - Kbuild development tree, Sam Ravnborg < sam@ravnborg.org> - git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git +대부분의 이러한 저장소는 git 트리지만, git이 아닌 SCM으로 관리되거나, quilt +시리즈로 제공되는 패치들도 존재한다. 이러한 서브시스템 저장소들은 MAINTAINERS +파일에 나열되어 있다. 대부분은 http://git.kernel.org 에서 볼 수 있다. - - ACPI development tree, Len Brown - git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git +제안된 패치는 서브시스템 트리에 커밋되기 전에 메일링 리스트를 통해 +리뷰된다(아래의 관련 섹션을 참고하기 바란다). 일부 커널 서브시스템의 경우, 이 +리뷰 프로세스는 patchwork라는 도구를 통해 추적된다. patchwork은 등록된 패치와 +패치에 대한 코멘트, 패치의 버전을 볼 수 있는 웹 인터페이스를 제공하고, +메인테이너는 패치를 리뷰 중, 리뷰 통과, 또는 반려됨으로 표시할 수 있다. +대부분의 이러한 patchwork 사이트는 http://patchwork.kernel.org/ 또는 +http://patchwork.ozlabs.org/ 에 나열되어 있다. - - Block development tree, Jens Axboe - git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git +3.x - 통합 테스트를 위한 next 커널 트리 +----------------------------------------- +서브시스템 트리들의 변경사항들은 mainline 3.x 트리로 들어오기 전에 통합 +테스트를 거쳐야 한다. 이런 목적으로, 모든 서브시스템 트리의 변경사항을 거의 +매일 받아가는 특수한 테스트 저장소가 존재한다: + http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git + http://linux.f-seidel.de/linux-next/pmwiki/ - - DRM development tree, Dave Airlie - git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git - - - ia64 development tree, Tony Luck < tony.luck@intel.com> - git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git - - - infiniband, Roland Dreier - git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git - - - libata, Jeff Garzik - git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git - - - network drivers, Jeff Garzik - git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git - - - pcmcia, Dominik Brodowski < linux@dominikbrodowski.net> - git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git - - - SCSI, James Bottomley < James.Bottomley@SteelEye.com> - git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git - - quilt trees: - - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman < gregkh@linuxfoundation.org> - kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ - - x86-64, partly i386, Andi Kleen < ak@suse.de> - ftp.firstfloor.org:/pub/ak/x86_64/quilt/ - - 다른 커널 트리들은 http://kernel.org/git와 MAINTAINERS 파일에서 참조할 수 - 있다. +이런 식으로, -next 커널을 통해 다음 머지 기간에 메인라인 커널에 어떤 변경이 +가해질 것인지 간략히 알 수 있다. 모험심 강한 테스터라면 -next 커널에서 테스트를 +수행하는 것도 좋을 것이다. 버그 보고 --------- @@ -597,7 +559,7 @@ Pat이라는 이름을 가진 여자가 있을 수도 있는 것이다. 리눅 이것이 무엇인지 더 자세한 것을 알고 싶다면 다음 문서의 ChageLog 항을 봐라. "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index c5182bb2c16c..f87241dfed87 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -342,7 +342,10 @@ kset use: When you are finished with the kset, call: void kset_unregister(struct kset *kset); -to destroy it. +to destroy it. This removes the kset from sysfs and decrements its reference +count. When the reference count goes to zero, the kset will be released. +Because other references to the kset may still exist, the release may happen +after kset_unregister() returns. An example of using a kset can be seen in the samples/kobject/kset-example.c file in the kernel tree. diff --git a/Documentation/laptops/hpfall.c b/Documentation/laptops/hpfall.c index a4a8fc5d05d4..b85dbbac0499 100644 --- a/Documentation/laptops/hpfall.c +++ b/Documentation/laptops/hpfall.c @@ -29,7 +29,7 @@ int set_unload_heads_path(char *device) return -EINVAL; strncpy(devname, device + 5, sizeof(devname)); - snprintf(unload_heads_path, sizeof(unload_heads_path), + snprintf(unload_heads_path, sizeof(unload_heads_path) - 1, "/sys/block/%s/device/unload_heads", devname); return 0; } diff --git a/Documentation/md.txt b/Documentation/md.txt index fbb2fcbf16b6..f925666e4342 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt @@ -533,7 +533,7 @@ also have found. The count in 'mismatch_cnt' is the number of sectors that were re-written, or (for 'check') would have been re-written. As most raid levels work in units of pages rather - than sectors, this my be larger than the number of actual errors + than sectors, this may be larger than the number of actual errors by a factor of the number of sectors in a page. bitmap_set_bits diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index c8c42e64e953..102dc19c4119 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -194,18 +194,22 @@ There are some minimal guarantees that may be expected of a CPU: (*) On any given CPU, dependent memory accesses will be issued in order, with respect to itself. This means that for: - Q = P; D = *Q; + ACCESS_ONCE(Q) = P; smp_read_barrier_depends(); D = ACCESS_ONCE(*Q); the CPU will issue the following memory operations: Q = LOAD P, D = LOAD *Q - and always in that order. + and always in that order. On most systems, smp_read_barrier_depends() + does nothing, but it is required for DEC Alpha. The ACCESS_ONCE() + is required to prevent compiler mischief. Please note that you + should normally use something like rcu_dereference() instead of + open-coding smp_read_barrier_depends(). (*) Overlapping loads and stores within a particular CPU will appear to be ordered within that CPU. This means that for: - a = *X; *X = b; + a = ACCESS_ONCE(*X); ACCESS_ONCE(*X) = b; the CPU will only issue the following sequence of memory operations: @@ -213,7 +217,7 @@ There are some minimal guarantees that may be expected of a CPU: And for: - *X = c; d = *X; + ACCESS_ONCE(*X) = c; d = ACCESS_ONCE(*X); the CPU will only issue: @@ -224,6 +228,12 @@ There are some minimal guarantees that may be expected of a CPU: And there are a number of things that _must_ or _must_not_ be assumed: + (*) It _must_not_ be assumed that the compiler will do what you want with + memory references that are not protected by ACCESS_ONCE(). Without + ACCESS_ONCE(), the compiler is within its rights to do all sorts + of "creative" transformations, which are covered in the Compiler + Barrier section. + (*) It _must_not_ be assumed that independent loads and stores will be issued in the order given. This means that for: @@ -371,33 +381,44 @@ Memory barriers come in four basic varieties: And a couple of implicit varieties: - (5) LOCK operations. + (5) ACQUIRE operations. This acts as a one-way permeable barrier. It guarantees that all memory - operations after the LOCK operation will appear to happen after the LOCK - operation with respect to the other components of the system. + operations after the ACQUIRE operation will appear to happen after the + ACQUIRE operation with respect to the other components of the system. + ACQUIRE operations include LOCK operations and smp_load_acquire() + operations. - Memory operations that occur before a LOCK operation may appear to happen - after it completes. + Memory operations that occur before an ACQUIRE operation may appear to + happen after it completes. - A LOCK operation should almost always be paired with an UNLOCK operation. + An ACQUIRE operation should almost always be paired with a RELEASE + operation. - (6) UNLOCK operations. + (6) RELEASE operations. This also acts as a one-way permeable barrier. It guarantees that all - memory operations before the UNLOCK operation will appear to happen before - the UNLOCK operation with respect to the other components of the system. + memory operations before the RELEASE operation will appear to happen + before the RELEASE operation with respect to the other components of the + system. RELEASE operations include UNLOCK operations and + smp_store_release() operations. - Memory operations that occur after an UNLOCK operation may appear to + Memory operations that occur after a RELEASE operation may appear to happen before it completes. - LOCK and UNLOCK operations are guaranteed to appear with respect to each - other strictly in the order specified. + The use of ACQUIRE and RELEASE operations generally precludes the need + for other sorts of memory barrier (but note the exceptions mentioned in + the subsection "MMIO write barrier"). In addition, a RELEASE+ACQUIRE + pair is -not- guaranteed to act as a full memory barrier. However, after + an ACQUIRE on a given variable, all memory accesses preceding any prior + RELEASE on that same variable are guaranteed to be visible. In other + words, within a given variable's critical section, all accesses of all + previous critical sections for that variable are guaranteed to have + completed. - The use of LOCK and UNLOCK operations generally precludes the need for - other sorts of memory barrier (but note the exceptions mentioned in the - subsection "MMIO write barrier"). + This means that ACQUIRE acts as a minimal "acquire" operation and + RELEASE acts as a minimal "release" operation. Memory barriers are only required where there's a possibility of interaction @@ -450,14 +471,14 @@ The usage requirements of data dependency barriers are a little subtle, and it's not always obvious that they're needed. To illustrate, consider the following sequence of events: - CPU 1 CPU 2 - =============== =============== + CPU 1 CPU 2 + =============== =============== { A == 1, B == 2, C = 3, P == &A, Q == &C } B = 4; - P = &B - Q = P; - D = *Q; + ACCESS_ONCE(P) = &B + Q = ACCESS_ONCE(P); + D = *Q; There's a clear data dependency here, and it would seem that by the end of the sequence, Q must be either &A or &B, and that: @@ -477,15 +498,15 @@ Alpha). To deal with this, a data dependency barrier or better must be inserted between the address load and the data load: - CPU 1 CPU 2 - =============== =============== + CPU 1 CPU 2 + =============== =============== { A == 1, B == 2, C = 3, P == &A, Q == &C } B = 4; - P = &B - Q = P; - - D = *Q; + ACCESS_ONCE(P) = &B + Q = ACCESS_ONCE(P); + + D = *Q; This enforces the occurrence of one of the two implications, and prevents the third possibility from arising. @@ -500,25 +521,26 @@ odd-numbered bank is idle, one can see the new value of the pointer P (&B), but the old value of the variable B (2). -Another example of where data dependency barriers might by required is where a +Another example of where data dependency barriers might be required is where a number is read from memory and then used to calculate the index for an array access: - CPU 1 CPU 2 - =============== =============== + CPU 1 CPU 2 + =============== =============== { M[0] == 1, M[1] == 2, M[3] = 3, P == 0, Q == 3 } M[1] = 4; - P = 1 - Q = P; - - D = M[Q]; + ACCESS_ONCE(P) = 1 + Q = ACCESS_ONCE(P); + + D = M[Q]; -The data dependency barrier is very important to the RCU system, for example. -See rcu_dereference() in include/linux/rcupdate.h. This permits the current -target of an RCU'd pointer to be replaced with a new modified target, without -the replacement target appearing to be incompletely initialised. +The data dependency barrier is very important to the RCU system, +for example. See rcu_assign_pointer() and rcu_dereference() in +include/linux/rcupdate.h. This permits the current target of an RCU'd +pointer to be replaced with a new modified target, without the replacement +target appearing to be incompletely initialised. See also the subsection on "Cache Coherency" for a more thorough example. @@ -530,24 +552,190 @@ A control dependency requires a full read memory barrier, not simply a data dependency barrier to make it work correctly. Consider the following bit of code: - q = &a; - if (p) { - - q = &b; + q = ACCESS_ONCE(a); + if (q) { + /* BUG: No data dependency!!! */ + p = ACCESS_ONCE(b); } - x = *q; This will not have the desired effect because there is no actual data -dependency, but rather a control dependency that the CPU may short-circuit by -attempting to predict the outcome in advance. In such a case what's actually -required is: +dependency, but rather a control dependency that the CPU may short-circuit +by attempting to predict the outcome in advance, so that other CPUs see +the load from b as having happened before the load from a. In such a +case what's actually required is: - q = &a; - if (p) { + q = ACCESS_ONCE(a); + if (q) { - q = &b; + p = ACCESS_ONCE(b); } - x = *q; + +However, stores are not speculated. This means that ordering -is- provided +in the following example: + + q = ACCESS_ONCE(a); + if (ACCESS_ONCE(q)) { + ACCESS_ONCE(b) = p; + } + +Please note that ACCESS_ONCE() is not optional! Without the ACCESS_ONCE(), +the compiler is within its rights to transform this example: + + q = a; + if (q) { + b = p; /* BUG: Compiler can reorder!!! */ + do_something(); + } else { + b = p; /* BUG: Compiler can reorder!!! */ + do_something_else(); + } + +into this, which of course defeats the ordering: + + b = p; + q = a; + if (q) + do_something(); + else + do_something_else(); + +Worse yet, if the compiler is able to prove (say) that the value of +variable 'a' is always non-zero, it would be well within its rights +to optimize the original example by eliminating the "if" statement +as follows: + + q = a; + b = p; /* BUG: Compiler can reorder!!! */ + do_something(); + +The solution is again ACCESS_ONCE(), which preserves the ordering between +the load from variable 'a' and the store to variable 'b': + + q = ACCESS_ONCE(a); + if (q) { + ACCESS_ONCE(b) = p; + do_something(); + } else { + ACCESS_ONCE(b) = p; + do_something_else(); + } + +You could also use barrier() to prevent the compiler from moving +the stores to variable 'b', but barrier() would not prevent the +compiler from proving to itself that a==1 always, so ACCESS_ONCE() +is also needed. + +It is important to note that control dependencies absolutely require a +a conditional. For example, the following "optimized" version of +the above example breaks ordering: + + q = ACCESS_ONCE(a); + ACCESS_ONCE(b) = p; /* BUG: No ordering vs. load from a!!! */ + if (q) { + /* ACCESS_ONCE(b) = p; -- moved up, BUG!!! */ + do_something(); + } else { + /* ACCESS_ONCE(b) = p; -- moved up, BUG!!! */ + do_something_else(); + } + +It is of course legal for the prior load to be part of the conditional, +for example, as follows: + + if (ACCESS_ONCE(a) > 0) { + ACCESS_ONCE(b) = q / 2; + do_something(); + } else { + ACCESS_ONCE(b) = q / 3; + do_something_else(); + } + +This will again ensure that the load from variable 'a' is ordered before the +stores to variable 'b'. + +In addition, you need to be careful what you do with the local variable 'q', +otherwise the compiler might be able to guess the value and again remove +the needed conditional. For example: + + q = ACCESS_ONCE(a); + if (q % MAX) { + ACCESS_ONCE(b) = p; + do_something(); + } else { + ACCESS_ONCE(b) = p; + do_something_else(); + } + +If MAX is defined to be 1, then the compiler knows that (q % MAX) is +equal to zero, in which case the compiler is within its rights to +transform the above code into the following: + + q = ACCESS_ONCE(a); + ACCESS_ONCE(b) = p; + do_something_else(); + +This transformation loses the ordering between the load from variable 'a' +and the store to variable 'b'. If you are relying on this ordering, you +should do something like the following: + + q = ACCESS_ONCE(a); + BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */ + if (q % MAX) { + ACCESS_ONCE(b) = p; + do_something(); + } else { + ACCESS_ONCE(b) = p; + do_something_else(); + } + +Finally, control dependencies do -not- provide transitivity. This is +demonstrated by two related examples: + + CPU 0 CPU 1 + ===================== ===================== + r1 = ACCESS_ONCE(x); r2 = ACCESS_ONCE(y); + if (r1 >= 0) if (r2 >= 0) + ACCESS_ONCE(y) = 1; ACCESS_ONCE(x) = 1; + + assert(!(r1 == 1 && r2 == 1)); + +The above two-CPU example will never trigger the assert(). However, +if control dependencies guaranteed transitivity (which they do not), +then adding the following two CPUs would guarantee a related assertion: + + CPU 2 CPU 3 + ===================== ===================== + ACCESS_ONCE(x) = 2; ACCESS_ONCE(y) = 2; + + assert(!(r1 == 2 && r2 == 2 && x == 1 && y == 1)); /* FAILS!!! */ + +But because control dependencies do -not- provide transitivity, the +above assertion can fail after the combined four-CPU example completes. +If you need the four-CPU example to provide ordering, you will need +smp_mb() between the loads and stores in the CPU 0 and CPU 1 code fragments. + +In summary: + + (*) Control dependencies can order prior loads against later stores. + However, they do -not- guarantee any other sort of ordering: + Not prior loads against later loads, nor prior stores against + later anything. If you need these other forms of ordering, + use smb_rmb(), smp_wmb(), or, in the case of prior stores and + later loads, smp_mb(). + + (*) Control dependencies require at least one run-time conditional + between the prior load and the subsequent store. If the compiler + is able to optimize the conditional away, it will have also + optimized away the ordering. Careful use of ACCESS_ONCE() can + help to preserve the needed conditional. + + (*) Control dependencies require that the compiler avoid reordering the + dependency into nonexistence. Careful use of ACCESS_ONCE() or + barrier() can help to preserve your control dependency. Please + see the Compiler Barrier section for more information. + + (*) Control dependencies do -not- provide transitivity. If you + need transitivity, use smp_mb(). SMP BARRIER PAIRING @@ -561,23 +749,23 @@ barrier, though a general barrier would also be viable. Similarly a read barrier or a data dependency barrier should always be paired with at least an write barrier, though, again, a general barrier is viable: - CPU 1 CPU 2 - =============== =============== - a = 1; + CPU 1 CPU 2 + =============== =============== + ACCESS_ONCE(a) = 1; - b = 2; x = b; - - y = a; + ACCESS_ONCE(b) = 2; x = ACCESS_ONCE(b); + + y = ACCESS_ONCE(a); Or: - CPU 1 CPU 2 - =============== =============================== + CPU 1 CPU 2 + =============== =============================== a = 1; - b = &a; x = b; - - y = *x; + ACCESS_ONCE(b) = &a; x = ACCESS_ONCE(b); + + y = *x; Basically, the read barrier always has to be there, even though it can be of the "weaker" type. @@ -586,13 +774,13 @@ the "weaker" type. match the loads after the read barrier or the data dependency barrier, and vice versa: - CPU 1 CPU 2 - =============== =============== - a = 1; }---- --->{ v = c - b = 2; } \ / { w = d - \ - c = 3; } / \ { x = a; - d = 4; }---- --->{ y = b; + CPU 1 CPU 2 + =================== =================== + ACCESS_ONCE(a) = 1; }---- --->{ v = ACCESS_ONCE(c); + ACCESS_ONCE(b) = 2; } \ / { w = ACCESS_ONCE(d); + \ + ACCESS_ONCE(c) = 3; } / \ { x = ACCESS_ONCE(a); + ACCESS_ONCE(d) = 4; }---- --->{ y = ACCESS_ONCE(b); EXAMPLES OF MEMORY BARRIER SEQUENCES @@ -882,12 +1070,12 @@ cache it for later use. Consider: - CPU 1 CPU 2 + CPU 1 CPU 2 ======================= ======================= - LOAD B - DIVIDE } Divide instructions generally - DIVIDE } take a long time to perform - LOAD A + LOAD B + DIVIDE } Divide instructions generally + DIVIDE } take a long time to perform + LOAD A Which might appear as this: @@ -910,13 +1098,13 @@ Which might appear as this: Placing a read barrier or a data dependency barrier just before the second load: - CPU 1 CPU 2 + CPU 1 CPU 2 ======================= ======================= - LOAD B - DIVIDE - DIVIDE + LOAD B + DIVIDE + DIVIDE - LOAD A + LOAD A will force any value speculatively obtained to be reconsidered to an extent dependent on the type of barrier used. If there was no change made to the @@ -1042,10 +1230,277 @@ compiler from moving the memory accesses either side of it to the other side: barrier(); -This is a general barrier - lesser varieties of compiler barrier do not exist. +This is a general barrier -- there are no read-read or write-write variants +of barrier(). However, ACCESS_ONCE() can be thought of as a weak form +for barrier() that affects only the specific accesses flagged by the +ACCESS_ONCE(). -The compiler barrier has no direct effect on the CPU, which may then reorder -things however it wishes. +The barrier() function has the following effects: + + (*) Prevents the compiler from reordering accesses following the + barrier() to precede any accesses preceding the barrier(). + One example use for this property is to ease communication between + interrupt-handler code and the code that was interrupted. + + (*) Within a loop, forces the compiler to load the variables used + in that loop's conditional on each pass through that loop. + +The ACCESS_ONCE() function can prevent any number of optimizations that, +while perfectly safe in single-threaded code, can be fatal in concurrent +code. Here are some examples of these sorts of optimizations: + + (*) The compiler is within its rights to merge successive loads from + the same variable. Such merging can cause the compiler to "optimize" + the following code: + + while (tmp = a) + do_something_with(tmp); + + into the following code, which, although in some sense legitimate + for single-threaded code, is almost certainly not what the developer + intended: + + if (tmp = a) + for (;;) + do_something_with(tmp); + + Use ACCESS_ONCE() to prevent the compiler from doing this to you: + + while (tmp = ACCESS_ONCE(a)) + do_something_with(tmp); + + (*) The compiler is within its rights to reload a variable, for example, + in cases where high register pressure prevents the compiler from + keeping all data of interest in registers. The compiler might + therefore optimize the variable 'tmp' out of our previous example: + + while (tmp = a) + do_something_with(tmp); + + This could result in the following code, which is perfectly safe in + single-threaded code, but can be fatal in concurrent code: + + while (a) + do_something_with(a); + + For example, the optimized version of this code could result in + passing a zero to do_something_with() in the case where the variable + a was modified by some other CPU between the "while" statement and + the call to do_something_with(). + + Again, use ACCESS_ONCE() to prevent the compiler from doing this: + + while (tmp = ACCESS_ONCE(a)) + do_something_with(tmp); + + Note that if the compiler runs short of registers, it might save + tmp onto the stack. The overhead of this saving and later restoring + is why compilers reload variables. Doing so is perfectly safe for + single-threaded code, so you need to tell the compiler about cases + where it is not safe. + + (*) The compiler is within its rights to omit a load entirely if it knows + what the value will be. For example, if the compiler can prove that + the value of variable 'a' is always zero, it can optimize this code: + + while (tmp = a) + do_something_with(tmp); + + Into this: + + do { } while (0); + + This transformation is a win for single-threaded code because it gets + rid of a load and a branch. The problem is that the compiler will + carry out its proof assuming that the current CPU is the only one + updating variable 'a'. If variable 'a' is shared, then the compiler's + proof will be erroneous. Use ACCESS_ONCE() to tell the compiler + that it doesn't know as much as it thinks it does: + + while (tmp = ACCESS_ONCE(a)) + do_something_with(tmp); + + But please note that the compiler is also closely watching what you + do with the value after the ACCESS_ONCE(). For example, suppose you + do the following and MAX is a preprocessor macro with the value 1: + + while ((tmp = ACCESS_ONCE(a)) % MAX) + do_something_with(tmp); + + Then the compiler knows that the result of the "%" operator applied + to MAX will always be zero, again allowing the compiler to optimize + the code into near-nonexistence. (It will still load from the + variable 'a'.) + + (*) Similarly, the compiler is within its rights to omit a store entirely + if it knows that the variable already has the value being stored. + Again, the compiler assumes that the current CPU is the only one + storing into the variable, which can cause the compiler to do the + wrong thing for shared variables. For example, suppose you have + the following: + + a = 0; + /* Code that does not store to variable a. */ + a = 0; + + The compiler sees that the value of variable 'a' is already zero, so + it might well omit the second store. This would come as a fatal + surprise if some other CPU might have stored to variable 'a' in the + meantime. + + Use ACCESS_ONCE() to prevent the compiler from making this sort of + wrong guess: + + ACCESS_ONCE(a) = 0; + /* Code that does not store to variable a. */ + ACCESS_ONCE(a) = 0; + + (*) The compiler is within its rights to reorder memory accesses unless + you tell it not to. For example, consider the following interaction + between process-level code and an interrupt handler: + + void process_level(void) + { + msg = get_message(); + flag = true; + } + + void interrupt_handler(void) + { + if (flag) + process_message(msg); + } + + There is nothing to prevent the the compiler from transforming + process_level() to the following, in fact, this might well be a + win for single-threaded code: + + void process_level(void) + { + flag = true; + msg = get_message(); + } + + If the interrupt occurs between these two statement, then + interrupt_handler() might be passed a garbled msg. Use ACCESS_ONCE() + to prevent this as follows: + + void process_level(void) + { + ACCESS_ONCE(msg) = get_message(); + ACCESS_ONCE(flag) = true; + } + + void interrupt_handler(void) + { + if (ACCESS_ONCE(flag)) + process_message(ACCESS_ONCE(msg)); + } + + Note that the ACCESS_ONCE() wrappers in interrupt_handler() + are needed if this interrupt handler can itself be interrupted + by something that also accesses 'flag' and 'msg', for example, + a nested interrupt or an NMI. Otherwise, ACCESS_ONCE() is not + needed in interrupt_handler() other than for documentation purposes. + (Note also that nested interrupts do not typically occur in modern + Linux kernels, in fact, if an interrupt handler returns with + interrupts enabled, you will get a WARN_ONCE() splat.) + + You should assume that the compiler can move ACCESS_ONCE() past + code not containing ACCESS_ONCE(), barrier(), or similar primitives. + + This effect could also be achieved using barrier(), but ACCESS_ONCE() + is more selective: With ACCESS_ONCE(), the compiler need only forget + the contents of the indicated memory locations, while with barrier() + the compiler must discard the value of all memory locations that + it has currented cached in any machine registers. Of course, + the compiler must also respect the order in which the ACCESS_ONCE()s + occur, though the CPU of course need not do so. + + (*) The compiler is within its rights to invent stores to a variable, + as in the following example: + + if (a) + b = a; + else + b = 42; + + The compiler might save a branch by optimizing this as follows: + + b = 42; + if (a) + b = a; + + In single-threaded code, this is not only safe, but also saves + a branch. Unfortunately, in concurrent code, this optimization + could cause some other CPU to see a spurious value of 42 -- even + if variable 'a' was never zero -- when loading variable 'b'. + Use ACCESS_ONCE() to prevent this as follows: + + if (a) + ACCESS_ONCE(b) = a; + else + ACCESS_ONCE(b) = 42; + + The compiler can also invent loads. These are usually less + damaging, but they can result in cache-line bouncing and thus in + poor performance and scalability. Use ACCESS_ONCE() to prevent + invented loads. + + (*) For aligned memory locations whose size allows them to be accessed + with a single memory-reference instruction, prevents "load tearing" + and "store tearing," in which a single large access is replaced by + multiple smaller accesses. For example, given an architecture having + 16-bit store instructions with 7-bit immediate fields, the compiler + might be tempted to use two 16-bit store-immediate instructions to + implement the following 32-bit store: + + p = 0x00010002; + + Please note that GCC really does use this sort of optimization, + which is not surprising given that it would likely take more + than two instructions to build the constant and then store it. + This optimization can therefore be a win in single-threaded code. + In fact, a recent bug (since fixed) caused GCC to incorrectly use + this optimization in a volatile store. In the absence of such bugs, + use of ACCESS_ONCE() prevents store tearing in the following example: + + ACCESS_ONCE(p) = 0x00010002; + + Use of packed structures can also result in load and store tearing, + as in this example: + + struct __attribute__((__packed__)) foo { + short a; + int b; + short c; + }; + struct foo foo1, foo2; + ... + + foo2.a = foo1.a; + foo2.b = foo1.b; + foo2.c = foo1.c; + + Because there are no ACCESS_ONCE() wrappers and no volatile markings, + the compiler would be well within its rights to implement these three + assignment statements as a pair of 32-bit loads followed by a pair + of 32-bit stores. This would result in load tearing on 'foo1.b' + and store tearing on 'foo2.b'. ACCESS_ONCE() again prevents tearing + in this example: + + foo2.a = foo1.a; + ACCESS_ONCE(foo2.b) = ACCESS_ONCE(foo1.b); + foo2.c = foo1.c; + +All that aside, it is never necessary to use ACCESS_ONCE() on a variable +that has been marked volatile. For example, because 'jiffies' is marked +volatile, it is never necessary to say ACCESS_ONCE(jiffies). The reason +for this is that ACCESS_ONCE() is implemented as a volatile cast, which +has no effect when its argument is already marked volatile. + +Please note that these compiler barriers have no direct effect on the CPU, +which may then reorder things however it wishes. CPU MEMORY BARRIERS @@ -1135,7 +1590,7 @@ There are some more advanced barrier functions: clear_bit( ... ); This prevents memory operations before the clear leaking to after it. See - the subsection on "Locking Functions" with reference to UNLOCK operation + the subsection on "Locking Functions" with reference to RELEASE operation implications. See Documentation/atomic_ops.txt for more information. See the "Atomic @@ -1169,8 +1624,8 @@ provide more substantial guarantees, but these may not be relied upon outside of arch specific code. -LOCKING FUNCTIONS ------------------ +ACQUIRING FUNCTIONS +------------------- The Linux kernel has a number of locking constructs: @@ -1181,65 +1636,107 @@ The Linux kernel has a number of locking constructs: (*) R/W semaphores (*) RCU -In all cases there are variants on "LOCK" operations and "UNLOCK" operations +In all cases there are variants on "ACQUIRE" operations and "RELEASE" operations for each construct. These operations all imply certain barriers: - (1) LOCK operation implication: + (1) ACQUIRE operation implication: - Memory operations issued after the LOCK will be completed after the LOCK - operation has completed. + Memory operations issued after the ACQUIRE will be completed after the + ACQUIRE operation has completed. - Memory operations issued before the LOCK may be completed after the LOCK - operation has completed. + Memory operations issued before the ACQUIRE may be completed after the + ACQUIRE operation has completed. An smp_mb__before_spinlock(), combined + with a following ACQUIRE, orders prior loads against subsequent stores and + stores and prior stores against subsequent stores. Note that this is + weaker than smp_mb()! The smp_mb__before_spinlock() primitive is free on + many architectures. - (2) UNLOCK operation implication: + (2) RELEASE operation implication: - Memory operations issued before the UNLOCK will be completed before the - UNLOCK operation has completed. + Memory operations issued before the RELEASE will be completed before the + RELEASE operation has completed. - Memory operations issued after the UNLOCK may be completed before the - UNLOCK operation has completed. + Memory operations issued after the RELEASE may be completed before the + RELEASE operation has completed. - (3) LOCK vs LOCK implication: + (3) ACQUIRE vs ACQUIRE implication: - All LOCK operations issued before another LOCK operation will be completed - before that LOCK operation. + All ACQUIRE operations issued before another ACQUIRE operation will be + completed before that ACQUIRE operation. - (4) LOCK vs UNLOCK implication: + (4) ACQUIRE vs RELEASE implication: - All LOCK operations issued before an UNLOCK operation will be completed - before the UNLOCK operation. + All ACQUIRE operations issued before a RELEASE operation will be + completed before the RELEASE operation. - All UNLOCK operations issued before a LOCK operation will be completed - before the LOCK operation. + (5) Failed conditional ACQUIRE implication: - (5) Failed conditional LOCK implication: - - Certain variants of the LOCK operation may fail, either due to being - unable to get the lock immediately, or due to receiving an unblocked + Certain locking variants of the ACQUIRE operation may fail, either due to + being unable to get the lock immediately, or due to receiving an unblocked signal whilst asleep waiting for the lock to become available. Failed locks do not imply any sort of barrier. -Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is -equivalent to a full barrier, but a LOCK followed by an UNLOCK is not. +[!] Note: one of the consequences of lock ACQUIREs and RELEASEs being only +one-way barriers is that the effects of instructions outside of a critical +section may seep into the inside of the critical section. -[!] Note: one of the consequences of LOCKs and UNLOCKs being only one-way - barriers is that the effects of instructions outside of a critical section - may seep into the inside of the critical section. - -A LOCK followed by an UNLOCK may not be assumed to be full memory barrier -because it is possible for an access preceding the LOCK to happen after the -LOCK, and an access following the UNLOCK to happen before the UNLOCK, and the -two accesses can themselves then cross: +An ACQUIRE followed by a RELEASE may not be assumed to be full memory barrier +because it is possible for an access preceding the ACQUIRE to happen after the +ACQUIRE, and an access following the RELEASE to happen before the RELEASE, and +the two accesses can themselves then cross: *A = a; - LOCK - UNLOCK + ACQUIRE M + RELEASE M *B = b; may occur as: - LOCK, STORE *B, STORE *A, UNLOCK + ACQUIRE M, STORE *B, STORE *A, RELEASE M + +This same reordering can of course occur if the lock's ACQUIRE and RELEASE are +to the same lock variable, but only from the perspective of another CPU not +holding that lock. + +In short, a RELEASE followed by an ACQUIRE may -not- be assumed to be a full +memory barrier because it is possible for a preceding RELEASE to pass a +later ACQUIRE from the viewpoint of the CPU, but not from the viewpoint +of the compiler. Note that deadlocks cannot be introduced by this +interchange because if such a deadlock threatened, the RELEASE would +simply complete. + +If it is necessary for a RELEASE-ACQUIRE pair to produce a full barrier, the +ACQUIRE can be followed by an smp_mb__after_unlock_lock() invocation. This +will produce a full barrier if either (a) the RELEASE and the ACQUIRE are +executed by the same CPU or task, or (b) the RELEASE and ACQUIRE act on the +same variable. The smp_mb__after_unlock_lock() primitive is free on many +architectures. Without smp_mb__after_unlock_lock(), the critical sections +corresponding to the RELEASE and the ACQUIRE can cross: + + *A = a; + RELEASE M + ACQUIRE N + *B = b; + +could occur as: + + ACQUIRE N, STORE *B, STORE *A, RELEASE M + +With smp_mb__after_unlock_lock(), they cannot, so that: + + *A = a; + RELEASE M + ACQUIRE N + smp_mb__after_unlock_lock(); + *B = b; + +will always occur as either of the following: + + STORE *A, RELEASE, ACQUIRE, STORE *B + STORE *A, ACQUIRE, RELEASE, STORE *B + +If the RELEASE and ACQUIRE were instead both operating on the same lock +variable, only the first of these two alternatives can occur. Locks and semaphores may not provide any guarantee of ordering on UP compiled systems, and so cannot be counted on in such a situation to actually achieve @@ -1253,33 +1750,33 @@ As an example, consider the following: *A = a; *B = b; - LOCK + ACQUIRE *C = c; *D = d; - UNLOCK + RELEASE *E = e; *F = f; The following sequence of events is acceptable: - LOCK, {*F,*A}, *E, {*C,*D}, *B, UNLOCK + ACQUIRE, {*F,*A}, *E, {*C,*D}, *B, RELEASE [+] Note that {*F,*A} indicates a combined access. But none of the following are: - {*F,*A}, *B, LOCK, *C, *D, UNLOCK, *E - *A, *B, *C, LOCK, *D, UNLOCK, *E, *F - *A, *B, LOCK, *C, UNLOCK, *D, *E, *F - *B, LOCK, *C, *D, UNLOCK, {*F,*A}, *E + {*F,*A}, *B, ACQUIRE, *C, *D, RELEASE, *E + *A, *B, *C, ACQUIRE, *D, RELEASE, *E, *F + *A, *B, ACQUIRE, *C, RELEASE, *D, *E, *F + *B, ACQUIRE, *C, *D, RELEASE, {*F,*A}, *E INTERRUPT DISABLING FUNCTIONS ----------------------------- -Functions that disable interrupts (LOCK equivalent) and enable interrupts -(UNLOCK equivalent) will act as compiler barriers only. So if memory or I/O +Functions that disable interrupts (ACQUIRE equivalent) and enable interrupts +(RELEASE equivalent) will act as compiler barriers only. So if memory or I/O barriers are required in such a situation, they must be provided from some other means. @@ -1418,75 +1915,81 @@ Other functions that imply barriers: (*) schedule() and similar imply full memory barriers. -================================= -INTER-CPU LOCKING BARRIER EFFECTS -================================= +=================================== +INTER-CPU ACQUIRING BARRIER EFFECTS +=================================== On SMP systems locking primitives give a more substantial form of barrier: one that does affect memory access ordering on other CPUs, within the context of conflict on any particular lock. -LOCKS VS MEMORY ACCESSES ------------------------- +ACQUIRES VS MEMORY ACCESSES +--------------------------- Consider the following: the system has a pair of spinlocks (M) and (Q), and three CPUs; then should the following sequence of events occur: CPU 1 CPU 2 =============================== =============================== - *A = a; *E = e; - LOCK M LOCK Q - *B = b; *F = f; - *C = c; *G = g; - UNLOCK M UNLOCK Q - *D = d; *H = h; + ACCESS_ONCE(*A) = a; ACCESS_ONCE(*E) = e; + ACQUIRE M ACQUIRE Q + ACCESS_ONCE(*B) = b; ACCESS_ONCE(*F) = f; + ACCESS_ONCE(*C) = c; ACCESS_ONCE(*G) = g; + RELEASE M RELEASE Q + ACCESS_ONCE(*D) = d; ACCESS_ONCE(*H) = h; Then there is no guarantee as to what order CPU 3 will see the accesses to *A through *H occur in, other than the constraints imposed by the separate locks on the separate CPUs. It might, for example, see: - *E, LOCK M, LOCK Q, *G, *C, *F, *A, *B, UNLOCK Q, *D, *H, UNLOCK M + *E, ACQUIRE M, ACQUIRE Q, *G, *C, *F, *A, *B, RELEASE Q, *D, *H, RELEASE M But it won't see any of: - *B, *C or *D preceding LOCK M - *A, *B or *C following UNLOCK M - *F, *G or *H preceding LOCK Q - *E, *F or *G following UNLOCK Q + *B, *C or *D preceding ACQUIRE M + *A, *B or *C following RELEASE M + *F, *G or *H preceding ACQUIRE Q + *E, *F or *G following RELEASE Q However, if the following occurs: CPU 1 CPU 2 =============================== =============================== - *A = a; - LOCK M [1] - *B = b; - *C = c; - UNLOCK M [1] - *D = d; *E = e; - LOCK M [2] - *F = f; - *G = g; - UNLOCK M [2] - *H = h; + ACCESS_ONCE(*A) = a; + ACQUIRE M [1] + ACCESS_ONCE(*B) = b; + ACCESS_ONCE(*C) = c; + RELEASE M [1] + ACCESS_ONCE(*D) = d; ACCESS_ONCE(*E) = e; + ACQUIRE M [2] + smp_mb__after_unlock_lock(); + ACCESS_ONCE(*F) = f; + ACCESS_ONCE(*G) = g; + RELEASE M [2] + ACCESS_ONCE(*H) = h; CPU 3 might see: - *E, LOCK M [1], *C, *B, *A, UNLOCK M [1], - LOCK M [2], *H, *F, *G, UNLOCK M [2], *D + *E, ACQUIRE M [1], *C, *B, *A, RELEASE M [1], + ACQUIRE M [2], *H, *F, *G, RELEASE M [2], *D But assuming CPU 1 gets the lock first, CPU 3 won't see any of: - *B, *C, *D, *F, *G or *H preceding LOCK M [1] - *A, *B or *C following UNLOCK M [1] - *F, *G or *H preceding LOCK M [2] - *A, *B, *C, *E, *F or *G following UNLOCK M [2] + *B, *C, *D, *F, *G or *H preceding ACQUIRE M [1] + *A, *B or *C following RELEASE M [1] + *F, *G or *H preceding ACQUIRE M [2] + *A, *B, *C, *E, *F or *G following RELEASE M [2] + +Note that the smp_mb__after_unlock_lock() is critically important +here: Without it CPU 3 might see some of the above orderings. +Without smp_mb__after_unlock_lock(), the accesses are not guaranteed +to be seen in order unless CPU 3 holds lock M. -LOCKS VS I/O ACCESSES ---------------------- +ACQUIRES VS I/O ACCESSES +------------------------ Under certain circumstances (especially involving NUMA), I/O accesses within two spinlocked sections on two different CPUs may be seen as interleaved by the @@ -1687,28 +2190,30 @@ explicit lock operations, described later). These include: xchg(); cmpxchg(); - atomic_xchg(); - atomic_cmpxchg(); - atomic_inc_return(); - atomic_dec_return(); - atomic_add_return(); - atomic_sub_return(); - atomic_inc_and_test(); - atomic_dec_and_test(); - atomic_sub_and_test(); - atomic_add_negative(); - atomic_add_unless(); /* when succeeds (returns 1) */ + atomic_xchg(); atomic_long_xchg(); + atomic_cmpxchg(); atomic_long_cmpxchg(); + atomic_inc_return(); atomic_long_inc_return(); + atomic_dec_return(); atomic_long_dec_return(); + atomic_add_return(); atomic_long_add_return(); + atomic_sub_return(); atomic_long_sub_return(); + atomic_inc_and_test(); atomic_long_inc_and_test(); + atomic_dec_and_test(); atomic_long_dec_and_test(); + atomic_sub_and_test(); atomic_long_sub_and_test(); + atomic_add_negative(); atomic_long_add_negative(); test_and_set_bit(); test_and_clear_bit(); test_and_change_bit(); -These are used for such things as implementing LOCK-class and UNLOCK-class + /* when succeeds (returns 1) */ + atomic_add_unless(); atomic_long_add_unless(); + +These are used for such things as implementing ACQUIRE-class and RELEASE-class operations and adjusting reference counters towards object destruction, and as such the implicit memory barrier effects are necessary. The following operations are potential problems as they do _not_ imply memory -barriers, but might be used for implementing such things as UNLOCK-class +barriers, but might be used for implementing such things as RELEASE-class operations: atomic_set(); @@ -1750,7 +2255,7 @@ The following operations are special locking primitives: clear_bit_unlock(); __clear_bit_unlock(); -These implement LOCK-class and UNLOCK-class operations. These should be used in +These implement ACQUIRE-class and RELEASE-class operations. These should be used in preference to other operations when implementing locking primitives, because their implementations can be optimised on many architectures. @@ -1887,8 +2392,8 @@ functions: space should suffice for PCI. [*] NOTE! attempting to load from the same location as was written to may - cause a malfunction - consider the 16550 Rx/Tx serial registers for - example. + cause a malfunction - consider the 16550 Rx/Tx serial registers for + example. Used with prefetchable I/O memory, an mmiowb() barrier may be required to force stores to be ordered. @@ -1955,19 +2460,19 @@ barriers for the most part act at the interface between the CPU and its cache : +--------+ +--------+ : +--------+ +-----------+ | | | | : | | | | +--------+ - | CPU | | Memory | : | CPU | | | | | - | Core |--->| Access |----->| Cache |<-->| | | | + | CPU | | Memory | : | CPU | | | | | + | Core |--->| Access |----->| Cache |<-->| | | | | | | Queue | : | | | |--->| Memory | - | | | | : | | | | | | - +--------+ +--------+ : +--------+ | | | | + | | | | : | | | | | | + +--------+ +--------+ : +--------+ | | | | : | Cache | +--------+ : | Coherency | : | Mechanism | +--------+ +--------+ +--------+ : +--------+ | | | | | | | | : | | | | | | | CPU | | Memory | : | CPU | | |--->| Device | - | Core |--->| Access |----->| Cache |<-->| | | | - | | | Queue | : | | | | | | + | Core |--->| Access |----->| Cache |<-->| | | | + | | | Queue | : | | | | | | | | | | : | | | | +--------+ +--------+ +--------+ : +--------+ +-----------+ : @@ -2090,7 +2595,7 @@ CPU's caches by some other cache event: p = &v; q = p; - + x = *q; Reads from v before v updated in cache @@ -2115,7 +2620,7 @@ queue before processing any further requests: p = &v; q = p; - + smp_read_barrier_depends() @@ -2177,11 +2682,11 @@ A programmer might take it for granted that the CPU will perform memory operations in exactly the order specified, so that if the CPU is, for example, given the following piece of code to execute: - a = *A; - *B = b; - c = *C; - d = *D; - *E = e; + a = ACCESS_ONCE(*A); + ACCESS_ONCE(*B) = b; + c = ACCESS_ONCE(*C); + d = ACCESS_ONCE(*D); + ACCESS_ONCE(*E) = e; they would then expect that the CPU will complete the memory operation for each instruction before moving on to the next one, leading to a definite sequence of @@ -2228,12 +2733,12 @@ However, it is guaranteed that a CPU will be self-consistent: it will see its _own_ accesses appear to be correctly ordered, without the need for a memory barrier. For instance with the following code: - U = *A; - *A = V; - *A = W; - X = *A; - *A = Y; - Z = *A; + U = ACCESS_ONCE(*A); + ACCESS_ONCE(*A) = V; + ACCESS_ONCE(*A) = W; + X = ACCESS_ONCE(*A); + ACCESS_ONCE(*A) = Y; + Z = ACCESS_ONCE(*A); and assuming no intervention by an external influence, it can be assumed that the final result will appear to be: @@ -2250,7 +2755,12 @@ accesses: in that order, but, without intervention, the sequence may have almost any combination of elements combined or discarded, provided the program's view of -the world remains consistent. +the world remains consistent. Note that ACCESS_ONCE() is -not- optional +in the above example, as there are architectures where a given CPU might +interchange successive loads to the same location. On such architectures, +ACCESS_ONCE() does whatever is necessary to prevent this, for example, on +Itanium the volatile casts used by ACCESS_ONCE() cause GCC to emit the +special ld.acq and st.rel instructions that prevent such reordering. The compiler may also combine, discard or defer elements of the sequence before the CPU even sees them. @@ -2264,13 +2774,13 @@ may be reduced to: *A = W; -since, without a write barrier, it can be assumed that the effect of the -storage of V to *A is lost. Similarly: +since, without either a write barrier or an ACCESS_ONCE(), it can be +assumed that the effect of the storage of V to *A is lost. Similarly: *A = Y; Z = *A; -may, without a memory barrier, be reduced to: +may, without a memory barrier or an ACCESS_ONCE(), be reduced to: *A = Y; Z = Y; diff --git a/Documentation/misc-devices/mei/mei-amt-version.c b/Documentation/misc-devices/mei/mei-amt-version.c index 49e4f770864a..57d0d871dcf7 100644 --- a/Documentation/misc-devices/mei/mei-amt-version.c +++ b/Documentation/misc-devices/mei/mei-amt-version.c @@ -115,8 +115,6 @@ static bool mei_init(struct mei *me, const uuid_le *guid, struct mei_client *cl; struct mei_connect_client_data data; - mei_deinit(me); - me->verbose = verbose; me->fd = open("/dev/mei", O_RDWR); diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index 89490beb3c0b..58e49042fc20 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt @@ -66,11 +66,10 @@ All mesh wide settings can be found in batman's own interface folder: # ls /sys/class/net/bat0/mesh/ -# aggregated_ogms gw_bandwidth log_level -# ap_isolation gw_mode orig_interval -# bonding gw_sel_class routing_algo -# bridge_loop_avoidance hop_penalty fragmentation - +#aggregated_ogms distributed_arp_table gw_sel_class orig_interval +#ap_isolation fragmentation hop_penalty routing_algo +#bonding gw_bandwidth isolation_mark vlan0 +#bridge_loop_avoidance gw_mode log_level There is a special folder for debugging information: diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 2cdb8b66caa9..5cdb22971d19 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -657,7 +657,8 @@ primary one slave is preferred over another, e.g., when one slave has higher throughput than another. - The primary option is only valid for active-backup mode. + The primary option is only valid for active-backup(1), + balance-tlb (5) and balance-alb (6) mode. primary_reselect @@ -853,6 +854,14 @@ resend_igmp This option was added for bonding version 3.7.0. +lp_interval + + Specifies the number of seconds between instances where the bonding + driver sends learning packets to each slaves peer switch. + + The valid range is 1 - 0x7fffffff; the default value is 1. This Option + has effect only in balance-tlb and balance-alb modes. + 3. Configuring Bonding Devices ============================== diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index 4c072414eadb..f3089d423515 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -2,21 +2,20 @@ can.txt -Readme file for the Controller Area Network Protocol Family (aka Socket CAN) +Readme file for the Controller Area Network Protocol Family (aka SocketCAN) This file contains - 1 Overview / What is Socket CAN + 1 Overview / What is SocketCAN 2 Motivation / Why using the socket API - 3 Socket CAN concept + 3 SocketCAN concept 3.1 receive lists 3.2 local loopback of sent frames - 3.3 network security issues (capabilities) - 3.4 network problem notifications + 3.3 network problem notifications - 4 How to use Socket CAN + 4 How to use SocketCAN 4.1 RAW protocol sockets with can_filters (SOCK_RAW) 4.1.1 RAW socket option CAN_RAW_FILTER 4.1.2 RAW socket option CAN_RAW_ERR_FILTER @@ -34,7 +33,7 @@ This file contains 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) - 5 Socket CAN core module + 5 SocketCAN core module 5.1 can.ko module params 5.2 procfs content 5.3 writing own CAN protocol modules @@ -51,20 +50,20 @@ This file contains 6.6 CAN FD (flexible data rate) driver support 6.7 supported CAN hardware - 7 Socket CAN resources + 7 SocketCAN resources 8 Credits ============================================================================ -1. Overview / What is Socket CAN +1. Overview / What is SocketCAN -------------------------------- The socketcan package is an implementation of CAN protocols (Controller Area Network) for Linux. CAN is a networking technology which has widespread use in automation, embedded devices, and automotive fields. While there have been other CAN implementations -for Linux based on character devices, Socket CAN uses the Berkeley +for Linux based on character devices, SocketCAN uses the Berkeley socket API, the Linux network stack and implements the CAN device drivers as network interfaces. The CAN socket API has been designed as similar as possible to the TCP/IP protocols to allow programmers, @@ -74,7 +73,7 @@ sockets. 2. Motivation / Why using the socket API ---------------------------------------- -There have been CAN implementations for Linux before Socket CAN so the +There have been CAN implementations for Linux before SocketCAN so the question arises, why we have started another project. Most existing implementations come as a device driver for some CAN hardware, they are based on character devices and provide comparatively little @@ -89,10 +88,10 @@ the CAN controller requires employment of another device driver and often the need for adaption of large parts of the application to the new driver's API. -Socket CAN was designed to overcome all of these limitations. A new +SocketCAN was designed to overcome all of these limitations. A new protocol family has been implemented which provides a socket interface to user space applications and which builds upon the Linux network -layer, so to use all of the provided queueing functionality. A device +layer, enabling use all of the provided queueing functionality. A device driver for CAN controller hardware registers itself with the Linux network layer as a network device, so that CAN frames from the controller can be passed up to the network layer and on to the CAN @@ -146,15 +145,15 @@ solution for a couple of reasons: providing an API for device drivers to register with. However, then it would be no more difficult, or may be even easier, to use the networking framework provided by the Linux kernel, and this is what - Socket CAN does. + SocketCAN does. The use of the networking framework of the Linux kernel is just the natural and most appropriate way to implement CAN for Linux. -3. Socket CAN concept +3. SocketCAN concept --------------------- - As described in chapter 2 it is the main goal of Socket CAN to + As described in chapter 2 it is the main goal of SocketCAN to provide a socket interface to user space applications which builds upon the Linux network layer. In contrast to the commonly known TCP/IP and ethernet networking, the CAN bus is a broadcast-only(!) @@ -168,11 +167,11 @@ solution for a couple of reasons: The network transparent access of multiple applications leads to the problem that different applications may be interested in the same - CAN-IDs from the same CAN network interface. The Socket CAN core + CAN-IDs from the same CAN network interface. The SocketCAN core module - which implements the protocol family CAN - provides several high efficient receive lists for this reason. If e.g. a user space application opens a CAN RAW socket, the raw protocol module itself - requests the (range of) CAN-IDs from the Socket CAN core that are + requests the (range of) CAN-IDs from the SocketCAN core that are requested by the user. The subscription and unsubscription of CAN-IDs can be done for specific CAN interfaces or for all(!) known CAN interfaces with the can_rx_(un)register() functions provided to @@ -217,21 +216,7 @@ solution for a couple of reasons: * = you really like to have this when you're running analyser tools like 'candump' or 'cansniffer' on the (same) node. - 3.3 network security issues (capabilities) - - The Controller Area Network is a local field bus transmitting only - broadcast messages without any routing and security concepts. - In the majority of cases the user application has to deal with - raw CAN frames. Therefore it might be reasonable NOT to restrict - the CAN access only to the user root, as known from other networks. - Since the currently implemented CAN_RAW and CAN_BCM sockets can only - send and receive frames to/from CAN interfaces it does not affect - security of others networks to allow all users to access the CAN. - To enable non-root users to access CAN_RAW and CAN_BCM protocol - sockets the Kconfig options CAN_RAW_USER and/or CAN_BCM_USER may be - selected at kernel compile time. - - 3.4 network problem notifications + 3.3 network problem notifications The use of the CAN bus may lead to several problems on the physical and media access control layer. Detecting and logging of these lower @@ -251,11 +236,11 @@ solution for a couple of reasons: by default. The format of the CAN error message frame is briefly described in the Linux header file "include/linux/can/error.h". -4. How to use Socket CAN +4. How to use SocketCAN ------------------------ Like TCP/IP, you first need to open a socket for communicating over a - CAN network. Since Socket CAN implements a new protocol family, you + CAN network. Since SocketCAN implements a new protocol family, you need to pass PF_CAN as the first argument to the socket(2) system call. Currently, there are two CAN protocols to choose from, the raw socket protocol and the broadcast manager (BCM). So to open a socket, @@ -286,8 +271,8 @@ solution for a couple of reasons: }; The alignment of the (linear) payload data[] to a 64bit boundary - allows the user to define own structs and unions to easily access the - CAN payload. There is no given byteorder on the CAN bus by + allows the user to define their own structs and unions to easily access + the CAN payload. There is no given byteorder on the CAN bus by default. A read(2) system call on a CAN_RAW socket transfers a struct can_frame to the user space. @@ -479,7 +464,7 @@ solution for a couple of reasons: setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); - To set the filters to zero filters is quite obsolete as not read + To set the filters to zero filters is quite obsolete as to not read data causes the raw socket to discard the received CAN frames. But having this 'send only' use-case we may remove the receive list in the Kernel to save a little (really a very little!) CPU usage. @@ -814,17 +799,17 @@ solution for a couple of reasons: 4.4 unconnected transport protocols (SOCK_DGRAM) -5. Socket CAN core module +5. SocketCAN core module ------------------------- - The Socket CAN core module implements the protocol family + The SocketCAN core module implements the protocol family PF_CAN. CAN protocol modules are loaded by the core module at runtime. The core module provides an interface for CAN protocol modules to subscribe needed CAN IDs (see chapter 3.1). 5.1 can.ko module params - - stats_timer: To calculate the Socket CAN core statistics + - stats_timer: To calculate the SocketCAN core statistics (e.g. current/maximum frames per second) this 1 second timer is invoked at can.ko module start time by default. This timer can be disabled by using stattimer=0 on the module commandline. @@ -833,7 +818,7 @@ solution for a couple of reasons: 5.2 procfs content - As described in chapter 3.1 the Socket CAN core uses several filter + As described in chapter 3.1 the SocketCAN core uses several filter lists to deliver received CAN frames to CAN protocol modules. These receive lists, their filters and the count of filter matches can be checked in the appropriate receive list. All entries contain the @@ -860,15 +845,15 @@ solution for a couple of reasons: Additional procfs files in /proc/net/can - stats - Socket CAN core statistics (rx/tx frames, match ratios, ...) + stats - SocketCAN core statistics (rx/tx frames, match ratios, ...) reset_stats - manual statistic reset - version - prints the Socket CAN core version and the ABI version + version - prints the SocketCAN core version and the ABI version 5.3 writing own CAN protocol modules To implement a new protocol in the protocol family PF_CAN a new protocol has to be defined in include/linux/can.h . - The prototypes and definitions to use the Socket CAN core can be + The prototypes and definitions to use the SocketCAN core can be accessed by including include/linux/can/core.h . In addition to functions that register the CAN protocol and the CAN device notifier chain there are functions to subscribe CAN @@ -1105,7 +1090,7 @@ solution for a couple of reasons: $ ip link set canX up type can bitrate 125000 - A device may enter the "bus-off" state if too much errors occurred on + A device may enter the "bus-off" state if too many errors occurred on the CAN bus. Then no more messages are received or sent. An automatic bus-off recovery can be enabled by setting the "restart-ms" to a non-zero value, e.g.: @@ -1125,7 +1110,7 @@ solution for a couple of reasons: CAN FD capable CAN controllers support two different bitrates for the arbitration phase and the payload phase of the CAN FD frame. Therefore a - second bittiming has to be specified in order to enable the CAN FD bitrate. + second bit timing has to be specified in order to enable the CAN FD bitrate. Additionally CAN FD capable CAN controllers support up to 64 bytes of payload. The representation of this length in can_frame.can_dlc and @@ -1150,21 +1135,16 @@ solution for a couple of reasons: 6.7 Supported CAN hardware Please check the "Kconfig" file in "drivers/net/can" to get an actual - list of the support CAN hardware. On the Socket CAN project website + list of the support CAN hardware. On the SocketCAN project website (see chapter 7) there might be further drivers available, also for older kernel versions. -7. Socket CAN resources +7. SocketCAN resources ----------------------- - You can find further resources for Socket CAN like user space tools, - support for old kernel versions, more drivers, mailing lists, etc. - at the BerliOS OSS project website for Socket CAN: - - http://developer.berlios.de/projects/socketcan - - If you have questions, bug fixes, etc., don't hesitate to post them to - the Socketcan-Users mailing list. But please search the archives first. + The Linux CAN / SocketCAN project ressources (project site / mailing list) + are referenced in the MAINTAINERS file in the Linux source tree. + Search for CAN NETWORK [LAYERS|DRIVERS]. 8. Credits ---------- diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt index cdb3e40b9d14..a06b48d2f5cc 100644 --- a/Documentation/networking/filter.txt +++ b/Documentation/networking/filter.txt @@ -1,49 +1,563 @@ -filter.txt: Linux Socket Filtering -Written by: Jay Schulist +Linux Socket Filtering aka Berkeley Packet Filter (BPF) +======================================================= Introduction -============ +------------ - Linux Socket Filtering is derived from the Berkeley -Packet Filter. There are some distinct differences between -the BSD and Linux Kernel Filtering. +Linux Socket Filtering (LSF) is derived from the Berkeley Packet Filter. +Though there are some distinct differences between the BSD and Linux +Kernel filtering, but when we speak of BPF or LSF in Linux context, we +mean the very same mechanism of filtering in the Linux kernel. -Linux Socket Filtering (LSF) allows a user-space program to -attach a filter onto any socket and allow or disallow certain -types of data to come through the socket. LSF follows exactly -the same filter code structure as the BSD Berkeley Packet Filter -(BPF), so referring to the BSD bpf.4 manpage is very helpful in -creating filters. +BPF allows a user-space program to attach a filter onto any socket and +allow or disallow certain types of data to come through the socket. LSF +follows exactly the same filter code structure as BSD's BPF, so referring +to the BSD bpf.4 manpage is very helpful in creating filters. -LSF is much simpler than BPF. One does not have to worry about -devices or anything like that. You simply create your filter -code, send it to the kernel via the SO_ATTACH_FILTER option and -if your filter code passes the kernel check on it, you then -immediately begin filtering data on that socket. +On Linux, BPF is much simpler than on BSD. One does not have to worry +about devices or anything like that. You simply create your filter code, +send it to the kernel via the SO_ATTACH_FILTER option and if your filter +code passes the kernel check on it, you then immediately begin filtering +data on that socket. -You can also detach filters from your socket via the -SO_DETACH_FILTER option. This will probably not be used much -since when you close a socket that has a filter on it the -filter is automagically removed. The other less common case -may be adding a different filter on the same socket where you had another -filter that is still running: the kernel takes care of removing -the old one and placing your new one in its place, assuming your -filter has passed the checks, otherwise if it fails the old filter -will remain on that socket. +You can also detach filters from your socket via the SO_DETACH_FILTER +option. This will probably not be used much since when you close a socket +that has a filter on it the filter is automagically removed. The other +less common case may be adding a different filter on the same socket where +you had another filter that is still running: the kernel takes care of +removing the old one and placing your new one in its place, assuming your +filter has passed the checks, otherwise if it fails the old filter will +remain on that socket. -SO_LOCK_FILTER option allows to lock the filter attached to a -socket. Once set, a filter cannot be removed or changed. This allows -one process to setup a socket, attach a filter, lock it then drop -privileges and be assured that the filter will be kept until the -socket is closed. +SO_LOCK_FILTER option allows to lock the filter attached to a socket. Once +set, a filter cannot be removed or changed. This allows one process to +setup a socket, attach a filter, lock it then drop privileges and be +assured that the filter will be kept until the socket is closed. -Examples -======== +The biggest user of this construct might be libpcap. Issuing a high-level +filter command like `tcpdump -i em1 port 22` passes through the libpcap +internal compiler that generates a structure that can eventually be loaded +via SO_ATTACH_FILTER to the kernel. `tcpdump -i em1 port 22 -ddd` +displays what is being placed into this structure. -Ioctls- -setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter)); -setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &value, sizeof(value)); -setsockopt(sockfd, SOL_SOCKET, SO_LOCK_FILTER, &value, sizeof(value)); +Although we were only speaking about sockets here, BPF in Linux is used +in many more places. There's xt_bpf for netfilter, cls_bpf in the kernel +qdisc layer, SECCOMP-BPF (SECure COMPuting [1]), and lots of other places +such as team driver, PTP code, etc where BPF is being used. -See the BSD bpf.4 manpage and the BSD Packet Filter paper written by -Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory. + [1] Documentation/prctl/seccomp_filter.txt + +Original BPF paper: + +Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new +architecture for user-level packet capture. In Proceedings of the +USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 +Conference Proceedings (USENIX'93). USENIX Association, Berkeley, +CA, USA, 2-2. [http://www.tcpdump.org/papers/bpf-usenix93.pdf] + +Structure +--------- + +User space applications include which contains the +following relevant structures: + +struct sock_filter { /* Filter block */ + __u16 code; /* Actual filter code */ + __u8 jt; /* Jump true */ + __u8 jf; /* Jump false */ + __u32 k; /* Generic multiuse field */ +}; + +Such a structure is assembled as an array of 4-tuples, that contains +a code, jt, jf and k value. jt and jf are jump offsets and k a generic +value to be used for a provided code. + +struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ + unsigned short len; /* Number of filter blocks */ + struct sock_filter __user *filter; +}; + +For socket filtering, a pointer to this structure (as shown in +follow-up example) is being passed to the kernel through setsockopt(2). + +Example +------- + +#include +#include +#include +#include +/* ... */ + +/* From the example above: tcpdump -i em1 port 22 -dd */ +struct sock_filter code[] = { + { 0x28, 0, 0, 0x0000000c }, + { 0x15, 0, 8, 0x000086dd }, + { 0x30, 0, 0, 0x00000014 }, + { 0x15, 2, 0, 0x00000084 }, + { 0x15, 1, 0, 0x00000006 }, + { 0x15, 0, 17, 0x00000011 }, + { 0x28, 0, 0, 0x00000036 }, + { 0x15, 14, 0, 0x00000016 }, + { 0x28, 0, 0, 0x00000038 }, + { 0x15, 12, 13, 0x00000016 }, + { 0x15, 0, 12, 0x00000800 }, + { 0x30, 0, 0, 0x00000017 }, + { 0x15, 2, 0, 0x00000084 }, + { 0x15, 1, 0, 0x00000006 }, + { 0x15, 0, 8, 0x00000011 }, + { 0x28, 0, 0, 0x00000014 }, + { 0x45, 6, 0, 0x00001fff }, + { 0xb1, 0, 0, 0x0000000e }, + { 0x48, 0, 0, 0x0000000e }, + { 0x15, 2, 0, 0x00000016 }, + { 0x48, 0, 0, 0x00000010 }, + { 0x15, 0, 1, 0x00000016 }, + { 0x06, 0, 0, 0x0000ffff }, + { 0x06, 0, 0, 0x00000000 }, +}; + +struct sock_fprog bpf = { + .len = ARRAY_SIZE(code), + .filter = code, +}; + +sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); +if (sock < 0) + /* ... bail out ... */ + +ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); +if (ret < 0) + /* ... bail out ... */ + +/* ... */ +close(sock); + +The above example code attaches a socket filter for a PF_PACKET socket +in order to let all IPv4/IPv6 packets with port 22 pass. The rest will +be dropped for this socket. + +The setsockopt(2) call to SO_DETACH_FILTER doesn't need any arguments +and SO_LOCK_FILTER for preventing the filter to be detached, takes an +integer value with 0 or 1. + +Note that socket filters are not restricted to PF_PACKET sockets only, +but can also be used on other socket families. + +Summary of system calls: + + * setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &val, sizeof(val)); + * setsockopt(sockfd, SOL_SOCKET, SO_DETACH_FILTER, &val, sizeof(val)); + * setsockopt(sockfd, SOL_SOCKET, SO_LOCK_FILTER, &val, sizeof(val)); + +Normally, most use cases for socket filtering on packet sockets will be +covered by libpcap in high-level syntax, so as an application developer +you should stick to that. libpcap wraps its own layer around all that. + +Unless i) using/linking to libpcap is not an option, ii) the required BPF +filters use Linux extensions that are not supported by libpcap's compiler, +iii) a filter might be more complex and not cleanly implementable with +libpcap's compiler, or iv) particular filter codes should be optimized +differently than libpcap's internal compiler does; then in such cases +writing such a filter "by hand" can be of an alternative. For example, +xt_bpf and cls_bpf users might have requirements that could result in +more complex filter code, or one that cannot be expressed with libpcap +(e.g. different return codes for various code paths). Moreover, BPF JIT +implementors may wish to manually write test cases and thus need low-level +access to BPF code as well. + +BPF engine and instruction set +------------------------------ + +Under tools/net/ there's a small helper tool called bpf_asm which can +be used to write low-level filters for example scenarios mentioned in the +previous section. Asm-like syntax mentioned here has been implemented in +bpf_asm and will be used for further explanations (instead of dealing with +less readable opcodes directly, principles are the same). The syntax is +closely modelled after Steven McCanne's and Van Jacobson's BPF paper. + +The BPF architecture consists of the following basic elements: + + Element Description + + A 32 bit wide accumulator + X 32 bit wide X register + M[] 16 x 32 bit wide misc registers aka "scratch memory + store", addressable from 0 to 15 + +A program, that is translated by bpf_asm into "opcodes" is an array that +consists of the following elements (as already mentioned): + + op:16, jt:8, jf:8, k:32 + +The element op is a 16 bit wide opcode that has a particular instruction +encoded. jt and jf are two 8 bit wide jump targets, one for condition +"jump if true", the other one "jump if false". Eventually, element k +contains a miscellaneous argument that can be interpreted in different +ways depending on the given instruction in op. + +The instruction set consists of load, store, branch, alu, miscellaneous +and return instructions that are also represented in bpf_asm syntax. This +table lists all bpf_asm instructions available resp. what their underlying +opcodes as defined in linux/filter.h stand for: + + Instruction Addressing mode Description + + ld 1, 2, 3, 4, 10 Load word into A + ldi 4 Load word into A + ldh 1, 2 Load half-word into A + ldb 1, 2 Load byte into A + ldx 3, 4, 5, 10 Load word into X + ldxi 4 Load word into X + ldxb 5 Load byte into X + + st 3 Store A into M[] + stx 3 Store X into M[] + + jmp 6 Jump to label + ja 6 Jump to label + jeq 7, 8 Jump on k == A + jneq 8 Jump on k != A + jne 8 Jump on k != A + jlt 8 Jump on k < A + jle 8 Jump on k <= A + jgt 7, 8 Jump on k > A + jge 7, 8 Jump on k >= A + jset 7, 8 Jump on k & A + + add 0, 4 A + + sub 0, 4 A - + mul 0, 4 A * + div 0, 4 A / + mod 0, 4 A % + neg 0, 4 !A + and 0, 4 A & + or 0, 4 A | + xor 0, 4 A ^ + lsh 0, 4 A << + rsh 0, 4 A >> + + tax Copy A into X + txa Copy X into A + + ret 4, 9 Return + +The next table shows addressing formats from the 2nd column: + + Addressing mode Syntax Description + + 0 x/%x Register X + 1 [k] BHW at byte offset k in the packet + 2 [x + k] BHW at the offset X + k in the packet + 3 M[k] Word at offset k in M[] + 4 #k Literal value stored in k + 5 4*([k]&0xf) Lower nibble * 4 at byte offset k in the packet + 6 L Jump label L + 7 #k,Lt,Lf Jump to Lt if true, otherwise jump to Lf + 8 #k,Lt Jump to Lt if predicate is true + 9 a/%a Accumulator A + 10 extension BPF extension + +The Linux kernel also has a couple of BPF extensions that are used along +with the class of load instructions by "overloading" the k argument with +a negative offset + a particular extension offset. The result of such BPF +extensions are loaded into A. + +Possible BPF extensions are shown in the following table: + + Extension Description + + len skb->len + proto skb->protocol + type skb->pkt_type + poff Payload start offset + ifidx skb->dev->ifindex + nla Netlink attribute of type X with offset A + nlan Nested Netlink attribute of type X with offset A + mark skb->mark + queue skb->queue_mapping + hatype skb->dev->type + rxhash skb->rxhash + cpu raw_smp_processor_id() + vlan_tci vlan_tx_tag_get(skb) + vlan_pr vlan_tx_tag_present(skb) + +These extensions can also be prefixed with '#'. +Examples for low-level BPF: + +** ARP packets: + + ldh [12] + jne #0x806, drop + ret #-1 + drop: ret #0 + +** IPv4 TCP packets: + + ldh [12] + jne #0x800, drop + ldb [23] + jneq #6, drop + ret #-1 + drop: ret #0 + +** (Accelerated) VLAN w/ id 10: + + ld vlan_tci + jneq #10, drop + ret #-1 + drop: ret #0 + +** SECCOMP filter example: + + ld [4] /* offsetof(struct seccomp_data, arch) */ + jne #0xc000003e, bad /* AUDIT_ARCH_X86_64 */ + ld [0] /* offsetof(struct seccomp_data, nr) */ + jeq #15, good /* __NR_rt_sigreturn */ + jeq #231, good /* __NR_exit_group */ + jeq #60, good /* __NR_exit */ + jeq #0, good /* __NR_read */ + jeq #1, good /* __NR_write */ + jeq #5, good /* __NR_fstat */ + jeq #9, good /* __NR_mmap */ + jeq #14, good /* __NR_rt_sigprocmask */ + jeq #13, good /* __NR_rt_sigaction */ + jeq #35, good /* __NR_nanosleep */ + bad: ret #0 /* SECCOMP_RET_KILL */ + good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ + +The above example code can be placed into a file (here called "foo"), and +then be passed to the bpf_asm tool for generating opcodes, output that xt_bpf +and cls_bpf understands and can directly be loaded with. Example with above +ARP code: + +$ ./bpf_asm foo +4,40 0 0 12,21 0 1 2054,6 0 0 4294967295,6 0 0 0, + +In copy and paste C-like output: + +$ ./bpf_asm -c foo +{ 0x28, 0, 0, 0x0000000c }, +{ 0x15, 0, 1, 0x00000806 }, +{ 0x06, 0, 0, 0xffffffff }, +{ 0x06, 0, 0, 0000000000 }, + +In particular, as usage with xt_bpf or cls_bpf can result in more complex BPF +filters that might not be obvious at first, it's good to test filters before +attaching to a live system. For that purpose, there's a small tool called +bpf_dbg under tools/net/ in the kernel source directory. This debugger allows +for testing BPF filters against given pcap files, single stepping through the +BPF code on the pcap's packets and to do BPF machine register dumps. + +Starting bpf_dbg is trivial and just requires issuing: + +# ./bpf_dbg + +In case input and output do not equal stdin/stdout, bpf_dbg takes an +alternative stdin source as a first argument, and an alternative stdout +sink as a second one, e.g. `./bpf_dbg test_in.txt test_out.txt`. + +Other than that, a particular libreadline configuration can be set via +file "~/.bpf_dbg_init" and the command history is stored in the file +"~/.bpf_dbg_history". + +Interaction in bpf_dbg happens through a shell that also has auto-completion +support (follow-up example commands starting with '>' denote bpf_dbg shell). +The usual workflow would be to ... + +> load bpf 6,40 0 0 12,21 0 3 2048,48 0 0 23,21 0 1 1,6 0 0 65535,6 0 0 0 + Loads a BPF filter from standard output of bpf_asm, or transformed via + e.g. `tcpdump -iem1 -ddd port 22 | tr '\n' ','`. Note that for JIT + debugging (next section), this command creates a temporary socket and + loads the BPF code into the kernel. Thus, this will also be useful for + JIT developers. + +> load pcap foo.pcap + Loads standard tcpdump pcap file. + +> run [] +bpf passes:1 fails:9 + Runs through all packets from a pcap to account how many passes and fails + the filter will generate. A limit of packets to traverse can be given. + +> disassemble +l0: ldh [12] +l1: jeq #0x800, l2, l5 +l2: ldb [23] +l3: jeq #0x1, l4, l5 +l4: ret #0xffff +l5: ret #0 + Prints out BPF code disassembly. + +> dump +/* { op, jt, jf, k }, */ +{ 0x28, 0, 0, 0x0000000c }, +{ 0x15, 0, 3, 0x00000800 }, +{ 0x30, 0, 0, 0x00000017 }, +{ 0x15, 0, 1, 0x00000001 }, +{ 0x06, 0, 0, 0x0000ffff }, +{ 0x06, 0, 0, 0000000000 }, + Prints out C-style BPF code dump. + +> breakpoint 0 +breakpoint at: l0: ldh [12] +> breakpoint 1 +breakpoint at: l1: jeq #0x800, l2, l5 + ... + Sets breakpoints at particular BPF instructions. Issuing a `run` command + will walk through the pcap file continuing from the current packet and + break when a breakpoint is being hit (another `run` will continue from + the currently active breakpoint executing next instructions): + + > run + -- register dump -- + pc: [0] <-- program counter + code: [40] jt[0] jf[0] k[12] <-- plain BPF code of current instruction + curr: l0: ldh [12] <-- disassembly of current instruction + A: [00000000][0] <-- content of A (hex, decimal) + X: [00000000][0] <-- content of X (hex, decimal) + M[0,15]: [00000000][0] <-- folded content of M (hex, decimal) + -- packet dump -- <-- Current packet from pcap (hex) + len: 42 + 0: 00 19 cb 55 55 a4 00 14 a4 43 78 69 08 06 00 01 + 16: 08 00 06 04 00 01 00 14 a4 43 78 69 0a 3b 01 26 + 32: 00 00 00 00 00 00 0a 3b 01 01 + (breakpoint) + > + +> breakpoint +breakpoints: 0 1 + Prints currently set breakpoints. + +> step [-, +] + Performs single stepping through the BPF program from the current pc + offset. Thus, on each step invocation, above register dump is issued. + This can go forwards and backwards in time, a plain `step` will break + on the next BPF instruction, thus +1. (No `run` needs to be issued here.) + +> select + Selects a given packet from the pcap file to continue from. Thus, on + the next `run` or `step`, the BPF program is being evaluated against + the user pre-selected packet. Numbering starts just as in Wireshark + with index 1. + +> quit +# + Exits bpf_dbg. + +JIT compiler +------------ + +The Linux kernel has a built-in BPF JIT compiler for x86_64, SPARC, PowerPC, +ARM and s390 and can be enabled through CONFIG_BPF_JIT. The JIT compiler is +transparently invoked for each attached filter from user space or for internal +kernel users if it has been previously enabled by root: + + echo 1 > /proc/sys/net/core/bpf_jit_enable + +For JIT developers, doing audits etc, each compile run can output the generated +opcode image into the kernel log via: + + echo 2 > /proc/sys/net/core/bpf_jit_enable + +Example output from dmesg: + +[ 3389.935842] flen=6 proglen=70 pass=3 image=ffffffffa0069c8f +[ 3389.935847] JIT code: 00000000: 55 48 89 e5 48 83 ec 60 48 89 5d f8 44 8b 4f 68 +[ 3389.935849] JIT code: 00000010: 44 2b 4f 6c 4c 8b 87 d8 00 00 00 be 0c 00 00 00 +[ 3389.935850] JIT code: 00000020: e8 1d 94 ff e0 3d 00 08 00 00 75 16 be 17 00 00 +[ 3389.935851] JIT code: 00000030: 00 e8 28 94 ff e0 83 f8 01 75 07 b8 ff ff 00 00 +[ 3389.935852] JIT code: 00000040: eb 02 31 c0 c9 c3 + +In the kernel source tree under tools/net/, there's bpf_jit_disasm for +generating disassembly out of the kernel log's hexdump: + +# ./bpf_jit_disasm +70 bytes emitted from JIT compiler (pass:3, flen:6) +ffffffffa0069c8f + : + 0: push %rbp + 1: mov %rsp,%rbp + 4: sub $0x60,%rsp + 8: mov %rbx,-0x8(%rbp) + c: mov 0x68(%rdi),%r9d + 10: sub 0x6c(%rdi),%r9d + 14: mov 0xd8(%rdi),%r8 + 1b: mov $0xc,%esi + 20: callq 0xffffffffe0ff9442 + 25: cmp $0x800,%eax + 2a: jne 0x0000000000000042 + 2c: mov $0x17,%esi + 31: callq 0xffffffffe0ff945e + 36: cmp $0x1,%eax + 39: jne 0x0000000000000042 + 3b: mov $0xffff,%eax + 40: jmp 0x0000000000000044 + 42: xor %eax,%eax + 44: leaveq + 45: retq + +Issuing option `-o` will "annotate" opcodes to resulting assembler +instructions, which can be very useful for JIT developers: + +# ./bpf_jit_disasm -o +70 bytes emitted from JIT compiler (pass:3, flen:6) +ffffffffa0069c8f + : + 0: push %rbp + 55 + 1: mov %rsp,%rbp + 48 89 e5 + 4: sub $0x60,%rsp + 48 83 ec 60 + 8: mov %rbx,-0x8(%rbp) + 48 89 5d f8 + c: mov 0x68(%rdi),%r9d + 44 8b 4f 68 + 10: sub 0x6c(%rdi),%r9d + 44 2b 4f 6c + 14: mov 0xd8(%rdi),%r8 + 4c 8b 87 d8 00 00 00 + 1b: mov $0xc,%esi + be 0c 00 00 00 + 20: callq 0xffffffffe0ff9442 + e8 1d 94 ff e0 + 25: cmp $0x800,%eax + 3d 00 08 00 00 + 2a: jne 0x0000000000000042 + 75 16 + 2c: mov $0x17,%esi + be 17 00 00 00 + 31: callq 0xffffffffe0ff945e + e8 28 94 ff e0 + 36: cmp $0x1,%eax + 83 f8 01 + 39: jne 0x0000000000000042 + 75 07 + 3b: mov $0xffff,%eax + b8 ff ff 00 00 + 40: jmp 0x0000000000000044 + eb 02 + 42: xor %eax,%eax + 31 c0 + 44: leaveq + c9 + 45: retq + c3 + +For BPF JIT developers, bpf_jit_disasm, bpf_asm and bpf_dbg provides a useful +toolchain for developing and testing the kernel's JIT compiler. + +Misc +---- + +Also trinity, the Linux syscall fuzzer, has built-in support for BPF and +SECCOMP-BPF kernel fuzzing. + +Written by +---------- + +The document was written in the hope that it is found useful and in order +to give potential BPF hackers or security auditors a better overview of +the underlying architecture. + +Jay Schulist +Daniel Borkmann diff --git a/Documentation/networking/i40evf.txt b/Documentation/networking/i40evf.txt new file mode 100644 index 000000000000..21e41271af79 --- /dev/null +++ b/Documentation/networking/i40evf.txt @@ -0,0 +1,47 @@ +Linux* Base Driver for Intel(R) Network Connection +================================================== + +Intel XL710 X710 Virtual Function Linux driver. +Copyright(c) 2013 Intel Corporation. + +Contents +======== + +- Identifying Your Adapter +- Known Issues/Troubleshooting +- Support + +This file describes the i40evf Linux* Base Driver for the Intel(R) XL710 +X710 Virtual Function. + +The i40evf driver supports XL710 and X710 virtual function devices that +can only be activated on kernels with CONFIG_PCI_IOV enabled. + +The guest OS loading the i40evf driver must support MSI-X interrupts. + +Identifying Your Adapter +======================== + +For more information on how to identify your adapter, go to the Adapter & +Driver ID Guide at: + + http://support.intel.com/support/go/network/adapter/idguide.htm + +Known Issues/Troubleshooting +============================ + + +Support +======= + +For general information, go to the Intel support website at: + + http://support.intel.com + +or the Intel Wired Networking project hosted by Sourceforge at: + + http://sourceforge.net/projects/e1000 + +If an issue is identified with the released source code on the supported +kernel with a supported adapter, email the specific information related +to the issue to e1000-devel@lists.sf.net diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 8a984e994e61..5de03740cdd5 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -15,17 +15,47 @@ ip_default_ttl - INTEGER forwarded) IP packets. Should be between 1 and 255 inclusive. Default: 64 (as recommended by RFC1700) -ip_no_pmtu_disc - BOOLEAN - Disable Path MTU Discovery. If enabled and a +ip_no_pmtu_disc - INTEGER + Disable Path MTU Discovery. If enabled in mode 1 and a fragmentation-required ICMP is received, the PMTU to this destination will be set to min_pmtu (see below). You will need to raise min_pmtu to the smallest interface MTU on your system manually if you want to avoid locally generated fragments. + + In mode 2 incoming Path MTU Discovery messages will be + discarded. Outgoing frames are handled the same as in mode 1, + implicitly setting IP_PMTUDISC_DONT on every created socket. + + Mode 3 is a hardend pmtu discover mode. The kernel will only + accept fragmentation-needed errors if the underlying protocol + can verify them besides a plain socket lookup. Current + protocols for which pmtu events will be honored are TCP, SCTP + and DCCP as they verify e.g. the sequence number or the + association. This mode should not be enabled globally but is + only intended to secure e.g. name servers in namespaces where + TCP path mtu must still work but path MTU information of other + protocols should be discarded. If enabled globally this mode + could break other protocols. + + Possible values: 0-3 Default: FALSE min_pmtu - INTEGER default 552 - minimum discovered Path MTU +ip_forward_use_pmtu - BOOLEAN + By default we don't trust protocol path MTUs while forwarding + because they could be easily forged and can lead to unwanted + fragmentation by the router. + You only need to enable this if you have user-space software + which tries to discover path mtus by itself and depends on the + kernel honoring this information. This is normally not the + case. + Default: 0 (disabled) + Possible values: + 0 - disabled + 1 - enabled + route/max_size - INTEGER Maximum number of routes allowed in the kernel. Increase this when using large numbers of interfaces and/or routes. @@ -160,6 +190,16 @@ tcp_app_win - INTEGER buffer. Value 0 is special, it means that nothing is reserved. Default: 31 +tcp_autocorking - BOOLEAN + Enable TCP auto corking : + When applications do consecutive small write()/sendmsg() system calls, + we try to coalesce these small writes as much as possible, to lower + total amount of sent packets. This is done if at least one prior + packet for the flow is waiting in Qdisc queues or device transmit + queue. Applications can still use TCP_CORK for optimal behavior + when they know how/when to uncork their sockets. + Default : 1 + tcp_available_congestion_control - STRING Shows the available congestion control choices that are registered. More congestion control algorithms may be available as modules, @@ -1078,6 +1118,21 @@ bindv6only - BOOLEAN Default: FALSE (as specified in RFC3493) +flowlabel_consistency - BOOLEAN + Protect the consistency (and unicity) of flow label. + You have to disable it to use IPV6_FL_F_REFLECT flag on the + flow label manager. + TRUE: enabled + FALSE: disabled + Default: TRUE + +anycast_src_echo_reply - BOOLEAN + Controls the use of anycast addresses as source addresses for ICMPv6 + echo reply + TRUE: enabled + FALSE: disabled + Default: FALSE + IPv6 Fragmentation: ip6frag_high_thresh - INTEGER diff --git a/Documentation/networking/ipsec.txt b/Documentation/networking/ipsec.txt new file mode 100644 index 000000000000..8dbc08b7e431 --- /dev/null +++ b/Documentation/networking/ipsec.txt @@ -0,0 +1,38 @@ + +Here documents known IPsec corner cases which need to be keep in mind when +deploy various IPsec configuration in real world production environment. + +1. IPcomp: Small IP packet won't get compressed at sender, and failed on + policy check on receiver. + +Quote from RFC3173: +2.2. Non-Expansion Policy + + If the total size of a compressed payload and the IPComp header, as + defined in section 3, is not smaller than the size of the original + payload, the IP datagram MUST be sent in the original non-compressed + form. To clarify: If an IP datagram is sent non-compressed, no + + IPComp header is added to the datagram. This policy ensures saving + the decompression processing cycles and avoiding incurring IP + datagram fragmentation when the expanded datagram is larger than the + MTU. + + Small IP datagrams are likely to expand as a result of compression. + Therefore, a numeric threshold should be applied before compression, + where IP datagrams of size smaller than the threshold are sent in the + original form without attempting compression. The numeric threshold + is implementation dependent. + +Current IPComp implementation is indeed by the book, while as in practice +when sending non-compressed packet to the peer(whether or not packet len +is smaller than the threshold or the compressed len is large than original +packet len), the packet is dropped when checking the policy as this packet +matches the selector but not coming from any XFRM layer, i.e., with no +security path. Such naked packet will not eventually make it to upper layer. +The result is much more wired to the user when ping peer with different +payload length. + +One workaround is try to set "level use" for each policy if user observed +above scenario. The consequence of doing so is small packet(uncompressed) +will skip policy checking on receiver side. diff --git a/Documentation/networking/packet_mmap.txt b/Documentation/networking/packet_mmap.txt index 8e48e3b14227..91ffe1d9e8ca 100644 --- a/Documentation/networking/packet_mmap.txt +++ b/Documentation/networking/packet_mmap.txt @@ -98,6 +98,11 @@ by the kernel. The destruction of the socket and all associated resources is done by a simple call to close(fd). +Similarly as without PACKET_MMAP, it is possible to use one socket +for capture and transmission. This can be done by mapping the +allocated RX and TX buffer ring with a single mmap() call. +See "Mapping and use of the circular buffer (ring)". + Next I will describe PACKET_MMAP settings and its constraints, also the mapping of the circular buffer in the user process and the use of this buffer. @@ -414,6 +419,19 @@ tp_block_size/tp_frame_size frames there will be a gap between the frames. This is because a frame cannot be spawn across two blocks. +To use one socket for capture and transmission, the mapping of both the +RX and TX buffer ring has to be done with one call to mmap: + + ... + setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &foo, sizeof(foo)); + setsockopt(fd, SOL_PACKET, PACKET_TX_RING, &bar, sizeof(bar)); + ... + rx_ring = mmap(0, size * 2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + tx_ring = rx_ring + size; + +RX must be the first as the kernel maps the TX ring memory right +after the RX one. + At the beginning of each frame there is an status field (see struct tpacket_hdr). If this field is 0 means that the frame is ready to be used for the kernel, If not, there is a frame the user can read @@ -517,8 +535,6 @@ where 'tpacket_version' can be TPACKET_V1 (default), TPACKET_V2, TPACKET_V3. TPACKET_V1: - Default if not otherwise specified by setsockopt(2) - RX_RING, TX_RING available - - VLAN metadata information available for packets - (TP_STATUS_VLAN_VALID) TPACKET_V1 --> TPACKET_V2: - Made 64 bit clean due to unsigned long usage in TPACKET_V1 @@ -526,6 +542,13 @@ TPACKET_V1 --> TPACKET_V2: userspace and the like - Timestamp resolution in nanoseconds instead of microseconds - RX_RING, TX_RING available + - VLAN metadata information available for packets + (TP_STATUS_VLAN_VALID, TP_STATUS_VLAN_TPID_VALID), + in the tpacket2_hdr structure: + - TP_STATUS_VLAN_VALID bit being set into the tp_status field indicates + that the tp_vlan_tci field has valid VLAN TCI value + - TP_STATUS_VLAN_TPID_VALID bit being set into the tp_status field + indicates that the tp_vlan_tpid field has valid VLAN TPID value - How to switch to TPACKET_V2: 1. Replace struct tpacket_hdr by struct tpacket2_hdr 2. Query header len and save @@ -952,6 +975,27 @@ int main(int argc, char **argp) return 0; } +------------------------------------------------------------------------------- ++ PACKET_QDISC_BYPASS +------------------------------------------------------------------------------- + +If there is a requirement to load the network with many packets in a similar +fashion as pktgen does, you might set the following option after socket +creation: + + int one = 1; + setsockopt(fd, SOL_PACKET, PACKET_QDISC_BYPASS, &one, sizeof(one)); + +This has the side-effect, that packets sent through PF_PACKET will bypass the +kernel's qdisc layer and are forcedly pushed to the driver directly. Meaning, +packet are not buffered, tc disciplines are ignored, increased loss can occur +and such packets are also not visible to other PF_PACKET sockets anymore. So, +you have been warned; generally, this can be useful for stress testing various +components of a system. + +On default, PACKET_QDISC_BYPASS is disabled and needs to be explicitly enabled +on PF_PACKET sockets. + ------------------------------------------------------------------------------- + PACKET_TIMESTAMP ------------------------------------------------------------------------------- diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt index d5b1a3935245..ebf270719402 100644 --- a/Documentation/networking/phy.txt +++ b/Documentation/networking/phy.txt @@ -255,7 +255,8 @@ Writing a PHY driver config_init: configures PHY into a sane state after a reset. For instance, a Davicom PHY requires descrambling disabled. - probe: Does any setup needed by the driver + probe: Allocate phy->priv, optionally refuse to bind. + PHY may not have been reset or had fixups run yet. suspend/resume: power management config_aneg: Changes the speed/duplex/negotiation settings read_status: Reads the current speed/duplex/negotiation settings diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt index 75e4fd708ccb..5a61a240a652 100644 --- a/Documentation/networking/pktgen.txt +++ b/Documentation/networking/pktgen.txt @@ -108,7 +108,9 @@ Examples: MPLS_RND, VID_RND, SVID_RND QUEUE_MAP_RND # queue map random QUEUE_MAP_CPU # queue map mirrors smp_processor_id() + IPSEC # Make IPsec encapsulation for packet + pgset spi SPI_VALUE Set specific SA used to transform packet. pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then cycle through the port range. @@ -177,6 +179,18 @@ Note when adding devices to a specific CPU there good idea to also assign /proc/irq/XX/smp_affinity so the TX-interrupts gets bound to the same CPU. as this reduces cache bouncing when freeing skb's. +Enable IPsec +============ +Default IPsec transformation with ESP encapsulation plus Transport mode +could be enabled by simply setting: + +pgset "flag IPSEC" +pgset "flows 1" + +To avoid breaking existing testbed scripts for using AH type and tunnel mode, +user could use "pgset spi SPI_VALUE" to specify which formal of transformation +to employ. + Current commands and configuration options ========================================== @@ -225,6 +239,7 @@ flag UDPDST_RND MACSRC_RND MACDST_RND + IPSEC dst_min dst_max diff --git a/Documentation/networking/regulatory.txt b/Documentation/networking/regulatory.txt index 9551622d0a7b..356f791af574 100644 --- a/Documentation/networking/regulatory.txt +++ b/Documentation/networking/regulatory.txt @@ -159,10 +159,10 @@ struct ieee80211_regdomain mydriver_jp_regdom = { REG_RULE(2412-20, 2484+20, 40, 6, 20, 0), /* IEEE 802.11a, channels 34..48 */ REG_RULE(5170-20, 5240+20, 40, 6, 20, - NL80211_RRF_PASSIVE_SCAN), + NL80211_RRF_NO_IR), /* IEEE 802.11a, channels 52..64 */ REG_RULE(5260-20, 5320+20, 40, 6, 20, - NL80211_RRF_NO_IBSS | + NL80211_RRF_NO_IR| NL80211_RRF_DFS), } }; diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index cdd916da838d..2090895b08d4 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -127,8 +127,9 @@ struct plat_stmmacenet_data { int riwt_off; void (*fix_mac_speed)(void *priv, unsigned int speed); void (*bus_setup)(void __iomem *ioaddr); - int (*init)(struct platform_device *pdev); - void (*exit)(struct platform_device *pdev); + void *(*setup)(struct platform_device *pdev); + int (*init)(struct platform_device *pdev, void *priv); + void (*exit)(struct platform_device *pdev, void *priv); void *custom_cfg; void *custom_data; void *bsp_priv; @@ -169,10 +170,13 @@ Where: o bus_setup: perform HW setup of the bus. For example, on some ST platforms this field is used to configure the AMBA bridge to generate more efficient STBus traffic. - o init/exit: callbacks used for calling a custom initialization; + o setup/init/exit: callbacks used for calling a custom initialization; this is sometime necessary on some platforms (e.g. ST boxes) where the HW needs to have set some PIO lines or system cfg - registers. + registers. setup should return a pointer to private data, + which will be stored in bsp_priv, and then passed to init and + exit callbacks. init/exit callbacks should not use or modify + platform data. o custom_cfg/custom_data: this is a custom configuration that can be passed while initializing the resources. o bsp_priv: another private pointer. diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt index 98097d8cb910..661d3c316a17 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt @@ -85,7 +85,7 @@ Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support by the network device and will be empty without that support. -SIOCSHWTSTAMP: +SIOCSHWTSTAMP, SIOCGHWTSTAMP: Hardware time stamping must also be initialized for each device driver that is expected to do hardware time stamping. The parameter is defined in @@ -115,6 +115,10 @@ Only a processes with admin rights may change the configuration. User space is responsible to ensure that multiple processes don't interfere with each other and that the settings are reset. +Any process can read the actual configuration by passing this +structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has +not been implemented in all drivers. + /* possible values for hwtstamp_config->tx_type */ enum { /* @@ -157,7 +161,8 @@ DEVICE IMPLEMENTATION A driver which supports hardware time stamping must support the SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with -the actual values as described in the section on SIOCSHWTSTAMP. +the actual values as described in the section on SIOCSHWTSTAMP. It +should also support SIOCGHWTSTAMP. Time stamps for received packets must be stored in the skb. To get a pointer to the shared time stamp structure of the skb call skb_hwtstamps(). Then diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore index 71e81eb2e22f..a380159765ce 100644 --- a/Documentation/networking/timestamping/.gitignore +++ b/Documentation/networking/timestamping/.gitignore @@ -1 +1,2 @@ timestamping +hwtstamp_config diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile index e79973443e9f..d934afc8306a 100644 --- a/Documentation/networking/timestamping/Makefile +++ b/Documentation/networking/timestamping/Makefile @@ -2,12 +2,13 @@ obj- := dummy.o # List of programs to build -hostprogs-y := timestamping +hostprogs-y := timestamping hwtstamp_config # Tell kbuild to always build the programs always := $(hostprogs-y) HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include +HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include clean: - rm -f timestamping + rm -f timestamping hwtstamp_config diff --git a/Documentation/networking/timestamping/hwtstamp_config.c b/Documentation/networking/timestamping/hwtstamp_config.c new file mode 100644 index 000000000000..e8b685a7f15f --- /dev/null +++ b/Documentation/networking/timestamping/hwtstamp_config.c @@ -0,0 +1,134 @@ +/* Test program for SIOC{G,S}HWTSTAMP + * Copyright 2013 Solarflare Communications + * Author: Ben Hutchings + */ + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static int +lookup_value(const char **names, int size, const char *name) +{ + int value; + + for (value = 0; value < size; value++) + if (names[value] && strcasecmp(names[value], name) == 0) + return value; + + return -1; +} + +static const char * +lookup_name(const char **names, int size, int value) +{ + return (value >= 0 && value < size) ? names[value] : NULL; +} + +static void list_names(FILE *f, const char **names, int size) +{ + int value; + + for (value = 0; value < size; value++) + if (names[value]) + fprintf(f, " %s\n", names[value]); +} + +static const char *tx_types[] = { +#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name + TX_TYPE(OFF), + TX_TYPE(ON), + TX_TYPE(ONESTEP_SYNC) +#undef TX_TYPE +}; +#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0]))) + +static const char *rx_filters[] = { +#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name + RX_FILTER(NONE), + RX_FILTER(ALL), + RX_FILTER(SOME), + RX_FILTER(PTP_V1_L4_EVENT), + RX_FILTER(PTP_V1_L4_SYNC), + RX_FILTER(PTP_V1_L4_DELAY_REQ), + RX_FILTER(PTP_V2_L4_EVENT), + RX_FILTER(PTP_V2_L4_SYNC), + RX_FILTER(PTP_V2_L4_DELAY_REQ), + RX_FILTER(PTP_V2_L2_EVENT), + RX_FILTER(PTP_V2_L2_SYNC), + RX_FILTER(PTP_V2_L2_DELAY_REQ), + RX_FILTER(PTP_V2_EVENT), + RX_FILTER(PTP_V2_SYNC), + RX_FILTER(PTP_V2_DELAY_REQ), +#undef RX_FILTER +}; +#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0]))) + +static void usage(void) +{ + fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n" + "tx_type is any of (case-insensitive):\n", + stderr); + list_names(stderr, tx_types, N_TX_TYPES); + fputs("rx_filter is any of (case-insensitive):\n", stderr); + list_names(stderr, rx_filters, N_RX_FILTERS); +} + +int main(int argc, char **argv) +{ + struct ifreq ifr; + struct hwtstamp_config config; + const char *name; + int sock; + + if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) { + usage(); + return 2; + } + + if (argc == 4) { + config.flags = 0; + config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]); + config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]); + if (config.tx_type < 0 || config.rx_filter < 0) { + usage(); + return 2; + } + } + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + perror("socket"); + return 1; + } + + strcpy(ifr.ifr_name, argv[1]); + ifr.ifr_data = (caddr_t)&config; + + if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) { + perror("ioctl"); + return 1; + } + + printf("flags = %#x\n", config.flags); + name = lookup_name(tx_types, N_TX_TYPES, config.tx_type); + if (name) + printf("tx_type = %s\n", name); + else + printf("tx_type = %d\n", config.tx_type); + name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter); + if (name) + printf("rx_filter = %s\n", name); + else + printf("rx_filter = %d\n", config.rx_filter); + + return 0; +} diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index a7929cb47e7c..23f1590f49fe 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -18,7 +18,7 @@ Definition of PIN CONTROLLER: - A pin controller is a piece of hardware, usually a set of registers, that can control PINs. It may be able to multiplex, bias, set load capacitance, - set drive strength etc for individual pins or groups of pins. + set drive strength, etc. for individual pins or groups of pins. Definition of PIN: @@ -90,7 +90,7 @@ selected drivers, you need to select them from your machine's Kconfig entry, since these are so tightly integrated with the machines they are used on. See for example arch/arm/mach-u300/Kconfig for an example. -Pins usually have fancier names than this. You can find these in the dataheet +Pins usually have fancier names than this. You can find these in the datasheet for your chip. Notice that the core pinctrl.h file provides a fancy macro called PINCTRL_PIN() to create the struct entries. As you can see I enumerated the pins from 0 in the upper left corner to 63 in the lower right corner. @@ -185,7 +185,7 @@ static struct pinctrl_desc foo_desc = { }; The pin control subsystem will call the .get_groups_count() function to -determine total number of legal selectors, then it will call the other functions +determine the total number of legal selectors, then it will call the other functions to retrieve the name and pins of the group. Maintaining the data structure of the groups is up to the driver, this is just a simple example - in practice you may need more entries in your group structure, for example specific register @@ -195,7 +195,7 @@ ranges associated with each group and so on. Pin configuration ================= -Pins can sometimes be software-configured in an various ways, mostly related +Pins can sometimes be software-configured in various ways, mostly related to their electronic properties when used as inputs or outputs. For example you may be able to make an output pin high impedance, or "tristate" meaning it is effectively disconnected. You may be able to connect an input pin to VDD or GND @@ -291,7 +291,7 @@ Since the pin controller subsystem have its pinspace local to the pin controller we need a mapping so that the pin control subsystem can figure out which pin controller handles control of a certain GPIO pin. Since a single pin controller may be muxing several GPIO ranges (typically SoCs that have -one set of pins but internally several GPIO silicon blocks, each modelled as +one set of pins, but internally several GPIO silicon blocks, each modelled as a struct gpio_chip) any number of GPIO ranges can be added to a pin controller instance like this: @@ -373,9 +373,9 @@ will be called on that specific pin controller. For all functionalities dealing with pin biasing, pin muxing etc, the pin controller subsystem will look up the corresponding pin number from the passed -in gpio number, and use the range's internals to retrive a pin number. After +in gpio number, and use the range's internals to retrieve a pin number. After that, the subsystem passes it on to the pin control driver, so the driver -will get an pin number into its handled number range. Further it is also passed +will get a pin number into its handled number range. Further it is also passed the range ID value, so that the pin controller knows which range it should deal with. @@ -430,8 +430,8 @@ pins you see some will be taken by things like a few VCC and GND to feed power to the chip, and quite a few will be taken by large ports like an external memory interface. The remaining pins will often be subject to pin multiplexing. -The example 8x8 PGA package above will have pin numbers 0 thru 63 assigned to -its physical pins. It will name the pins { A1, A2, A3 ... H6, H7, H8 } using +The example 8x8 PGA package above will have pin numbers 0 through 63 assigned +to its physical pins. It will name the pins { A1, A2, A3 ... H6, H7, H8 } using pinctrl_register_pins() and a suitable data set as shown earlier. In this 8x8 BGA package the pins { A8, A7, A6, A5 } can be used as an SPI port @@ -442,7 +442,7 @@ we cannot use the SPI port and I2C port at the same time. However in the inside of the package the silicon performing the SPI logic can alternatively be routed out on pins { G4, G3, G2, G1 }. -On the botton row at { A1, B1, C1, D1, E1, F1, G1, H1 } we have something +On the bottom row at { A1, B1, C1, D1, E1, F1, G1, H1 } we have something special - it's an external MMC bus that can be 2, 4 or 8 bits wide, and it will consume 2, 4 or 8 pins respectively, so either { A1, B1 } are taken or { A1, B1, C1, D1 } or all of them. If we use all 8 bits, we cannot use the SPI @@ -549,7 +549,7 @@ Assumptions: We assume that the number of possible function maps to pin groups is limited by the hardware. I.e. we assume that there is no system where any function can be -mapped to any pin, like in a phone exchange. So the available pins groups for +mapped to any pin, like in a phone exchange. So the available pin groups for a certain function will be limited to a few choices (say up to eight or so), not hundreds or any amount of choices. This is the characteristic we have found by inspecting available pinmux hardware, and a necessary assumption since we @@ -564,7 +564,7 @@ The pinmux core takes care of preventing conflicts on pins and calling the pin controller driver to execute different settings. It is the responsibility of the pinmux driver to impose further restrictions -(say for example infer electronic limitations due to load etc) to determine +(say for example infer electronic limitations due to load, etc.) to determine whether or not the requested function can actually be allowed, and in case it is possible to perform the requested mux setting, poke the hardware so that this happens. @@ -755,7 +755,7 @@ Pin control interaction with the GPIO subsystem Note that the following implies that the use case is to use a certain pin from the Linux kernel using the API in with gpio_request() and similar functions. There are cases where you may be using something -that your datasheet calls "GPIO mode" but actually is just an electrical +that your datasheet calls "GPIO mode", but actually is just an electrical configuration for a certain device. See the section below named "GPIO mode pitfalls" for more details on this scenario. @@ -871,7 +871,7 @@ hardware and shall be put into different subsystems: - Registers (or fields within registers) that control muxing of signals from various other HW blocks (e.g. I2C, MMC, or GPIO) onto pins should - be exposed through the pinctrl subssytem, as mux functions. + be exposed through the pinctrl subsystem, as mux functions. - Registers (or fields within registers) that control GPIO functionality such as setting a GPIO's output value, reading a GPIO's input value, or @@ -895,7 +895,7 @@ Example: a pin is usually muxed in to be used as a UART TX line. But during system sleep, we need to put this pin into "GPIO mode" and ground it. If you make a 1-to-1 map to the GPIO subsystem for this pin, you may start -to think that you need to come up with something real complex, that the +to think that you need to come up with something really complex, that the pin shall be used for UART TX and GPIO at the same time, that you will grab a pin control handle and set it to a certain state to enable UART TX to be muxed in, then twist it over to GPIO mode and use gpio_direction_output() @@ -964,12 +964,12 @@ GPIO mode. This will give the desired effect without any bogus interaction with the GPIO subsystem. It is just an electrical configuration used by that device when going to sleep, it might imply that the pin is set into something the -datasheet calls "GPIO mode" but that is not the point: it is still used +datasheet calls "GPIO mode", but that is not the point: it is still used by that UART device to control the pins that pertain to that very UART driver, putting them into modes needed by the UART. GPIO in the Linux kernel sense are just some 1-bit line, and is a different use case. -How the registers are poked to attain the push/pull and output low +How the registers are poked to attain the push or pull, and output low configuration and the muxing of the "u0" or "gpio-mode" group onto these pins is a question for the driver. @@ -977,7 +977,7 @@ Some datasheets will be more helpful and refer to the "GPIO mode" as "low power mode" rather than anything to do with GPIO. This often means the same thing electrically speaking, but in this latter case the software engineers will usually quickly identify that this is some -specific muxing/configuration rather than anything related to the GPIO +specific muxing or configuration rather than anything related to the GPIO API. @@ -1024,8 +1024,7 @@ up the device struct (just like with clockdev or regulators). The function name must match a function provided by the pinmux driver handling this pin range. As you can see we may have several pin controllers on the system and thus -we need to specify which one of them that contain the functions we wish -to map. +we need to specify which one of them contains the functions we wish to map. You register this pinmux mapping to the pinmux subsystem by simply: @@ -1254,10 +1253,10 @@ The semantics of the pinctrl APIs are: pinctrl_get(). - pinctrl_lookup_state() is called in process context to obtain a handle to a - specific state for a the client device. This operation may be slow too. + specific state for a client device. This operation may be slow, too. - pinctrl_select_state() programs pin controller hardware according to the - definition of the state as given by the mapping table. In theory this is a + definition of the state as given by the mapping table. In theory, this is a fast-path operation, since it only involved blasting some register settings into hardware. However, note that some pin controllers may have their registers on a slow/IRQ-based bus, so client devices should not assume they diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 445ad743ec81..6f4eb322ffaf 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -55,14 +55,21 @@ Struct Resources: For printing struct resources. The 'R' and 'r' specifiers result in a printed resource with ('R') or without ('r') a decoded flags member. -Physical addresses: +Physical addresses types phys_addr_t: - %pa 0x01234567 or 0x0123456789abcdef + %pa[p] 0x01234567 or 0x0123456789abcdef For printing a phys_addr_t type (and its derivatives, such as resource_size_t) which can vary based on build options, regardless of the width of the CPU data path. Passed by reference. +DMA addresses types dma_addr_t: + + %pad 0x01234567 or 0x0123456789abcdef + + For printing a dma_addr_t type which can vary based on build options, + regardless of the width of the CPU data path. Passed by reference. + Raw buffer as a hex string: %*ph 00 01 02 ... 3f %*phC 00:01:02: ... :3f diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 03c9d9299c6b..f430004df73c 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt @@ -71,7 +71,7 @@ To create an rfkill driver, driver's Kconfig needs to have depends on RFKILL || !RFKILL to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL -case allows the driver to be built when rfkill is not configured, which which +case allows the driver to be built when rfkill is not configured, which case all rfkill API can still be used but will be provided by static inlines which compile to almost nothing. diff --git a/Documentation/robust-futex-ABI.txt b/Documentation/robust-futex-ABI.txt index fd1cd8aae4eb..16eb314f56cc 100644 --- a/Documentation/robust-futex-ABI.txt +++ b/Documentation/robust-futex-ABI.txt @@ -146,8 +146,8 @@ On removal: 1) set the 'list_op_pending' word to the address of the 'lock entry' to be removed, 2) remove the lock entry for this lock from the 'head' list, - 2) release the futex lock, and - 2) clear the 'lock_op_pending' word. + 3) release the futex lock, and + 4) clear the 'lock_op_pending' word. On exit, the kernel will consider the address stored in 'list_op_pending' and the address of each 'lock word' found by walking diff --git a/Documentation/rt-mutex-design.txt b/Documentation/rt-mutex-design.txt index a5bcd7f5c33f..8666070d3189 100644 --- a/Documentation/rt-mutex-design.txt +++ b/Documentation/rt-mutex-design.txt @@ -30,7 +30,7 @@ is something called unbounded priority inversion. That is when the high priority process is prevented from running by a lower priority process for an undetermined amount of time. -The classic example of unbounded priority inversion is were you have three +The classic example of unbounded priority inversion is where you have three processes, let's call them processes A, B, and C, where A is the highest priority process, C is the lowest, and B is in between. A tries to grab a lock that C owns and must wait and lets C run to release the lock. But in the diff --git a/Documentation/s390/qeth.txt b/Documentation/s390/qeth.txt new file mode 100644 index 000000000000..74122ada9949 --- /dev/null +++ b/Documentation/s390/qeth.txt @@ -0,0 +1,50 @@ +IBM s390 QDIO Ethernet Driver + +HiperSockets Bridge Port Support + +Uevents + +To generate the events the device must be assigned a role of either +a primary or a secondary Bridge Port. For more information, see +"z/VM Connectivity, SC24-6174". + +When run on HiperSockets Bridge Capable Port hardware, and the state +of some configured Bridge Port device on the channel changes, a udev +event with ACTION=CHANGE is emitted on behalf of the corresponding +ccwgroup device. The event has the following attributes: + +BRIDGEPORT=statechange - indicates that the Bridge Port device changed + its state. + +ROLE={primary|secondary|none} - the role assigned to the port. + +STATE={active|standby|inactive} - the newly assumed state of the port. + +When run on HiperSockets Bridge Capable Port hardware with host address +notifications enabled, a udev event with ACTION=CHANGE is emitted. +It is emitted on behalf of the corresponding ccwgroup device when a host +or a VLAN is registered or unregistered on the network served by the device. +The event has the following attributes: + +BRIDGEDHOST={reset|register|deregister|abort} - host address + notifications are started afresh, a new host or VLAN is registered or + deregistered on the Bridge Port HiperSockets channel, or address + notifications are aborted. + +VLAN=numeric-vlan-id - VLAN ID on which the event occurred. Not included + if no VLAN is involved in the event. + +MAC=xx:xx:xx:xx:xx:xx - MAC address of the host that is being registered + or deregistered from the HiperSockets channel. Not reported if the + event reports the creation or destruction of a VLAN. + +NTOK_BUSID=x.y.zzzz - device bus ID (CSSID, SSID and device number). + +NTOK_IID=xx - device IID. + +NTOK_CHPID=xx - device CHPID. + +NTOK_CHID=xxxx - device channel ID. + +Note that the NTOK_* attributes refer to devices other than the one +connected to the system on which the OS is running. diff --git a/Documentation/scsi/00-INDEX b/Documentation/scsi/00-INDEX index 9b0787f965e9..2044be565d93 100644 --- a/Documentation/scsi/00-INDEX +++ b/Documentation/scsi/00-INDEX @@ -42,8 +42,6 @@ aic79xx.txt - Adaptec Ultra320 SCSI host adapters aic7xxx.txt - info on driver for Adaptec controllers -aic7xxx_old.txt - - info on driver for Adaptec controllers, old generation arcmsr_spec.txt - ARECA FIRMWARE SPEC (for IOP331 adapter) dc395x.txt diff --git a/Documentation/scsi/aic7xxx_old.txt b/Documentation/scsi/aic7xxx_old.txt deleted file mode 100644 index ecfc474f36a8..000000000000 --- a/Documentation/scsi/aic7xxx_old.txt +++ /dev/null @@ -1,511 +0,0 @@ - AIC7xxx Driver for Linux - -Introduction ----------------------------- -The AIC7xxx SCSI driver adds support for Adaptec (http://www.adaptec.com) -SCSI controllers and chipsets. Major portions of the driver and driver -development are shared between both Linux and FreeBSD. Support for the -AIC-7xxx chipsets have been in the default Linux kernel since approximately -linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD -2.1.0 or later. - - Supported cards/chipsets - ---------------------------- - Adaptec Cards - ---------------------------- - AHA-274x - AHA-274xT - AHA-2842 - AHA-2910B - AHA-2920C - AHA-2930 - AHA-2930U - AHA-2930CU - AHA-2930U2 - AHA-2940 - AHA-2940W - AHA-2940U - AHA-2940UW - AHA-2940UW-PRO - AHA-2940AU - AHA-2940U2W - AHA-2940U2 - AHA-2940U2B - AHA-2940U2BOEM - AHA-2944D - AHA-2944WD - AHA-2944UD - AHA-2944UWD - AHA-2950U2 - AHA-2950U2W - AHA-2950U2B - AHA-29160M - AHA-3940 - AHA-3940U - AHA-3940W - AHA-3940UW - AHA-3940AUW - AHA-3940U2W - AHA-3950U2B - AHA-3950U2D - AHA-3960D - AHA-39160M - AHA-3985 - AHA-3985U - AHA-3985W - AHA-3985UW - - Motherboard Chipsets - ---------------------------- - AIC-777x - AIC-785x - AIC-786x - AIC-787x - AIC-788x - AIC-789x - AIC-3860 - - Bus Types - ---------------------------- - W - Wide SCSI, SCSI-3, 16bit bus, 68pin connector, will also support - SCSI-1/SCSI-2 50pin devices, transfer rates up to 20MB/s. - U - Ultra SCSI, transfer rates up to 40MB/s. - U2- Ultra 2 SCSI, transfer rates up to 80MB/s. - D - Differential SCSI. - T - Twin Channel SCSI. Up to 14 SCSI devices. - - AHA-274x - EISA SCSI controller - AHA-284x - VLB SCSI controller - AHA-29xx - PCI SCSI controller - AHA-394x - PCI controllers with two separate SCSI controllers on-board. - AHA-398x - PCI RAID controllers with three separate SCSI controllers - on-board. - - Not Supported Devices - ------------------------------ - Adaptec Cards - ---------------------------- - AHA-2920 (Only the cards that use the Future Domain chipset are not - supported, any 2920 cards based on Adaptec AIC chipsets, - such as the 2920C, are supported) - AAA-13x Raid Adapters - AAA-113x Raid Port Card - - Motherboard Chipsets - ---------------------------- - AIC-7810 - - Bus Types - ---------------------------- - R - Raid Port busses are not supported. - - The hardware RAID devices sold by Adaptec are *NOT* supported by this - driver (and will people please stop emailing me about them, they are - a totally separate beast from the bare SCSI controllers and this driver - cannot be retrofitted in any sane manner to support the hardware RAID - features on those cards - Doug Ledford). - - - People - ------------------------------ - Justin T Gibbs gibbs@plutotech.com - (BSD Driver Author) - Dan Eischen deischen@iworks.InterWorks.org - (Original Linux Driver Co-maintainer) - Dean Gehnert deang@teleport.com - (Original Linux FTP/patch maintainer) - Jess Johnson jester@frenzy.com - (AIC7xxx FAQ author) - Doug Ledford dledford@redhat.com - (Current Linux aic7xxx-5.x.x Driver/Patch/FTP maintainer) - - Special thanks go to John Aycock (aycock@cpsc.ucalgary.ca), the original - author of the driver. John has since retired from the project. Thanks - again for all his work! - - Mailing list - ------------------------------ - There is a mailing list available for users who want to track development - and converse with other users and developers. This list is for both - FreeBSD and Linux support of the AIC7xxx chipsets. - - To subscribe to the AIC7xxx mailing list send mail to the list server, - with "subscribe AIC7xxx" in the body (no Subject: required): - To: majordomo@FreeBSD.ORG - --- - subscribe AIC7xxx - - To unsubscribe from the list, send mail to the list server with: - To: majordomo@FreeBSD.ORG - --- - unsubscribe AIC7xxx - - Send regular messages and replies to: AIC7xxx@FreeBSD.ORG - - Boot Command line options - ------------------------------ - "aic7xxx=no_reset" - Eliminate the SCSI bus reset during startup. - Some SCSI devices need the initial reset that this option disables - in order to work. If you have problems at bootup, please make sure - you aren't using this option. - - "aic7xxx=reverse_scan" - Certain PCI motherboards scan for devices at - bootup by scanning from the highest numbered PCI device to the - lowest numbered PCI device, others do just the opposite and scan - from lowest to highest numbered PCI device. There is no reliable - way to autodetect this ordering. So, we default to the most common - order, which is lowest to highest. Then, in case your motherboard - scans from highest to lowest, we have this option. If your BIOS - finds the drives on controller A before controller B but the linux - kernel finds your drives on controller B before A, then you should - use this option. - - "aic7xxx=extended" - Force the driver to detect extended drive translation - on your controller. This helps those people who have cards without - a SEEPROM make sure that linux and all other operating systems think - the same way about your hard drives. - - "aic7xxx=scbram" - Some cards have external SCB RAM that can be used to - give the card more hardware SCB slots. This allows the driver to use - that SCB RAM. Without this option, the driver won't touch the SCB - RAM because it is known to cause problems on a few cards out there - (such as 3985 class cards). - - "aic7xxx=irq_trigger:x" - Replace x with either 0 or 1 to force the kernel - to use the correct IRQ type for your card. This only applies to EISA - based controllers. On these controllers, 0 is for Edge triggered - interrupts, and 1 is for Level triggered interrupts. If you aren't - sure or don't know which IRQ trigger type your EISA card uses, then - let the kernel autodetect the trigger type. - - "aic7xxx=verbose" - This option can be used in one of two ways. If you - simply specify aic7xxx=verbose, then the kernel will automatically - pick the default set of verbose messages for you to see. - Alternatively, you can specify the command as - "aic7xxx=verbose:0xXXXX" where the X entries are replaced with - hexadecimal digits. This option is a bit field type option. For - a full listing of the available options, search for the - #define VERBOSE_xxxxxx lines in the aic7xxx.c file. If you want - verbose messages, then it is recommended that you simply use the - aic7xxx=verbose variant of this command. - - "aic7xxx=pci_parity:x" - This option controls whether or not the driver - enables PCI parity error checking on the PCI bus. By default, this - checking is disabled. To enable the checks, simply specify pci_parity - with no value afterwords. To reverse the parity from even to odd, - supply any number other than 0 or 255. In short: - pci_parity - Even parity checking (even is the normal PCI parity) - pci_parity:x - Where x > 0, Odd parity checking - pci_parity:0 - No check (default) - NOTE: In order to get Even PCI parity checking, you must use the - version of the option that does not include the : and a number at - the end (unless you want to enter exactly 2^32 - 1 as the number). - - "aic7xxx=no_probe" - This option will disable the probing for any VLB - based 2842 controllers and any EISA based controllers. This is - needed on certain newer motherboards where the normal EISA I/O ranges - have been claimed by other PCI devices. Probing on those machines - will often result in the machine crashing or spontaneously rebooting - during startup. Examples of machines that need this are the - Dell PowerEdge 6300 machines. - - "aic7xxx=seltime:2" - This option controls how long the card waits - during a device selection sequence for the device to respond. - The original SCSI spec says that this "should be" 256ms. This - is generally not required with modern devices. However, some - very old SCSI I devices need the full 256ms. Most modern devices - can run fine with only 64ms. The default for this option is - 64ms. If you need to change this option, then use the following - table to set the proper value in the example above: - 0 - 256ms - 1 - 128ms - 2 - 64ms - 3 - 32ms - - "aic7xxx=panic_on_abort" - This option is for debugging and will cause - the driver to panic the linux kernel and freeze the system the first - time the drivers abort or reset routines are called. This is most - helpful when some problem causes infinite reset loops that scroll too - fast to see. By using this option, you can write down what the errors - actually are and send that information to me so it can be fixed. - - "aic7xxx=dump_card" - This option will print out the *entire* set of - configuration registers on the card during the init sequence. This - is a debugging aid used to see exactly what state the card is in - when we finally finish our initialization routines. If you don't - have documentation on the chipsets, this will do you absolutely - no good unless you are simply trying to write all the information - down in order to send it to me. - - "aic7xxx=dump_sequencer" - This is the same as the above options except - that instead of dumping the register contents on the card, this - option dumps the contents of the sequencer program RAM. This gives - the ability to verify that the instructions downloaded to the - card's sequencer are indeed what they are supposed to be. Again, - unless you have documentation to tell you how to interpret these - numbers, then it is totally useless. - - "aic7xxx=override_term:0xffffffff" - This option is used to force the - termination on your SCSI controllers to a particular setting. This - is a bit mask variable that applies for up to 8 aic7xxx SCSI channels. - Each channel gets 4 bits, divided as follows: - bit 3 2 1 0 - | | | Enable/Disable Single Ended Low Byte Termination - | | En/Disable Single Ended High Byte Termination - | En/Disable Low Byte LVD Termination - En/Disable High Byte LVD Termination - - The upper 2 bits that deal with LVD termination only apply to Ultra2 - controllers. Furthermore, due to the current Ultra2 controller - designs, these bits are tied together such that setting either bit - enables both low and high byte LVD termination. It is not possible - to only set high or low byte LVD termination in this manner. This is - an artifact of the BIOS definition on Ultra2 controllers. For other - controllers, the only important bits are the two lowest bits. Setting - the higher bits on non-Ultra2 controllers has no effect. A few - examples of how to use this option: - - Enable low and high byte termination on a non-ultra2 controller that - is the first aic7xxx controller (the correct bits are 0011), - aic7xxx=override_term:0x3 - - Enable all termination on the third aic7xxx controller, high byte - termination on the second aic7xxx controller, and low and high byte - SE termination on the first aic7xxx controller - (bits are 1111 0010 0011), - aic7xxx=override_term:0xf23 - - No attempt has been made to make this option non-cryptic. It really - shouldn't be used except in dire circumstances, and if that happens, - I'm probably going to be telling you what to set this to anyway :) - - "aic7xxx=stpwlev:0xffffffff" - This option is used to control the STPWLEV - bit in the DEVCONFIG PCI register. Currently, this is one of the - very few registers that we have absolutely *no* way of detecting - what the variable should be. It depends entirely on how the chipset - and external terminators were coupled by the card/motherboard maker. - Further, a chip reset (at power up) always sets this bit to 0. If - there is no BIOS to run on the chipset/card (such as with a 2910C - or a motherboard controller with the BIOS totally disabled) then - the variable may not get set properly. Of course, if the proper - setting was 0, then that's what it would be after the reset, but if - the proper setting is actually 1.....you get the picture. Now, since - we can't detect this at all, I've added this option to force the - setting. If you have a BIOS on your controller then you should never - need to use this option. However, if you are having lots of SCSI - reset problems and can't seem to get them knocked out, this may help. - - Here's a test to know for certain if you need this option. Make - a boot floppy that you can use to boot your computer up and that - will detect the aic7xxx controller. Next, power down your computer. - While it's down, unplug all SCSI cables from your Adaptec SCSI - controller. Boot the system back up to the Adaptec EZ-SCSI BIOS - and then make sure that termination is enabled on your adapter (if - you have an Adaptec BIOS of course). Next, boot up the floppy you - made and wait for it to detect the aic7xxx controller. If the kernel - finds the controller fine, says scsi : x hosts and then tries to - detect your devices like normal, up to the point where it fails to - mount your root file system and panics, then you're fine. If, on - the other hand, the system goes into an infinite reset loop, then - you need to use this option and/or the previous option to force the - proper termination settings on your controller. If this happens, - then you next need to figure out what your settings should be. - - To find the correct settings, power your machine back down, connect - back up the SCSI cables, and boot back into your machine like normal. - However, boot with the aic7xxx=verbose:0x39 option. Record the - initial DEVCONFIG values for each of your aic7xxx controllers as - they are listed, and also record what the machine is detecting as - the proper termination on your controllers. NOTE: the order in - which the initial DEVCONFIG values are printed out is not guaranteed - to be the same order as the SCSI controllers are registered. The - above option and this option both work on the order of the SCSI - controllers as they are registered, so make sure you match the right - DEVCONFIG values with the right controllers if you have more than - one aic7xxx controller. - - Once you have the detected termination settings and the initial - DEVCONFIG values for each controller, then figure out what the - termination on each of the controllers *should* be. Hopefully, that - part is correct, but it could possibly be wrong if there is - bogus cable detection logic on your controller or something similar. - If all the controllers have the correct termination settings, then - don't set the aic7xxx=override_term variable at all, leave it alone. - Next, on any controllers that go into an infinite reset loop when - you unplug all the SCSI cables, get the starting DEVCONFIG value. - If the initial DEVCONFIG value is divisible by 2, then the correct - setting for that controller is 0. If it's an odd number, then - the correct setting for that controller is 1. For any other - controllers that didn't have an infinite reset problem, then reverse - the above options. If DEVCONFIG was even, then the correct setting - is 1, if not then the correct setting is 0. - - Now that you know what the correct setting was for each controller, - we need to encode that into the aic7xxx=stpwlev:0x... variable. - This variable is a bit field encoded variable. Bit 0 is for the first - aic7xxx controller, bit 1 for the next, etc. Put all these bits - together and you get a number. For example, if the third aic7xxx - needed a 1, but the second and first both needed a 0, then the bits - would be 100 in binary. This then translates to 0x04. You would - therefore set aic7xxx=stpwlev:0x04. This is fairly standard binary - to hexadecimal conversions here. If you aren't up to speed on the - binary->hex conversion then send an email to the aic7xxx mailing - list and someone can help you out. - - "aic7xxx=tag_info:{{8,8..},{8,8..},..}" - This option is used to disable - or enable Tagged Command Queueing (TCQ) on specific devices. As of - driver version 5.1.11, TCQ is now either on or off by default - according to the setting you choose during the make config process. - In order to en/disable TCQ for certain devices at boot time, a user - may use this boot param. The driver will then parse this message out - and en/disable the specific device entries that are present based upon - the value given. The param line is parsed in the following manner: - - { - first instance indicates the start of this parameter values - second instance is the start of entries for a particular - device entry - } - end the entries for a particular host adapter, or end the entire - set of parameter entries - , - move to next entry. Inside of a set of device entries, this - moves us to the next device on the list. Outside of device - entries, this moves us to the next host adapter - . - Same effect as , but is safe to use with insmod. - x - the number to enter into the array at this position. - 0 = Enable tagged queueing on this device and use the default - queue depth - 1-254 = Enable tagged queueing on this device and use this - number as the queue depth - 255 = Disable tagged queueing on this device. - Note: anything above 32 for an actual queue depth is wasteful - and not recommended. - - A few examples of how this can be used: - - tag_info:{{8,12,,0,,255,4}} - This line will only effect the first aic7xxx card registered. It - will set scsi id 0 to a queue depth of 8, id 1 to 12, leave id 2 - at the default, set id 3 to tagged queueing enabled and use the - default queue depth, id 4 default, id 5 disabled, and id 6 to 4. - Any not specified entries stay at the default value, repeated - commas with no value specified will simply increment to the next id - without changing anything for the missing values. - - tag_info:{,,,{,,,255}} - First, second, and third adapters at default values. Fourth - adapter, id 3 is disabled. Notice that leading commas simply - increment what the first number effects, and there are no need - for trailing commas. When you close out an adapter, or the - entire entry, anything not explicitly set stays at the default - value. - - A final note on this option. The scanner I used for this isn't - perfect or highly robust. If you mess the line up, the worst that - should happen is that the line will get ignored. If you don't - close out the entire entry with the final bracket, then any other - aic7xxx options after this will get ignored. So, in general, be - sure of what you are entering, and after you have it right, just - add it to the lilo.conf file so there won't be any mistakes. As - a means of checking this parser, the entire tag_info array for - each card is now printed out in the /proc/scsi/aic7xxx/x file. You - can use that to verify that your options were parsed correctly. - - Boot command line options may be combined to form the proper set of options - a user might need. For example, the following is valid: - - aic7xxx=verbose,extended,irq_trigger:1 - - The only requirement is that individual options be separated by a comma or - a period on the command line. - - Module Loading command options - ------------------------------ - When loading the aic7xxx driver as a module, the exact same options are - available to the user. However, the syntax to specify the options changes - slightly. For insmod, you need to wrap the aic7xxx= argument in quotes - and replace all ',' with '.'. So, for example, a valid insmod line - would be: - - insmod aic7xxx aic7xxx='verbose.irq_trigger:1.extended' - - This line should result in the *exact* same behaviour as if you typed - it in at the lilo prompt and the driver was compiled into the kernel - instead of being a module. The reason for the single quote is so that - the shell won't try to interpret anything in the line, such as {. - Insmod assumes any options starting with a letter instead of a number - is a character string (which is what we want) and by switching all of - the commas to periods, insmod won't interpret this as more than one - string and write junk into our binary image. I consider it a bug in - the insmod program that even if you wrap your string in quotes (quotes - that pass the shell mind you and that insmod sees) it still treats - a comma inside of those quotes as starting a new variable, resulting - in memory scribbles if you don't switch the commas to periods. - - - Kernel Compile options - ------------------------------ - The various kernel compile time options for this driver are now fairly - well documented in the file drivers/scsi/Kconfig. In order to - see this documentation, you need to use one of the advanced configuration - programs (menuconfig and xconfig). If you are using the "make menuconfig" - method of configuring your kernel, then you would simply highlight the - option in question and hit the ? key. If you are using the "make xconfig" - method of configuring your kernel, then simply click on the help button - next to the option you have questions about. The help information from - the Configure.help file will then get automatically displayed. - - /proc support - ------------------------------ - The /proc support for the AIC7xxx can be found in the /proc/scsi/aic7xxx/ - directory. That directory contains a file for each SCSI controller in - the system. Each file presents the current configuration and transfer - statistics (enabled with #define in aic7xxx.c) for each controller. - - Thanks to Michael Neuffer for his upper-level SCSI help, and - Matthew Jacob for statistics support. - - Debugging the driver - ------------------------------ - Should you have problems with this driver, and would like some help in - getting them solved, there are a couple debugging items built into - the driver to facilitate getting the needed information from the system. - In general, I need a complete description of the problem, with as many - logs as possible concerning what happens. To help with this, there is - a command option aic7xxx=panic_on_abort. This option, when set, forces - the driver to panic the kernel on the first SCSI abort issued by the - mid level SCSI code. If your system is going to reset loops and you - can't read the screen, then this is what you need. Not only will it - stop the system, but it also prints out a large amount of state - information in the process. Second, if you specify the option - "aic7xxx=verbose:0x1ffff", the system will print out *SOOOO* much - information as it runs that you won't be able to see anything. - However, this can actually be very useful if your machine simply - locks up when trying to boot, since it will pin-point what was last - happening (in regards to the aic7xxx driver) immediately prior to - the lockup. This is really only useful if your machine simply can - not boot up successfully. If you can get your machine to run, then - this will produce far too much information. - - FTP sites - ------------------------------ - ftp://ftp.redhat.com/pub/aic/ - - Out of date. I used to keep stuff here, but too many people - complained about having a hard time getting into Red Hat's ftp - server. So use the web site below instead. - ftp://ftp.pcnet.com/users/eischen/Linux/ - - Dan Eischen's driver distribution area - ftp://ekf2.vsb.cz/pub/linux/kernel/aic7xxx/ftp.teleport.com/ - - European Linux mirror of Teleport site - - Web sites - ------------------------------ - http://people.redhat.com/dledford/ - - My web site, also the primary aic7xxx site with several related - pages. - -Dean W. Gehnert -deang@teleport.com - -$Revision: 3.0 $ - -Modified by Doug Ledford 1998-2000 - diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt index 6ff16b620d84..a0c85110a07e 100644 --- a/Documentation/scsi/scsi_eh.txt +++ b/Documentation/scsi/scsi_eh.txt @@ -42,20 +42,14 @@ discussion. Once LLDD gets hold of a scmd, either the LLDD will complete the command by calling scsi_done callback passed from midlayer when -invoking hostt->queuecommand() or SCSI midlayer will time it out. +invoking hostt->queuecommand() or the block layer will time it out. [1-2-1] Completing a scmd w/ scsi_done For all non-EH commands, scsi_done() is the completion callback. It -does the following. - - 1. Delete timeout timer. If it fails, it means that timeout timer - has expired and is going to finish the command. Just return. - - 2. Link scmd to per-cpu scsi_done_q using scmd->en_entry - - 3. Raise SCSI_SOFTIRQ +just calls blk_complete_request() to delete the block layer timer and +raise SCSI_SOFTIRQ SCSI_SOFTIRQ handler scsi_softirq calls scsi_decide_disposition() to determine what to do with the command. scsi_decide_disposition() @@ -64,10 +58,12 @@ with the command. - SUCCESS scsi_finish_command() is invoked for the command. The - function does some maintenance choirs and notify completion by - calling scmd->done() callback, which, for fs requests, would - be HLD completion callback - sd:sd_rw_intr, sr:rw_intr, - st:st_intr. + function does some maintenance chores and then calls + scsi_io_completion() to finish the I/O. + scsi_io_completion() then notifies the block layer on + the completed request by calling blk_end_request and + friends or figures out what to do with the remainder + of the data in case of an error. - NEEDS_RETRY - ADD_TO_MLQUEUE @@ -86,33 +82,45 @@ function 1. invokes optional hostt->eh_timed_out() callback. Return value can be one of - - EH_HANDLED - This indicates that eh_timed_out() dealt with the timeout. The - scmd is passed to __scsi_done() and thus linked into per-cpu - scsi_done_q. Normal command completion described in [1-2-1] - follows. + - BLK_EH_HANDLED + This indicates that eh_timed_out() dealt with the timeout. + The command is passed back to the block layer and completed + via __blk_complete_requests(). - - EH_RESET_TIMER + *NOTE* After returning BLK_EH_HANDLED the SCSI layer is + assumed to be finished with the command, and no other + functions from the SCSI layer will be called. So this + should typically only be returned if the eh_timed_out() + handler raced with normal completion. + + - BLK_EH_RESET_TIMER This indicates that more time is required to finish the command. Timer is restarted. This action is counted as a retry and only allowed scmd->allowed + 1(!) times. Once the - limit is reached, action for EH_NOT_HANDLED is taken instead. + limit is reached, action for BLK_EH_NOT_HANDLED is taken instead. - *NOTE* This action is racy as the LLDD could finish the scmd - after the timeout has expired but before it's added back. In - such cases, scsi_done() would think that timeout has occurred - and return without doing anything. We lose completion and the - command will time out again. - - - EH_NOT_HANDLED - This is the same as when eh_timed_out() callback doesn't exist. + - BLK_EH_NOT_HANDLED + eh_timed_out() callback did not handle the command. Step #2 is taken. + 2. If the host supports asynchronous completion (as indicated by the + no_async_abort setting in the host template) scsi_abort_command() + is invoked to schedule an asynchrous abort. If that fails + Step #3 is taken. + 2. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the command. See [1-3] for more information. +[1-3] Asynchronous command aborts -[1-3] How EH takes over + After a timeout occurs a command abort is scheduled from + scsi_abort_command(). If the abort is successful the command + will either be retried (if the number of retries is not exhausted) + or terminated with DID_TIME_OUT. + Otherwise scsi_eh_scmd_add() is invoked for the command. + See [1-4] for more information. + +[1-4] How EH takes over scmds enter EH via scsi_eh_scmd_add(), which does the following. @@ -320,7 +328,8 @@ scmd->allowed. <> - This action is taken for each timed out command. + This action is taken for each timed out command when + no_async_abort is enabled in the host template. hostt->eh_abort_handler() is invoked for each scmd. The handler returns SUCCESS if it has succeeded to make LLDD and all related hardware forget about the scmd. diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 2b06aba4fa0f..d6a9bdeee7f2 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt @@ -882,8 +882,11 @@ Details: * * Calling context: kernel thread * - * Notes: Invoked from scsi_eh thread. No other commands will be - * queued on current host during eh. + * Notes: If 'no_async_abort' is defined this callback + * will be invoked from scsi_eh thread. No other commands + * will then be queued on current host during eh. + * Otherwise it will be called whenever scsi_times_out() + * is called due to a command timeout. * * Optionally defined in: LLD **/ @@ -1257,6 +1260,8 @@ of interest: address space use_clustering - 1=>SCSI commands in mid level's queue can be merged, 0=>disallow SCSI command merging + no_async_abort - 1=>Asynchronous aborts are not supported + 0=>Timed-out commands will be aborted asynchronously hostt - pointer to driver's struct scsi_host_template from which this struct Scsi_Host instance was spawned hostt->proc_name - name of LLD. This is the driver name that sysfs uses diff --git a/Documentation/scsi/scsi_transport_srp/Makefile b/Documentation/scsi/scsi_transport_srp/Makefile new file mode 100644 index 000000000000..5f6b567e955c --- /dev/null +++ b/Documentation/scsi/scsi_transport_srp/Makefile @@ -0,0 +1,7 @@ +all: rport_state_diagram.svg rport_state_diagram.png + +rport_state_diagram.svg: rport_state_diagram.dot + dot -Tsvg -o $@ $< + +rport_state_diagram.png: rport_state_diagram.dot + dot -Tpng -o $@ $< diff --git a/Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot b/Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot new file mode 100644 index 000000000000..75d610d6411a --- /dev/null +++ b/Documentation/scsi/scsi_transport_srp/rport_state_diagram.dot @@ -0,0 +1,26 @@ +digraph srp_initiator { + node [shape = doublecircle]; running lost; + node [shape = circle]; + + { + rank = min; + running_rta [ label = "running;\nreconnect\ntimer\nactive" ]; + }; + running [ label = "running;\nreconnect\ntimer\nstopped" ]; + blocked; + failfast [ label = "fail I/O\nfast" ]; + lost; + + running -> running_rta [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nsrp_start_tl_fail_timers()" ]; + running_rta -> running [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nreconnecting succeeded" ]; + running -> blocked [ label = "fast_io_fail_tmo >= 0 or\ndev_loss_tmo >= 0;\nsrp_start_tl_fail_timers()" ]; + running -> failfast [ label = "fast_io_fail_tmo = off and\ndev_loss_tmo = off;\nreconnecting failed\n" ]; + blocked -> failfast [ label = "fast_io_fail_tmo\nexpired or\nreconnecting\nfailed" ]; + blocked -> lost [ label = "dev_loss_tmo\nexpired or\nsrp_stop_rport_timers()" ]; + failfast -> lost [ label = "dev_loss_tmo\nexpired or\nsrp_stop_rport_timers()" ]; + blocked -> running [ label = "reconnecting\nsucceeded" ]; + failfast -> failfast [ label = "reconnecting\nfailed" ]; + failfast -> running [ label = "reconnecting\nsucceeded" ]; + running -> lost [ label = "srp_stop_rport_timers()" ]; + running_rta -> lost [ label = "srp_stop_rport_timers()" ]; +} diff --git a/Documentation/security/IMA-templates.txt b/Documentation/security/IMA-templates.txt index a777e5f1df5b..a4e102dddfea 100644 --- a/Documentation/security/IMA-templates.txt +++ b/Documentation/security/IMA-templates.txt @@ -67,12 +67,14 @@ descriptors by adding their identifier to the format string - 'd-ng': the digest of the event, calculated with an arbitrary hash algorithm (field format: [:]digest, where the digest prefix is shown only if the hash algorithm is not SHA1 or MD5); - - 'n-ng': the name of the event, without size limitations. + - 'n-ng': the name of the event, without size limitations; + - 'sig': the file signature. Below, there is the list of defined template descriptors: - "ima": its format is 'd|n'; - - "ima-ng" (default): its format is 'd-ng|n-ng'. + - "ima-ng" (default): its format is 'd-ng|n-ng'; + - "ima-sig": its format is 'd-ng|n-ng|sig'. diff --git a/Documentation/sound/alsa/soc/overview.txt b/Documentation/sound/alsa/soc/overview.txt index 138ac88c1461..ff88f52eec98 100644 --- a/Documentation/sound/alsa/soc/overview.txt +++ b/Documentation/sound/alsa/soc/overview.txt @@ -49,18 +49,23 @@ features :- * Machine specific controls: Allow machines to add controls to the sound card (e.g. volume control for speaker amplifier). -To achieve all this, ASoC basically splits an embedded audio system into 3 -components :- +To achieve all this, ASoC basically splits an embedded audio system into +multiple re-usable component drivers :- - * Codec driver: The codec driver is platform independent and contains audio - controls, audio interface capabilities, codec DAPM definition and codec IO - functions. + * Codec class drivers: The codec class driver is platform independent and + contains audio controls, audio interface capabilities, codec DAPM + definition and codec IO functions. This class extends to BT, FM and MODEM + ICs if required. Codec class drivers should be generic code that can run + on any architecture and machine. - * Platform driver: The platform driver contains the audio DMA engine and audio - interface drivers (e.g. I2S, AC97, PCM) for that platform. + * Platform class drivers: The platform class driver includes the audio DMA + engine driver, digital audio interface (DAI) drivers (e.g. I2S, AC97, PCM) + and any audio DSP drivers for that platform. - * Machine driver: The machine driver handles any machine specific controls and - audio events (e.g. turning on an amp at start of playback). + * Machine class driver: The machine driver class acts as the glue that + decribes and binds the other component drivers together to form an ALSA + "sound card device". It handles any machine specific controls and + machine level audio events (e.g. turning on an amp at start of playback). Documentation @@ -84,3 +89,7 @@ machine.txt: Machine driver internals. pop_clicks.txt: How to minimise audio artifacts. clocking.txt: ASoC clocking for best power performance. + +jack.txt: ASoC jack detection. + +DPCM.txt: Dynamic PCM - Describes DPCM with DSP examples. diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index f21edb983413..f72e0d1e0da8 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -34,7 +34,7 @@ SPI slave functions are usually not interoperable between vendors - It may also be used to stream data in either direction (half duplex), or both of them at the same time (full duplex). - - Some devices may use eight bit words. Others may different word + - Some devices may use eight bit words. Others may use different word lengths, such as streams of 12-bit or 20-bit digital samples. - Words are usually sent with their most significant bit (MSB) first, @@ -121,7 +121,7 @@ active. So the master must set the clock to inactive before selecting a slave, and the slave can tell the chosen polarity by sampling the clock level when its select line goes active. That's why many devices support for example both modes 0 and 3: they don't care about polarity, -and alway clock data in/out on rising clock edges. +and always clock data in/out on rising clock edges. How do these driver programming interfaces work? @@ -139,7 +139,7 @@ a command and then reading its response. There are two types of SPI driver, here called: - Controller drivers ... controllers may be built in to System-On-Chip + Controller drivers ... controllers may be built into System-On-Chip processors, and often support both Master and Slave roles. These drivers touch hardware registers and may use DMA. Or they can be PIO bitbangers, needing just GPIO pins. @@ -548,7 +548,7 @@ SPI MASTER METHODS DEPRECATED METHODS master->transfer(struct spi_device *spi, struct spi_message *message) - This must not sleep. Its responsibility is arrange that the + This must not sleep. Its responsibility is to arrange that the transfer happens and its complete() callback is issued. The two will normally happen later, after other transfers complete, and if the controller is idle it will need to be kickstarted. This diff --git a/Documentation/static-keys.txt b/Documentation/static-keys.txt index 9f5263d3152c..c4407a41b0fc 100644 --- a/Documentation/static-keys.txt +++ b/Documentation/static-keys.txt @@ -116,7 +116,7 @@ The branch(es) can then be switched via: static_key_slow_dec(&key); Thus, 'static_key_slow_inc()' means 'make the branch true', and -'static_key_slow_dec()' means 'make the the branch false' with appropriate +'static_key_slow_dec()' means 'make the branch false' with appropriate reference counting. For example, if the key is initialized true, a static_key_slow_dec(), will switch the branch to false. And a subsequent static_key_slow_inc(), will change the branch back to true. Likewise, if the @@ -236,7 +236,7 @@ label case adds: If we then include the padding bytes, the jump label code saves, 16 total bytes of instruction memory for this small function. In this case the non-jump label -function is 80 bytes long. Thus, we have have saved 20% of the instruction +function is 80 bytes long. Thus, we have saved 20% of the instruction footprint. We can in fact improve this even further, since the 5-byte no-op really can be a 2-byte no-op since we can reach the branch with a 2-byte jmp. However, we have not yet implemented optimal no-op sizes (they are currently diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 26b7ee491df8..ee9a2f983b99 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -33,6 +33,7 @@ show up in /proc/sys/kernel: - domainname - hostname - hotplug +- kexec_load_disabled - kptr_restrict - kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] @@ -287,6 +288,18 @@ Default value is "/sbin/hotplug". ============================================================== +kexec_load_disabled: + +A toggle indicating if the kexec_load syscall has been disabled. This +value defaults to 0 (false: kexec_load enabled), but can be set to 1 +(true: kexec_load disabled). Once true, kexec can no longer be used, and +the toggle cannot be set back to false. This allows a kexec image to be +loaded before disabling the syscall, allowing a system to set up (and +later use) an image without it being altered. Generally used together +with the "modules_disabled" sysctl. + +============================================================== + kptr_restrict: This toggle indicates whether restrictions are placed on @@ -331,7 +344,7 @@ A toggle value indicating if modules are allowed to be loaded in an otherwise modular kernel. This toggle defaults to off (0), but can be set true (1). Once true, modules can be neither loaded nor unloaded, and the toggle cannot be set back -to false. +to false. Generally used with the "kexec_load_disabled" toggle. ============================================================== @@ -428,11 +441,6 @@ rate for each task. numa_balancing_scan_size_mb is how many megabytes worth of pages are scanned for a given scan. -numa_balancing_settle_count is how many scan periods must complete before -the schedule balancer stops pushing the task towards a preferred node. This -gives the scheduler a chance to place the task on an alternative node if the -preferred node is overloaded. - numa_balancing_migrate_deferred is how many page migrations get skipped unconditionally, after a page migration is skipped because a page is shared with other tasks. This reduces page migration overhead, and determines diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 1fbd4eb7b64a..9f5481bdc5a4 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -47,6 +47,7 @@ Currently, these files are in /proc/sys/vm: - numa_zonelist_order - oom_dump_tasks - oom_kill_allocating_task +- overcommit_kbytes - overcommit_memory - overcommit_ratio - page-cluster @@ -574,6 +575,17 @@ The default value is 0. ============================================================== +overcommit_kbytes: + +When overcommit_memory is set to 2, the committed address space is not +permitted to exceed swap plus this amount of physical RAM. See below. + +Note: overcommit_kbytes is the counterpart of overcommit_ratio. Only one +of them may be specified at a time. Setting one disables the other (which +then appears as 0 when read). + +============================================================== + overcommit_memory: This value contains a flag that enables memory overcommitment. diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt index 37732a220d33..c94435df2037 100644 --- a/Documentation/trace/events.txt +++ b/Documentation/trace/events.txt @@ -287,3 +287,210 @@ their old filters): prev_pid == 0 # cat sched_wakeup/filter common_pid == 0 + +6. Event triggers +================= + +Trace events can be made to conditionally invoke trigger 'commands' +which can take various forms and are described in detail below; +examples would be enabling or disabling other trace events or invoking +a stack trace whenever the trace event is hit. Whenever a trace event +with attached triggers is invoked, the set of trigger commands +associated with that event is invoked. Any given trigger can +additionally have an event filter of the same form as described in +section 5 (Event filtering) associated with it - the command will only +be invoked if the event being invoked passes the associated filter. +If no filter is associated with the trigger, it always passes. + +Triggers are added to and removed from a particular event by writing +trigger expressions to the 'trigger' file for the given event. + +A given event can have any number of triggers associated with it, +subject to any restrictions that individual commands may have in that +regard. + +Event triggers are implemented on top of "soft" mode, which means that +whenever a trace event has one or more triggers associated with it, +the event is activated even if it isn't actually enabled, but is +disabled in a "soft" mode. That is, the tracepoint will be called, +but just will not be traced, unless of course it's actually enabled. +This scheme allows triggers to be invoked even for events that aren't +enabled, and also allows the current event filter implementation to be +used for conditionally invoking triggers. + +The syntax for event triggers is roughly based on the syntax for +set_ftrace_filter 'ftrace filter commands' (see the 'Filter commands' +section of Documentation/trace/ftrace.txt), but there are major +differences and the implementation isn't currently tied to it in any +way, so beware about making generalizations between the two. + +6.1 Expression syntax +--------------------- + +Triggers are added by echoing the command to the 'trigger' file: + + # echo 'command[:count] [if filter]' > trigger + +Triggers are removed by echoing the same command but starting with '!' +to the 'trigger' file: + + # echo '!command[:count] [if filter]' > trigger + +The [if filter] part isn't used in matching commands when removing, so +leaving that off in a '!' command will accomplish the same thing as +having it in. + +The filter syntax is the same as that described in the 'Event +filtering' section above. + +For ease of use, writing to the trigger file using '>' currently just +adds or removes a single trigger and there's no explicit '>>' support +('>' actually behaves like '>>') or truncation support to remove all +triggers (you have to use '!' for each one added.) + +6.2 Supported trigger commands +------------------------------ + +The following commands are supported: + +- enable_event/disable_event + + These commands can enable or disable another trace event whenever + the triggering event is hit. When these commands are registered, + the other trace event is activated, but disabled in a "soft" mode. + That is, the tracepoint will be called, but just will not be traced. + The event tracepoint stays in this mode as long as there's a trigger + in effect that can trigger it. + + For example, the following trigger causes kmalloc events to be + traced when a read system call is entered, and the :1 at the end + specifies that this enablement happens only once: + + # echo 'enable_event:kmem:kmalloc:1' > \ + /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger + + The following trigger causes kmalloc events to stop being traced + when a read system call exits. This disablement happens on every + read system call exit: + + # echo 'disable_event:kmem:kmalloc' > \ + /sys/kernel/debug/tracing/events/syscalls/sys_exit_read/trigger + + The format is: + + enable_event::[:count] + disable_event::[:count] + + To remove the above commands: + + # echo '!enable_event:kmem:kmalloc:1' > \ + /sys/kernel/debug/tracing/events/syscalls/sys_enter_read/trigger + + # echo '!disable_event:kmem:kmalloc' > \ + /sys/kernel/debug/tracing/events/syscalls/sys_exit_read/trigger + + Note that there can be any number of enable/disable_event triggers + per triggering event, but there can only be one trigger per + triggered event. e.g. sys_enter_read can have triggers enabling both + kmem:kmalloc and sched:sched_switch, but can't have two kmem:kmalloc + versions such as kmem:kmalloc and kmem:kmalloc:1 or 'kmem:kmalloc if + bytes_req == 256' and 'kmem:kmalloc if bytes_alloc == 256' (they + could be combined into a single filter on kmem:kmalloc though). + +- stacktrace + + This command dumps a stacktrace in the trace buffer whenever the + triggering event occurs. + + For example, the following trigger dumps a stacktrace every time the + kmalloc tracepoint is hit: + + # echo 'stacktrace' > \ + /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger + + The following trigger dumps a stacktrace the first 5 times a kmalloc + request happens with a size >= 64K + + # echo 'stacktrace:5 if bytes_req >= 65536' > \ + /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger + + The format is: + + stacktrace[:count] + + To remove the above commands: + + # echo '!stacktrace' > \ + /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger + + # echo '!stacktrace:5 if bytes_req >= 65536' > \ + /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger + + The latter can also be removed more simply by the following (without + the filter): + + # echo '!stacktrace:5' > \ + /sys/kernel/debug/tracing/events/kmem/kmalloc/trigger + + Note that there can be only one stacktrace trigger per triggering + event. + +- snapshot + + This command causes a snapshot to be triggered whenever the + triggering event occurs. + + The following command creates a snapshot every time a block request + queue is unplugged with a depth > 1. If you were tracing a set of + events or functions at the time, the snapshot trace buffer would + capture those events when the trigger event occured: + + # echo 'snapshot if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + To only snapshot once: + + # echo 'snapshot:1 if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + To remove the above commands: + + # echo '!snapshot if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + # echo '!snapshot:1 if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + Note that there can be only one snapshot trigger per triggering + event. + +- traceon/traceoff + + These commands turn tracing on and off when the specified events are + hit. The parameter determines how many times the tracing system is + turned on and off. If unspecified, there is no limit. + + The following command turns tracing off the first time a block + request queue is unplugged with a depth > 1. If you were tracing a + set of events or functions at the time, you could then examine the + trace buffer to see the sequence of events that led up to the + trigger event: + + # echo 'traceoff:1 if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + To always disable tracing when nr_rq > 1 : + + # echo 'traceoff if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + To remove the above commands: + + # echo '!traceoff:1 if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + # echo '!traceoff if nr_rq > 1' > \ + /sys/kernel/debug/tracing/events/block/block_unplug/trigger + + Note that there can be only one traceon or traceoff trigger per + triggering event. diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl index 4a37c4759cd2..00e425faa2fd 100644 --- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl @@ -123,7 +123,7 @@ my $regex_writepage; # Static regex used. Specified like this for readability and for use with /o # (process_pid) (cpus ) ( time ) (tpoint ) (details) -my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)'; +my $regex_traceevent = '\s*([a-zA-Z0-9-]*)\s*(\[[0-9]*\])(\s*[dX.][Nnp.][Hhs.][0-9a-fA-F.]*|)\s*([0-9.]*):\s*([a-zA-Z_]*):\s*(.*)'; my $regex_statname = '[-0-9]*\s\((.*)\).*'; my $regex_statppid = '[-0-9]*\s\(.*\)\s[A-Za-z]\s([0-9]*).*'; @@ -270,8 +270,8 @@ EVENT_PROCESS: while ($traceevent = ) { if ($traceevent =~ /$regex_traceevent/o) { $process_pid = $1; - $timestamp = $3; - $tracepoint = $4; + $timestamp = $4; + $tracepoint = $5; $process_pid =~ /(.*)-([0-9]*)$/; my $process = $1; @@ -299,7 +299,7 @@ EVENT_PROCESS: $perprocesspid{$process_pid}->{MM_VMSCAN_DIRECT_RECLAIM_BEGIN}++; $perprocesspid{$process_pid}->{STATE_DIRECT_BEGIN} = $timestamp; - $details = $5; + $details = $6; if ($details !~ /$regex_direct_begin/o) { print "WARNING: Failed to parse mm_vmscan_direct_reclaim_begin as expected\n"; print " $details\n"; @@ -322,7 +322,7 @@ EVENT_PROCESS: $perprocesspid{$process_pid}->{HIGH_DIRECT_RECLAIM_LATENCY}[$index] = "$order-$latency"; } } elsif ($tracepoint eq "mm_vmscan_kswapd_wake") { - $details = $5; + $details = $6; if ($details !~ /$regex_kswapd_wake/o) { print "WARNING: Failed to parse mm_vmscan_kswapd_wake as expected\n"; print " $details\n"; @@ -356,7 +356,7 @@ EVENT_PROCESS: } elsif ($tracepoint eq "mm_vmscan_wakeup_kswapd") { $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD}++; - $details = $5; + $details = $6; if ($details !~ /$regex_wakeup_kswapd/o) { print "WARNING: Failed to parse mm_vmscan_wakeup_kswapd as expected\n"; print " $details\n"; @@ -366,7 +366,7 @@ EVENT_PROCESS: my $order = $3; $perprocesspid{$process_pid}->{MM_VMSCAN_WAKEUP_KSWAPD_PERORDER}[$order]++; } elsif ($tracepoint eq "mm_vmscan_lru_isolate") { - $details = $5; + $details = $6; if ($details !~ /$regex_lru_isolate/o) { print "WARNING: Failed to parse mm_vmscan_lru_isolate as expected\n"; print " $details\n"; @@ -387,7 +387,7 @@ EVENT_PROCESS: } $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; } elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") { - $details = $5; + $details = $6; if ($details !~ /$regex_lru_shrink_inactive/o) { print "WARNING: Failed to parse mm_vmscan_lru_shrink_inactive as expected\n"; print " $details\n"; @@ -397,7 +397,7 @@ EVENT_PROCESS: my $nr_reclaimed = $4; $perprocesspid{$process_pid}->{HIGH_NR_RECLAIMED} += $nr_reclaimed; } elsif ($tracepoint eq "mm_vmscan_writepage") { - $details = $5; + $details = $6; if ($details !~ /$regex_writepage/o) { print "WARNING: Failed to parse mm_vmscan_writepage as expected\n"; print " $details\n"; diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt index d9c3e682312c..f1cf9a34ad9d 100644 --- a/Documentation/trace/uprobetracer.txt +++ b/Documentation/trace/uprobetracer.txt @@ -19,18 +19,44 @@ user to calculate the offset of the probepoint in the object. Synopsis of uprobe_tracer ------------------------- - p[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS] : Set a uprobe - r[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS] : Set a return uprobe (uretprobe) - -:[GRP/]EVENT : Clear uprobe or uretprobe event + p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe + r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe) + -:[GRP/]EVENT : Clear uprobe or uretprobe event GRP : Group name. If omitted, "uprobes" is the default value. EVENT : Event name. If omitted, the event name is generated based - on SYMBOL+offs. + on PATH+OFFSET. PATH : Path to an executable or a library. - SYMBOL[+offs] : Symbol+offset where the probe is inserted. + OFFSET : Offset where the probe is inserted. FETCHARGS : Arguments. Each probe can have up to 128 args. %REG : Fetch register REG + @ADDR : Fetch memory at ADDR (ADDR should be in userspace) + @+OFFSET : Fetch memory at OFFSET (OFFSET from same file as PATH) + $stackN : Fetch Nth entry of stack (N >= 0) + $stack : Fetch stack address. + $retval : Fetch return value.(*) + +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) + NAME=FETCHARG : Set NAME as the argument name of FETCHARG. + FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types + (u8/u16/u32/u64/s8/s16/s32/s64), "string" and bitfield + are supported. + + (*) only for return probe. + (**) this is useful for fetching a field of data structures. + +Types +----- +Several types are supported for fetch-args. Uprobe tracer will access memory +by given type. Prefix 's' and 'u' means those types are signed and unsigned +respectively. Traced arguments are shown in decimal (signed) or hex (unsigned). +String type is a special type, which fetches a "null-terminated" string from +user space. +Bitfield is another special type, which takes 3 parameters, bit-width, bit- +offset, and container-size (usually 32). The syntax is; + + b@/ + Event Profiling --------------- diff --git a/Documentation/unaligned-memory-access.txt b/Documentation/unaligned-memory-access.txt index f866c72291bf..a445da098bc6 100644 --- a/Documentation/unaligned-memory-access.txt +++ b/Documentation/unaligned-memory-access.txt @@ -137,24 +137,34 @@ Code that causes unaligned access ================================= With the above in mind, let's move onto a real life example of a function -that can cause an unaligned memory access. The following function adapted +that can cause an unaligned memory access. The following function taken from include/linux/etherdevice.h is an optimized routine to compare two ethernet MAC addresses for equality. -unsigned int compare_ether_addr(const u8 *addr1, const u8 *addr2) +bool ether_addr_equal(const u8 *addr1, const u8 *addr2) { - const u16 *a = (const u16 *) addr1; - const u16 *b = (const u16 *) addr2; +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS + u32 fold = ((*(const u32 *)addr1) ^ (*(const u32 *)addr2)) | + ((*(const u16 *)(addr1 + 4)) ^ (*(const u16 *)(addr2 + 4))); + + return fold == 0; +#else + const u16 *a = (const u16 *)addr1; + const u16 *b = (const u16 *)addr2; return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; +#endif } -In the above function, the reference to a[0] causes 2 bytes (16 bits) to -be read from memory starting at address addr1. Think about what would happen -if addr1 was an odd address such as 0x10003. (Hint: it'd be an unaligned -access.) +In the above function, when the hardware has efficient unaligned access +capability, there is no issue with this code. But when the hardware isn't +able to access memory on arbitrary boundaries, the reference to a[0] causes +2 bytes (16 bits) to be read from memory starting at address addr1. + +Think about what would happen if addr1 was an odd address such as 0x10003. +(Hint: it'd be an unaligned access.) Despite the potential unaligned access problems with the above function, it -is included in the kernel anyway but is understood to only work on +is included in the kernel anyway but is understood to only work normally on 16-bit-aligned addresses. It is up to the caller to ensure this alignment or not use this function at all. This alignment-unsafe function is still useful as it is a decent optimization for the cases when you can ensure alignment, diff --git a/Documentation/usb/gadget_multi.txt b/Documentation/usb/gadget_multi.txt index 80f4ef0eb75b..7d66a8636cb5 100644 --- a/Documentation/usb/gadget_multi.txt +++ b/Documentation/usb/gadget_multi.txt @@ -14,7 +14,7 @@ A CDC ECM (Ethernet) function may be turned on via a Kconfig option and RNDIS can be turned off. If they are both enabled the gadget will have two configurations -- one with RNDIS and another with CDC ECM[3]. -Please not that if you use non-standard configuration (that is enable +Please note that if you use non-standard configuration (that is enable CDC ECM) you may need to change vendor and/or product ID. * Host drivers diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index a30035dd4c26..366bf4b47ef4 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -2104,7 +2104,7 @@ Returns: 0 on success, -1 on error Allows setting an eventfd to directly trigger a guest interrupt. kvm_irqfd.fd specifies the file descriptor to use as the eventfd and kvm_irqfd.gsi specifies the irqchip pin toggled by this event. When -an event is tiggered on the eventfd, an interrupt is injected into +an event is triggered on the eventfd, an interrupt is injected into the guest using the specified gsi pin. The irqfd is removed using the KVM_IRQFD_FLAG_DEASSIGN flag, specifying both kvm_irqfd.fd and kvm_irqfd.gsi. @@ -2115,7 +2115,7 @@ interrupts. When KVM_IRQFD_FLAG_RESAMPLE is set the user must pass an additional eventfd in the kvm_irqfd.resamplefd field. When operating in resample mode, posting of an interrupt through kvm_irq.fd asserts the specified gsi in the irqchip. When the irqchip is resampled, such -as from an EOI, the gsi is de-asserted and the user is notifed via +as from an EOI, the gsi is de-asserted and the user is notified via kvm_irqfd.resamplefd. It is the user's responsibility to re-queue the interrupt if the device making use of it still requires service. Note that closing the resamplefd is not sufficient to disable the @@ -2327,7 +2327,7 @@ current state. "addr" is ignored. Capability: basic Architectures: arm, arm64 Type: vcpu ioctl -Parameters: struct struct kvm_vcpu_init (in) +Parameters: struct kvm_vcpu_init (in) Returns: 0 on success; -1 on error Errors:  EINVAL:    the target is unknown, or the combination of features is invalid. @@ -2391,7 +2391,8 @@ struct kvm_reg_list { This ioctl returns the guest registers that are supported for the KVM_GET_ONE_REG/KVM_SET_ONE_REG calls. -4.85 KVM_ARM_SET_DEVICE_ADDR + +4.85 KVM_ARM_SET_DEVICE_ADDR (deprecated) Capability: KVM_CAP_ARM_SET_DEVICE_ADDR Architectures: arm, arm64 @@ -2429,6 +2430,10 @@ must be called after calling KVM_CREATE_IRQCHIP, but before calling KVM_RUN on any of the VCPUs. Calling this ioctl twice for any of the base addresses will return -EEXIST. +Note, this IOCTL is deprecated and the more flexible SET/GET_DEVICE_ATTR API +should be used instead. + + 4.86 KVM_PPC_RTAS_DEFINE_TOKEN Capability: KVM_CAP_PPC_RTAS diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt new file mode 100644 index 000000000000..7f4e91b1316b --- /dev/null +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt @@ -0,0 +1,73 @@ +ARM Virtual Generic Interrupt Controller (VGIC) +=============================================== + +Device types supported: + KVM_DEV_TYPE_ARM_VGIC_V2 ARM Generic Interrupt Controller v2.0 + +Only one VGIC instance may be instantiated through either this API or the +legacy KVM_CREATE_IRQCHIP api. The created VGIC will act as the VM interrupt +controller, requiring emulated user-space devices to inject interrupts to the +VGIC instead of directly to CPUs. + +Groups: + KVM_DEV_ARM_VGIC_GRP_ADDR + Attributes: + KVM_VGIC_V2_ADDR_TYPE_DIST (rw, 64-bit) + Base address in the guest physical address space of the GIC distributor + register mappings. + + KVM_VGIC_V2_ADDR_TYPE_CPU (rw, 64-bit) + Base address in the guest physical address space of the GIC virtual cpu + interface register mappings. + + KVM_DEV_ARM_VGIC_GRP_DIST_REGS + Attributes: + The attr field of kvm_device_attr encodes two values: + bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 | + values: | reserved | cpu id | offset | + + All distributor regs are (rw, 32-bit) + + The offset is relative to the "Distributor base address" as defined in the + GICv2 specs. Getting or setting such a register has the same effect as + reading or writing the register on the actual hardware from the cpu + specified with cpu id field. Note that most distributor fields are not + banked, but return the same value regardless of the cpu id used to access + the register. + Limitations: + - Priorities are not implemented, and registers are RAZ/WI + Errors: + -ENODEV: Getting or setting this register is not yet supported + -EBUSY: One or more VCPUs are running + + KVM_DEV_ARM_VGIC_GRP_CPU_REGS + Attributes: + The attr field of kvm_device_attr encodes two values: + bits: | 63 .... 40 | 39 .. 32 | 31 .... 0 | + values: | reserved | cpu id | offset | + + All CPU interface regs are (rw, 32-bit) + + The offset specifies the offset from the "CPU interface base address" as + defined in the GICv2 specs. Getting or setting such a register has the + same effect as reading or writing the register on the actual hardware. + + The Active Priorities Registers APRn are implementation defined, so we set a + fixed format for our implementation that fits with the model of a "GICv2 + implementation without the security extensions" which we present to the + guest. This interface always exposes four register APR[0-3] describing the + maximum possible 128 preemption levels. The semantics of the register + indicate if any interrupts in a given preemption level are in the active + state by setting the corresponding bit. + + Thus, preemption level X has one or more active interrupts if and only if: + + APRn[X mod 32] == 0b1, where n = X / 32 + + Bits for undefined preemption levels are RAZ/WI. + + Limitations: + - Priorities are not implemented, and registers are RAZ/WI + Errors: + -ENODEV: Getting or setting this register is not yet supported + -EBUSY: One or more VCPUs are running diff --git a/Documentation/virtual/kvm/hypercalls.txt b/Documentation/virtual/kvm/hypercalls.txt index 022198e389d7..c8d040e27046 100644 --- a/Documentation/virtual/kvm/hypercalls.txt +++ b/Documentation/virtual/kvm/hypercalls.txt @@ -17,6 +17,9 @@ S390: S390 uses diagnose instruction as hypercall (0x500) along with hypercall number in R1. + For further information on the S390 diagnose call as supported by KVM, + refer to Documentation/virtual/kvm/s390-diag.txt. + PowerPC: It uses R3-R10 and hypercall number in R11. R4-R11 are used as output registers. Return value is placed in R3. @@ -74,7 +77,7 @@ Usage example : A vcpu of a paravirtualized guest that is busywaiting in guest kernel mode for an event to occur (ex: a spinlock to become available) can execute HLT instruction once it has busy-waited for more than a threshold time-interval. Execution of HLT instruction would cause the hypervisor to put -the vcpu to sleep until occurence of an appropriate event. Another vcpu of the +the vcpu to sleep until occurrence of an appropriate event. Another vcpu of the same guest can wakeup the sleeping vcpu by issuing KVM_HC_KICK_CPU hypercall, specifying APIC ID (a1) of the vcpu to be woken up. An additional argument (a0) is used in the hypercall for future use. diff --git a/Documentation/virtual/kvm/locking.txt b/Documentation/virtual/kvm/locking.txt index f8869410d40c..d68af4dc3006 100644 --- a/Documentation/virtual/kvm/locking.txt +++ b/Documentation/virtual/kvm/locking.txt @@ -112,7 +112,7 @@ The Dirty bit is lost in this case. In order to avoid this kind of issue, we always treat the spte as "volatile" if it can be updated out of mmu-lock, see spte_has_volatile_bits(), it means, -the spte is always atomicly updated in this case. +the spte is always atomically updated in this case. 3): flush tlbs due to spte updated If the spte is updated from writable to readonly, we should flush all TLBs, @@ -125,7 +125,7 @@ be flushed caused by this reason in mmu_spte_update() since this is a common function to update spte (present -> present). Since the spte is "volatile" if it can be updated out of mmu-lock, we always -atomicly update the spte, the race caused by fast page fault can be avoided, +atomically update the spte, the race caused by fast page fault can be avoided, See the comments in spte_has_volatile_bits() and mmu_spte_update(). 3. Reference diff --git a/Documentation/virtual/kvm/ppc-pv.txt b/Documentation/virtual/kvm/ppc-pv.txt index 4cd076febb02..4643cde517c4 100644 --- a/Documentation/virtual/kvm/ppc-pv.txt +++ b/Documentation/virtual/kvm/ppc-pv.txt @@ -115,7 +115,7 @@ If any other bit changes in the MSR, please still use mtmsr(d). Patched instructions ==================== -The "ld" and "std" instructions are transormed to "lwz" and "stw" instructions +The "ld" and "std" instructions are transformed to "lwz" and "stw" instructions respectively on 32 bit systems with an added offset of 4 to accommodate for big endianness. diff --git a/Documentation/virtual/kvm/s390-diag.txt b/Documentation/virtual/kvm/s390-diag.txt new file mode 100644 index 000000000000..f1de4fbade15 --- /dev/null +++ b/Documentation/virtual/kvm/s390-diag.txt @@ -0,0 +1,80 @@ +The s390 DIAGNOSE call on KVM +============================= + +KVM on s390 supports the DIAGNOSE call for making hypercalls, both for +native hypercalls and for selected hypercalls found on other s390 +hypervisors. + +Note that bits are numbered as by the usual s390 convention (most significant +bit on the left). + + +General remarks +--------------- + +DIAGNOSE calls by the guest cause a mandatory intercept. This implies +all supported DIAGNOSE calls need to be handled by either KVM or its +userspace. + +All DIAGNOSE calls supported by KVM use the RS-a format: + +-------------------------------------- +| '83' | R1 | R3 | B2 | D2 | +-------------------------------------- +0 8 12 16 20 31 + +The second-operand address (obtained by the base/displacement calculation) +is not used to address data. Instead, bits 48-63 of this address specify +the function code, and bits 0-47 are ignored. + +The supported DIAGNOSE function codes vary by the userspace used. For +DIAGNOSE function codes not specific to KVM, please refer to the +documentation for the s390 hypervisors defining them. + + +DIAGNOSE function code 'X'500' - KVM virtio functions +----------------------------------------------------- + +If the function code specifies 0x500, various virtio-related functions +are performed. + +General register 1 contains the virtio subfunction code. Supported +virtio subfunctions depend on KVM's userspace. Generally, userspace +provides either s390-virtio (subcodes 0-2) or virtio-ccw (subcode 3). + +Upon completion of the DIAGNOSE instruction, general register 2 contains +the function's return code, which is either a return code or a subcode +specific value. + +Subcode 0 - s390-virtio notification and early console printk + Handled by userspace. + +Subcode 1 - s390-virtio reset + Handled by userspace. + +Subcode 2 - s390-virtio set status + Handled by userspace. + +Subcode 3 - virtio-ccw notification + Handled by either userspace or KVM (ioeventfd case). + + General register 2 contains a subchannel-identification word denoting + the subchannel of the virtio-ccw proxy device to be notified. + + General register 3 contains the number of the virtqueue to be notified. + + General register 4 contains a 64bit identifier for KVM usage (the + kvm_io_bus cookie). If general register 4 does not contain a valid + identifier, it is ignored. + + After completion of the DIAGNOSE call, general register 2 may contain + a 64bit identifier (in the kvm_io_bus cookie case). + + See also the virtio standard for a discussion of this hypercall. + + +DIAGNOSE function code 'X'501 - KVM breakpoint +---------------------------------------------- + +If the function code specifies 0x501, breakpoint functions may be performed. +This function code is handled by userspace. diff --git a/Documentation/virtual/kvm/timekeeping.txt b/Documentation/virtual/kvm/timekeeping.txt index df8946377cb6..76808a17ad84 100644 --- a/Documentation/virtual/kvm/timekeeping.txt +++ b/Documentation/virtual/kvm/timekeeping.txt @@ -467,7 +467,7 @@ at any time. This causes problems as the passage of real time, the injection of machine interrupts and the associated clock sources are no longer completely synchronized with real time. -This same problem can occur on native harware to a degree, as SMM mode may +This same problem can occur on native hardware to a degree, as SMM mode may steal cycles from the naturally on X86 systems when SMM mode is used by the BIOS, but not in such an extreme fashion. However, the fact that SMM mode may cause similar problems to virtualization makes it a good justification for diff --git a/Documentation/vm/locking b/Documentation/vm/locking deleted file mode 100644 index f61228bd6395..000000000000 --- a/Documentation/vm/locking +++ /dev/null @@ -1,130 +0,0 @@ -Started Oct 1999 by Kanoj Sarcar - -The intent of this file is to have an uptodate, running commentary -from different people about how locking and synchronization is done -in the Linux vm code. - -page_table_lock & mmap_sem --------------------------------------- - -Page stealers pick processes out of the process pool and scan for -the best process to steal pages from. To guarantee the existence -of the victim mm, a mm_count inc and a mmdrop are done in swap_out(). -Page stealers hold kernel_lock to protect against a bunch of races. -The vma list of the victim mm is also scanned by the stealer, -and the page_table_lock is used to preserve list sanity against the -process adding/deleting to the list. This also guarantees existence -of the vma. Vma existence is not guaranteed once try_to_swap_out() -drops the page_table_lock. To guarantee the existence of the underlying -file structure, a get_file is done before the swapout() method is -invoked. The page passed into swapout() is guaranteed not to be reused -for a different purpose because the page reference count due to being -present in the user's pte is not released till after swapout() returns. - -Any code that modifies the vmlist, or the vm_start/vm_end/ -vm_flags:VM_LOCKED/vm_next of any vma *in the list* must prevent -kswapd from looking at the chain. - -The rules are: -1. To scan the vmlist (look but don't touch) you must hold the - mmap_sem with read bias, i.e. down_read(&mm->mmap_sem) -2. To modify the vmlist you need to hold the mmap_sem with - read&write bias, i.e. down_write(&mm->mmap_sem) *AND* - you need to take the page_table_lock. -3. The swapper takes _just_ the page_table_lock, this is done - because the mmap_sem can be an extremely long lived lock - and the swapper just cannot sleep on that. -4. The exception to this rule is expand_stack, which just - takes the read lock and the page_table_lock, this is ok - because it doesn't really modify fields anybody relies on. -5. You must be able to guarantee that while holding page_table_lock - or page_table_lock of mm A, you will not try to get either lock - for mm B. - -The caveats are: -1. find_vma() makes use of, and updates, the mmap_cache pointer hint. -The update of mmap_cache is racy (page stealer can race with other code -that invokes find_vma with mmap_sem held), but that is okay, since it -is a hint. This can be fixed, if desired, by having find_vma grab the -page_table_lock. - - -Code that add/delete elements from the vmlist chain are -1. callers of insert_vm_struct -2. callers of merge_segments -3. callers of avl_remove - -Code that changes vm_start/vm_end/vm_flags:VM_LOCKED of vma's on -the list: -1. expand_stack -2. mprotect -3. mlock -4. mremap - -It is advisable that changes to vm_start/vm_end be protected, although -in some cases it is not really needed. Eg, vm_start is modified by -expand_stack(), it is hard to come up with a destructive scenario without -having the vmlist protection in this case. - -The page_table_lock nests with the inode i_mmap_mutex and the kmem cache -c_spinlock spinlocks. This is okay, since the kmem code asks for pages after -dropping c_spinlock. The page_table_lock also nests with pagecache_lock and -pagemap_lru_lock spinlocks, and no code asks for memory with these locks -held. - -The page_table_lock is grabbed while holding the kernel_lock spinning monitor. - -The page_table_lock is a spin lock. - -Note: PTL can also be used to guarantee that no new clones using the -mm start up ... this is a loose form of stability on mm_users. For -example, it is used in copy_mm to protect against a racing tlb_gather_mmu -single address space optimization, so that the zap_page_range (from -truncate) does not lose sending ipi's to cloned threads that might -be spawned underneath it and go to user mode to drag in pte's into tlbs. - -swap_lock --------------- -The swap devices are chained in priority order from the "swap_list" header. -The "swap_list" is used for the round-robin swaphandle allocation strategy. -The #free swaphandles is maintained in "nr_swap_pages". These two together -are protected by the swap_lock. - -The swap_lock also protects all the device reference counts on the -corresponding swaphandles, maintained in the "swap_map" array, and the -"highest_bit" and "lowest_bit" fields. - -The swap_lock is a spinlock, and is never acquired from intr level. - -To prevent races between swap space deletion or async readahead swapins -deciding whether a swap handle is being used, ie worthy of being read in -from disk, and an unmap -> swap_free making the handle unused, the swap -delete and readahead code grabs a temp reference on the swaphandle to -prevent warning messages from swap_duplicate <- read_swap_cache_async. - -Swap cache locking ------------------- -Pages are added into the swap cache with kernel_lock held, to make sure -that multiple pages are not being added (and hence lost) by associating -all of them with the same swaphandle. - -Pages are guaranteed not to be removed from the scache if the page is -"shared": ie, other processes hold reference on the page or the associated -swap handle. The only code that does not follow this rule is shrink_mmap, -which deletes pages from the swap cache if no process has a reference on -the page (multiple processes might have references on the corresponding -swap handle though). lookup_swap_cache() races with shrink_mmap, when -establishing a reference on a scache page, so, it must check whether the -page it located is still in the swapcache, or shrink_mmap deleted it. -(This race is due to the fact that shrink_mmap looks at the page ref -count with pagecache_lock, but then drops pagecache_lock before deleting -the page from the scache). - -do_wp_page and do_swap_page have MP races in them while trying to figure -out whether a page is "shared", by looking at the page_count + swap_count. -To preserve the sum of the counts, the page lock _must_ be acquired before -calling is_page_shared (else processes might switch their swap_count refs -to the page count refs, after the page count ref has been snapshotted). - -Swap device deletion code currently breaks all the scache assumptions, -since it grabs neither mmap_sem nor page_table_lock. diff --git a/Documentation/vm/overcommit-accounting b/Documentation/vm/overcommit-accounting index 8eaa2fc4b8fa..cbfaaa674118 100644 --- a/Documentation/vm/overcommit-accounting +++ b/Documentation/vm/overcommit-accounting @@ -14,8 +14,8 @@ The Linux kernel supports the following overcommit handling modes 2 - Don't overcommit. The total address space commit for the system is not permitted to exceed swap + a - configurable percentage (default is 50) of physical RAM. - Depending on the percentage you use, in most situations + configurable amount (default is 50%) of physical RAM. + Depending on the amount you use, in most situations this means a process will not be killed while accessing pages but will receive errors on memory allocation as appropriate. @@ -26,7 +26,8 @@ The Linux kernel supports the following overcommit handling modes The overcommit policy is set via the sysctl `vm.overcommit_memory'. -The overcommit percentage is set via `vm.overcommit_ratio'. +The overcommit amount can be set via `vm.overcommit_ratio' (percentage) +or `vm.overcommit_kbytes' (absolute value). The current overcommit limit and amount committed are viewable in /proc/meminfo as CommitLimit and Committed_AS respectively. diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index f4f268c2b826..cb81741d3b0b 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt @@ -608,6 +608,9 @@ Protocol: 2.12+ - If 1, the kernel supports the 64-bit EFI handoff entry point given at handover_offset + 0x200. + Bit 4 (read): XLF_EFI_KEXEC + - If 1, the kernel supports kexec EFI boot with EFI runtime support. + Field name: cmdline_size Type: read Offset/size: 0x238/4 diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index 1228b22e142b..5223479291a2 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt @@ -78,14 +78,6 @@ APICs no_timer_check Don't check the IO-APIC timer. This can work around problems with incorrect timer initialization on some boards. - - apicmaintimer Run time keeping from the local APIC timer instead - of using the PIT/HPET interrupt for this. This is useful - when the PIT/HPET interrupts are unreliable. - - noapicmaintimer Don't do time keeping using the APIC timer. - Useful when this option was auto selected, but doesn't work. - apicpmtimer Do APIC timer calibration using the pmtimer. Implies apicmaintimer. Useful when your PIT timer is totally @@ -144,11 +136,6 @@ Non Executable Mappings on Enable(default) off Disable -SMP - - additional_cpus=NUM Allow NUM more CPUs for hotplug - (defaults are specified by the BIOS, see Documentation/x86/x86_64/cpu-hotplug-spec) - NUMA numa=off Only set up a single NUMA node spanning all memory. @@ -289,16 +276,6 @@ Debugging kstack=N Print N words from the kernel stack in oops dumps. - pagefaulttrace Dump all page faults. Only useful for extreme debugging - and will create a lot of output. - - call_trace=[old|both|newfallback|new] - old: use old inexact backtracer - new: use new exact dwarf2 unwinder - both: print entries from both - newfallback: use new unwinder but fall back to old if it gets - stuck (default) - Miscellaneous nogbpages diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index 881582f75c9c..c584a51add15 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt @@ -28,4 +28,11 @@ reference. Current X86-64 implementations only support 40 bits of address space, but we support up to 46 bits. This expands into MBZ space in the page tables. +->trampoline_pgd: + +We map EFI runtime services in the aforementioned PGD in the virtual +range of 64Gb (arbitrarily set, can be raised if needed) + +0xffffffef00000000 - 0xffffffff00000000 + -Andi Kleen, Jul 2004 diff --git a/Documentation/xtensa/atomctl.txt b/Documentation/xtensa/atomctl.txt index 10a8d1ff35ec..1da783ac200c 100644 --- a/Documentation/xtensa/atomctl.txt +++ b/Documentation/xtensa/atomctl.txt @@ -40,5 +40,5 @@ See Section 4.3.12.4 of ISA; Bits: --------- --------------- ----------------- ---------------- 0 Exception Exception Exception 1 RCW Transaction RCW Transaction RCW Transaction - 2 Internal Operation Exception Reserved + 2 Internal Operation Internal Operation Reserved 3 Reserved Reserved Reserved diff --git a/Documentation/xtensa/mmu.txt b/Documentation/xtensa/mmu.txt index 2b1af7606d57..0312fe66475c 100644 --- a/Documentation/xtensa/mmu.txt +++ b/Documentation/xtensa/mmu.txt @@ -44,3 +44,21 @@ After step 4, we jump to intended (linked) address of this code. 40..5F -> 40 40..5F -> pc -> pc 40..5F -> pc 20..3F -> 20 -> 20 20..3F -> 20 00..1F -> 00 -> 00 00..1F -> 00 + +The default location of IO peripherals is above 0xf0000000. This may change +using a "ranges" property in a device tree simple-bus node. See ePAPR 1.1, §6.5 +for details on the syntax and semantic of simple-bus nodes. The following +limitations apply: + +1. Only top level simple-bus nodes are considered + +2. Only one (first) simple-bus node is considered + +3. Empty "ranges" properties are not supported + +4. Only the first triplet in the "ranges" property is considered + +5. The parent-bus-address value is rounded down to the nearest 256MB boundary + +6. The IO area covers the entire 256MB segment of parent-bus-address; the + "ranges" triplet length field is ignored diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO index 7fba5aab9ef9..6c914aa87e71 100644 --- a/Documentation/zh_CN/HOWTO +++ b/Documentation/zh_CN/HOWTO @@ -112,7 +112,7 @@ Linux内核代码中包含有大量的文档。这些文档对于学习如何与 其他关于如何正确地生成补丁的优秀文档包括: "The Perfect Patch" - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt "Linux kernel patch submission format" http://linux.yyz.us/patch-format.html @@ -515,7 +515,7 @@ Linux内核社区并不喜欢一下接收大段的代码。修改需要被恰当 想了解它具体应该看起来像什么,请查阅以下文档中的“ChangeLog”章节: “The Perfect Patch” - http://userweb.kernel.org/~akpm/stuff/tpp.txt + http://www.ozlabs.org/~akpm/stuff/tpp.txt 这些事情有时候做起来很难。要在任何方面都做到完美可能需要好几年时间。这是 diff --git a/Documentation/zorro.txt b/Documentation/zorro.txt index d5829d14774a..90a64d52bea2 100644 --- a/Documentation/zorro.txt +++ b/Documentation/zorro.txt @@ -95,8 +95,9 @@ The treatment of these regions depends on the type of Zorro space: ------------- linux/include/linux/zorro.h -linux/include/asm-{m68k,ppc}/zorro.h -linux/include/linux/zorro_ids.h +linux/include/uapi/linux/zorro.h +linux/include/uapi/linux/zorro_ids.h +linux/arch/m68k/include/asm/zorro.h linux/drivers/zorro /proc/bus/zorro diff --git a/MAINTAINERS b/MAINTAINERS index d3303eb1d102..2507f38b208f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -93,6 +93,11 @@ Descriptions of section entries: N: Files and directories with regex patterns. N: [^a-z]tegra all files whose path contains the word tegra One pattern per line. Multiple N: lines acceptable. + scripts/get_maintainer.pl has different behavior for files that + match F: pattern and matches of N: patterns. By default, + get_maintainer will not look at git log history when an F: pattern + match occurs. When an N: match occurs, git log history is used + to also notify the people that have git commit signatures. X: Files and directories that are NOT maintained, same rules as F: Files exclusions are tested before file matches. Can be useful for excluding a specific subdirectory, for instance: @@ -252,6 +257,7 @@ F: Documentation/ABI/testing/sysfs-bus-acpi F: drivers/pci/*acpi* F: drivers/pci/*/*acpi* F: drivers/pci/*/*/*acpi* +F: tools/power/acpi ACPI COMPONENT ARCHITECTURE (ACPICA) M: Robert Moore @@ -266,6 +272,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm S: Supported F: drivers/acpi/acpica/ F: include/acpi/ +F: tools/power/acpi/ ACPI FAN DRIVER M: Zhang Rui @@ -484,7 +491,6 @@ M: Hannes Reinecke L: linux-scsi@vger.kernel.org S: Maintained F: drivers/scsi/aic7xxx/ -F: drivers/scsi/aic7xxx_old/ AIMSLAB FM RADIO RECEIVER DRIVER M: Hans Verkuil @@ -539,6 +545,13 @@ F: drivers/tty/serial/altera_jtaguart.c F: include/linux/altera_uart.h F: include/linux/altera_jtaguart.h +AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER +M: Tom Lendacky +L: linux-crypto@vger.kernel.org +S: Supported +F: drivers/crypto/ccp/ +F: include/linux/ccp.h + AMD FAM15H PROCESSOR POWER MONITORING DRIVER M: Andreas Herrmann L: lm-sensors@lm-sensors.org @@ -766,7 +779,12 @@ ARM/Allwinner A1X SoC support M: Maxime Ripard L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: arch/arm/mach-sunxi/ +N: sun[x4567]i + +ARM/Allwinner SoC Clock Support +M: Emilio López +S: Maintained +F: drivers/clk/sunxi/ ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES M: Andrew Victor @@ -783,7 +801,7 @@ F: arch/arm/boot/dts/sama*.dts F: arch/arm/boot/dts/sama*.dtsi ARM/CALXEDA HIGHBANK ARCHITECTURE -M: Rob Herring +M: Rob Herring L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-highbank/ @@ -867,6 +885,12 @@ S: Maintained F: arch/arm/mach-ebsa110/ F: drivers/net/ethernet/amd/am79c961a.* +ARM/ENERGY MICRO (SILICON LABS) EFM32 SUPPORT +M: Uwe Kleine-König +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +N: efm32 + ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6) M: Daniel Ribeiro M: Stefan Schmidt @@ -1029,6 +1053,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-mvebu/ +ARM/Marvell Berlin SoC support +M: Sebastian Hesselbarth +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-berlin/ + ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support M: Jason Cooper M: Andrew Lunn @@ -1322,6 +1352,14 @@ F: drivers/rtc/rtc-ab8500.c F: drivers/rtc/rtc-pl031.c T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git +ARM/Ux500 CLOCK FRAMEWORK SUPPORT +M: Ulf Hansson +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +T: git git://git.linaro.org/people/ulfh/clk.git +S: Maintained +F: drivers/clk/ux500/ +F: include/linux/platform_data/clk-ux500.h + ARM/VFP SUPPORT M: Russell King L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1368,6 +1406,10 @@ T: git git://git.xilinx.com/linux-xlnx.git S: Supported F: arch/arm/mach-zynq/ F: drivers/cpuidle/cpuidle-zynq.c +N: zynq +N: xilinx +F: drivers/clocksource/cadence_ttc_timer.c +F: drivers/mmc/host/sdhci-of-arasan.c ARM SMMU DRIVER M: Will Deacon @@ -1432,7 +1474,7 @@ F: Documentation/aoe/ F: drivers/block/aoe/ ATHEROS ATH GENERIC UTILITIES -M: "Luis R. Rodriguez" +M: "Luis R. Rodriguez" L: linux-wireless@vger.kernel.org S: Supported F: drivers/net/wireless/ath/* @@ -1440,7 +1482,7 @@ F: drivers/net/wireless/ath/* ATHEROS ATH5K WIRELESS DRIVER M: Jiri Slaby M: Nick Kossifidis -M: "Luis R. Rodriguez" +M: "Luis R. Rodriguez" L: linux-wireless@vger.kernel.org L: ath5k-devel@lists.ath5k.org W: http://wireless.kernel.org/en/users/Drivers/ath5k @@ -1455,17 +1497,6 @@ T: git git://github.com/kvalo/ath.git S: Supported F: drivers/net/wireless/ath/ath6kl/ -ATHEROS ATH9K WIRELESS DRIVER -M: "Luis R. Rodriguez" -M: Jouni Malinen -M: Vasanthakumar Thiagarajan -M: Senthil Balasubramanian -L: linux-wireless@vger.kernel.org -L: ath9k-devel@lists.ath9k.org -W: http://wireless.kernel.org/en/users/Drivers/ath9k -S: Supported -F: drivers/net/wireless/ath/ath9k/ - WILOCITY WIL6210 WIRELESS DRIVER M: Vladimir Kondratiev L: linux-wireless@vger.kernel.org @@ -1595,11 +1626,10 @@ S: Supported F: drivers/scsi/esas2r AUDIT SUBSYSTEM -M: Al Viro M: Eric Paris L: linux-audit@redhat.com (subscribers-only) W: http://people.redhat.com/sgrubb/audit/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current.git +T: git git://git.infradead.org/users/eparis/audit.git S: Maintained F: include/linux/audit.h F: include/uapi/linux/audit.h @@ -2021,6 +2051,7 @@ L: linux-can@vger.kernel.org W: http://gitorious.org/linux-can T: git git://gitorious.org/linux-can/linux-can-next.git S: Maintained +F: Documentation/networking/can.txt F: net/can/ F: include/linux/can/core.h F: include/uapi/linux/can.h @@ -2155,6 +2186,11 @@ M: Nishank Trivedi S: Supported F: drivers/net/ethernet/cisco/enic/ +CISCO VIC LOW LATENCY NIC DRIVER +M: Upinder Malhi +S: Supported +F: drivers/infiniband/hw/usnic + CIRRUS LOGIC EP93XX ETHERNET DRIVER M: Hartley Sweeten L: netdev@vger.kernel.org @@ -2616,7 +2652,7 @@ S: Maintained F: drivers/platform/x86/dell-laptop.c DELL LAPTOP SMM DRIVER -S: Orphan +M: Guenter Roeck F: drivers/char/i8k.c F: include/uapi/linux/i8k.h @@ -2825,8 +2861,10 @@ F: include/uapi/drm/ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) M: Daniel Vetter +M: Jani Nikula L: intel-gfx@lists.freedesktop.org L: dri-devel@lists.freedesktop.org +Q: http://patchwork.freedesktop.org/project/intel-gfx/ T: git git://people.freedesktop.org/~danvet/drm-intel S: Supported F: drivers/gpu/drm/i915/ @@ -3330,6 +3368,7 @@ EXTERNAL CONNECTOR SUBSYSTEM (EXTCON) M: MyungJoo Ham M: Chanwoo Choi L: linux-kernel@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git S: Maintained F: drivers/extcon/ F: Documentation/extcon/ @@ -3339,7 +3378,6 @@ M: Jingoo Han L: linux-fbdev@vger.kernel.org S: Maintained F: drivers/video/exynos/exynos_dp* -F: include/video/exynos_dp* EXYNOS MIPI DISPLAY DRIVERS M: Inki Dae @@ -3629,6 +3667,7 @@ W: http://en.wikipedia.org/wiki/F2FS T: git git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git S: Maintained F: Documentation/filesystems/f2fs.txt +F: Documentation/ABI/testing/sysfs-fs-f2fs F: fs/f2fs/ F: include/linux/f2fs_fs.h @@ -3949,6 +3988,12 @@ S: Orphan F: Documentation/filesystems/hfs.txt F: fs/hfs/ +HFSPLUS FILESYSTEM +L: linux-fsdevel@vger.kernel.org +S: Orphan +F: Documentation/filesystems/hfsplus.txt +F: fs/hfsplus/ + HGA FRAMEBUFFER DRIVER M: Ferenc Bakonyi L: linux-nvidia@lists.surfsouth.com @@ -4469,7 +4514,7 @@ M: Deepak Saxena S: Maintained F: drivers/char/hw_random/ixp4xx-rng.c -INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf/i40e) +INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf/i40e/i40evf) M: Jeff Kirsher M: Jesse Brandeburg M: Bruce Allan @@ -4478,6 +4523,7 @@ M: Don Skidmore M: Greg Rose M: Alex Duyck M: John Ronciak +M: Mitch Williams L: e1000-devel@lists.sourceforge.net W: http://www.intel.com/support/feedback.htm W: http://e1000.sourceforge.net/ @@ -4493,6 +4539,7 @@ F: Documentation/networking/ixgb.txt F: Documentation/networking/ixgbe.txt F: Documentation/networking/ixgbevf.txt F: Documentation/networking/i40e.txt +F: Documentation/networking/i40evf.txt F: drivers/net/ethernet/intel/ INTEL-MID GPIO DRIVER @@ -4910,7 +4957,7 @@ F: include/linux/sunrpc/ F: include/uapi/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) -M: Gleb Natapov +M: Gleb Natapov M: Paolo Bonzini L: kvm@vger.kernel.org W: http://www.linux-kvm.org @@ -5136,6 +5183,11 @@ F: drivers/lguest/ F: include/linux/lguest*.h F: tools/lguest/ +LIBLOCKDEP +M: Sasha Levin +S: Maintained +F: tools/lib/lockdep/ + LINUX FOR IBM pSERIES (RS/6000) M: Paul Mackerras W: http://www.ibm.com/linux/ltc/projects/ppc @@ -5731,7 +5783,7 @@ F: drivers/mfd/ F: include/linux/mfd/ MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM -M: Chris Ball +M: Chris Ball L: linux-mmc@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git S: Maintained @@ -6256,7 +6308,7 @@ F: drivers/i2c/busses/i2c-ocores.c OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Grant Likely -M: Rob Herring +M: Rob Herring L: devicetree@vger.kernel.org W: http://fdt.secretlab.ca T: git git://git.secretlab.ca/git/linux-2.6.git @@ -6268,7 +6320,7 @@ K: of_get_property K: of_match_table OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS -M: Rob Herring +M: Rob Herring M: Pawel Moll M: Mark Rutland M: Ian Campbell @@ -6701,7 +6753,7 @@ F: include/linux/timer* F: kernel/*timer* POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS -M: Anton Vorontsov +M: Dmitry Eremin-Solenikov M: David Woodhouse T: git git://git.infradead.org/battery-2.6.git S: Maintained @@ -6920,8 +6972,7 @@ S: Maintained F: drivers/scsi/qla1280.[ch] QLOGIC QLA2XXX FC-SCSI DRIVER -M: Andrew Vasquez -M: linux-driver@qlogic.com +M: qla2xxx-upstream@qlogic.com L: linux-scsi@vger.kernel.org S: Supported F: Documentation/scsi/LICENSE.qla2xxx @@ -6983,6 +7034,14 @@ T: git git://linuxtv.org/anttip/media_tree.git S: Maintained F: drivers/media/tuners/qt1010* +QUALCOMM ATHEROS ATH9K WIRELESS DRIVER +M: QCA ath9k Development +L: linux-wireless@vger.kernel.org +L: ath9k-devel@lists.ath9k.org +W: http://wireless.kernel.org/en/users/Drivers/ath9k +S: Supported +F: drivers/net/wireless/ath/ath9k/ + QUALCOMM ATHEROS ATH10K WIRELESS DRIVER M: Kalle Valo L: ath10k@lists.infradead.org @@ -7094,6 +7153,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git F: Documentation/RCU/torture.txt F: kernel/rcu/torture.c +RCUTORTURE TEST FRAMEWORK +M: "Paul E. McKenney" +S: Supported +T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git +F: tools/testing/selftests/rcutorture + RDC R-321X SoC M: Florian Fainelli S: Maintained @@ -7392,6 +7457,12 @@ L: linux-media@vger.kernel.org S: Supported F: drivers/media/i2c/s5c73m3/* +SAMSUNG SOC CLOCK DRIVERS +M: Tomasz Figa +S: Supported +L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) +F: drivers/clk/samsung/ + SERIAL DRIVERS M: Greg Kroah-Hartman L: linux-serial@vger.kernel.org @@ -7463,7 +7534,7 @@ S: Maintained F: drivers/scsi/sr* SCSI RDMA PROTOCOL (SRP) INITIATOR -M: David Dillow +M: Bart Van Assche L: linux-rdma@vger.kernel.org S: Supported W: http://www.openfabrics.org @@ -7475,8 +7546,9 @@ F: include/scsi/srp.h SCSI SG DRIVER M: Doug Gilbert L: linux-scsi@vger.kernel.org -W: http://www.torque.net/sg +W: http://sg.danny.cz/sg S: Maintained +F: Documentation/scsi/scsi-generic.txt F: drivers/scsi/sg.c F: include/scsi/sg.h @@ -7538,7 +7610,7 @@ S: Maintained F: drivers/mmc/host/sdricoh_cs.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER -M: Chris Ball +M: Chris Ball L: linux-mmc@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git S: Maintained @@ -7631,7 +7703,7 @@ F: drivers/net/ethernet/emulex/benet/ SFC NETWORK DRIVER M: Solarflare linux maintainers -M: Ben Hutchings +M: Shradha Shah L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/sfc/ @@ -8556,6 +8628,7 @@ S: Supported F: drivers/thermal/ F: include/linux/thermal.h F: include/linux/cpu_cooling.h +F: Documentation/devicetree/bindings/thermal/ THINGM BLINK(1) USB RGB LED DRIVER M: Vivien Didelot @@ -8623,12 +8696,11 @@ S: Maintained F: sound/soc/codecs/twl4030* TI WILINK WIRELESS DRIVERS -M: Luciano Coelho L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org/en/users/Drivers/wl12xx W: http://wireless.kernel.org/en/users/Drivers/wl1251 T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git -S: Maintained +S: Orphan F: drivers/net/wireless/ti/ F: include/linux/wl12xx.h @@ -8697,7 +8769,6 @@ F: include/linux/toshiba.h F: include/uapi/linux/toshiba.h TMIO MMC DRIVER -M: Guennadi Liakhovetski M: Ian Molton L: linux-mmc@vger.kernel.org S: Maintained @@ -8729,14 +8800,10 @@ S: Odd fixes F: drivers/media/usb/tm6000/ TPM DEVICE DRIVER -M: Leonidas Da Silva Barbosa -M: Ashley Lai M: Peter Huewe -M: Rajiv Andrade -W: http://tpmdd.sourceforge.net +M: Ashley Lai M: Marcel Selhorst -M: Sirrix AG -W: http://www.sirrix.com +W: http://tpmdd.sourceforge.net L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) S: Maintained F: drivers/char/tpm/ @@ -9226,6 +9293,7 @@ F: include/media/videobuf2-* VIRTIO CONSOLE DRIVER M: Amit Shah +L: virtio-dev@lists.oasis-open.org L: virtualization@lists.linux-foundation.org S: Maintained F: drivers/char/virtio_console.c @@ -9235,6 +9303,7 @@ F: include/uapi/linux/virtio_console.h VIRTIO CORE, NET AND BLOCK DRIVERS M: Rusty Russell M: "Michael S. Tsirkin" +L: virtio-dev@lists.oasis-open.org L: virtualization@lists.linux-foundation.org S: Maintained F: drivers/virtio/ @@ -9247,6 +9316,7 @@ F: include/uapi/linux/virtio_*.h VIRTIO HOST (VHOST) M: "Michael S. Tsirkin" L: kvm@vger.kernel.org +L: virtio-dev@lists.oasis-open.org L: virtualization@lists.linux-foundation.org L: netdev@vger.kernel.org S: Maintained @@ -9544,6 +9614,7 @@ M: Konrad Rzeszutek Wilk M: Boris Ostrovsky M: David Vrabel L: xen-devel@lists.xenproject.org (moderated for non-subscribers) +T: git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git S: Supported F: arch/x86/xen/ F: drivers/*/xen-*front.c diff --git a/Makefile b/Makefile index 14d592cbbc5f..455fd484b20e 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 13 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = NAME = One Giant Leap for Frogkind # *DOCUMENTATION* @@ -595,10 +595,24 @@ ifneq ($(CONFIG_FRAME_WARN),0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif -# Force gcc to behave correct even for buggy distributions -ifndef CONFIG_CC_STACKPROTECTOR -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector) +# Handle stack protector mode. +ifdef CONFIG_CC_STACKPROTECTOR_REGULAR + stackp-flag := -fstack-protector + ifeq ($(call cc-option, $(stackp-flag)),) + $(warning Cannot use CONFIG_CC_STACKPROTECTOR: \ + -fstack-protector not supported by compiler)) + endif +else ifdef CONFIG_CC_STACKPROTECTOR_STRONG + stackp-flag := -fstack-protector-strong + ifeq ($(call cc-option, $(stackp-flag)),) + $(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \ + -fstack-protector-strong not supported by compiler) + endif +else + # Force off for distro compilers that enable stack protector by default. + stackp-flag := $(call cc-option, -fno-stack-protector) endif +KBUILD_CFLAGS += $(stackp-flag) # This warning generated too much noise in a regular build. # Use make W=1 to enable this warning (see scripts/Makefile.build) diff --git a/arch/Kconfig b/arch/Kconfig index f1cf895c040f..80bbb8ccd0d1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -336,6 +336,73 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. +config HAVE_CC_STACKPROTECTOR + bool + help + An arch should select this symbol if: + - its compiler supports the -fstack-protector option + - it has implemented a stack canary (e.g. __stack_chk_guard) + +config CC_STACKPROTECTOR + def_bool n + help + Set when a stack-protector mode is enabled, so that the build + can enable kernel-side support for the GCC feature. + +choice + prompt "Stack Protector buffer overflow detection" + depends on HAVE_CC_STACKPROTECTOR + default CC_STACKPROTECTOR_NONE + help + This option turns on the "stack-protector" GCC feature. This + feature puts, at the beginning of functions, a canary value on + the stack just before the return address, and validates + the value just before actually returning. Stack based buffer + overflows (that need to overwrite this return address) now also + overwrite the canary, which gets detected and the attack is then + neutralized via a kernel panic. + +config CC_STACKPROTECTOR_NONE + bool "None" + help + Disable "stack-protector" GCC feature. + +config CC_STACKPROTECTOR_REGULAR + bool "Regular" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added if they + have an 8-byte or larger character array on the stack. + + This feature requires gcc version 4.2 or above, or a distribution + gcc with the feature backported ("-fstack-protector"). + + On an x86 "defconfig" build, this feature adds canary checks to + about 3% of all kernel functions, which increases kernel code size + by about 0.3%. + +config CC_STACKPROTECTOR_STRONG + bool "Strong" + select CC_STACKPROTECTOR + help + Functions will have the stack-protector canary logic added in any + of the following conditions: + + - local variable's address used as part of the right hand side of an + assignment or function argument + - local variable is an array (or union containing an array), + regardless of array type or length + - uses register local variables + + This feature requires gcc version 4.9 or above, or a distribution + gcc with the feature backported ("-fstack-protector-strong"). + + On an x86 "defconfig" build, this feature adds canary checks to + about 20% of all kernel functions, which increases the kernel code + size by about 2%. + +endchoice + config HAVE_CONTEXT_TRACKING bool help diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index d39dc9b95a2c..97a2d9a096b9 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -2,6 +2,7 @@ config ALPHA bool default y select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_MIGHT_HAVE_PC_SERIO select HAVE_AOUT select HAVE_IDE select HAVE_OPROFILE @@ -539,13 +540,13 @@ config SMP depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL ---help--- This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. + a system with only one CPU, say N. If you have a system with more + than one CPU, say Y. - If you say N here, the kernel will run on single and multiprocessor + If you say N here, the kernel will run on uni- and multiprocessor machines, but will use only one CPU of a multiprocessor machine. If you say Y here, the kernel will run on many, but not all, - singleprocessor machines. On a singleprocessor machine, the kernel + uniprocessor machines. On a uniprocessor machine, the kernel will run faster if you say N here. See also the SMP-HOWTO available at diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index f01fb505ad52..a73a8e208a4a 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -4,3 +4,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h generic-y += preempt.h +generic-y += hash.h diff --git a/arch/alpha/include/asm/barrier.h b/arch/alpha/include/asm/barrier.h index ce8860a0b32d..3832bdb794fe 100644 --- a/arch/alpha/include/asm/barrier.h +++ b/arch/alpha/include/asm/barrier.h @@ -3,33 +3,18 @@ #include -#define mb() \ -__asm__ __volatile__("mb": : :"memory") +#define mb() __asm__ __volatile__("mb": : :"memory") +#define rmb() __asm__ __volatile__("mb": : :"memory") +#define wmb() __asm__ __volatile__("wmb": : :"memory") -#define rmb() \ -__asm__ __volatile__("mb": : :"memory") - -#define wmb() \ -__asm__ __volatile__("wmb": : :"memory") - -#define read_barrier_depends() \ -__asm__ __volatile__("mb": : :"memory") +#define read_barrier_depends() __asm__ __volatile__("mb": : :"memory") #ifdef CONFIG_SMP #define __ASM_SMP_MB "\tmb\n" -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() #else #define __ASM_SMP_MB -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) #endif -#define set_mb(var, value) \ -do { var = value; mb(); } while (0) +#include #endif /* __BARRIER_H */ diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index e3a1491d5073..3de1394bcab8 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -85,4 +85,6 @@ #define SO_MAX_PACING_RATE 47 +#define SO_BPF_EXTENSIONS 48 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 2b183b0d3207..99e8d4796c96 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -83,7 +83,7 @@ static int pci_mmap_resource(struct kobject *kobj, if (iomem_is_exclusive(res->start)) return -EINVAL; - pcibios_resource_to_bus(pdev, &bar, res); + pcibios_resource_to_bus(pdev->bus, &bar, res); vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0)); mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; @@ -139,7 +139,7 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num) long dense_offset; unsigned long sparse_size; - pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]); + pcibios_resource_to_bus(pdev->bus, &bar, &pdev->resource[num]); /* All core logic chips have 4G sparse address space, except CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index a21d0ab3b19e..eddee7720343 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -325,7 +325,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, /* Helper for generic DMA-mapping functions. */ static struct pci_dev *alpha_gendev_to_pci(struct device *dev) { - if (dev && dev->bus == &pci_bus_type) + if (dev && dev_is_pci(dev)) return to_pci_dev(dev); /* Assume that non-PCI devices asking for DMA are either ISA or EISA, diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 9063ae6553cc..9be30c8cb0c2 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -128,8 +128,8 @@ config SMP default n help This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. + a system with only one CPU, say N. If you have a system with more + than one CPU, say Y. if SMP @@ -409,17 +409,6 @@ config ARC_DBG_TLB_MISS_COUNT Counts number of I and D TLB Misses and exports them via Debugfs The counters can be cleared via Debugfs as well -config CMDLINE_UBOOT - bool "Support U-boot kernel command line passing" - default n - help - If you are using U-boot (www.denx.de) and wish to pass the kernel - command line from the U-boot environment to the Linux kernel then - switch this option on. - ARC U-boot will setup the cmdline in RAM/flash and set r2 to point - to it. kernel startup code will append this to DeviceTree - /bootargs provided cmdline args. - config ARC_BUILTIN_DTB_NAME string "Built in DTB" help diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 5943f7f9d325..0d3362991c31 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -1,4 +1,5 @@ generic-y += auxvec.h +generic-y += barrier.h generic-y += bugs.h generic-y += bitsperlong.h generic-y += clkdev.h @@ -11,6 +12,7 @@ generic-y += fcntl.h generic-y += fb.h generic-y += ftrace.h generic-y += hardirq.h +generic-y += hash.h generic-y += hw_irq.h generic-y += ioctl.h generic-y += ioctls.h diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 83f03ca6caf6..03e494f695d1 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -190,6 +190,11 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) #endif /* !CONFIG_ARC_HAS_LLSC */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + /** * __atomic_add_unless - add unless the number is a given value * @v: pointer of type atomic_t diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h index f6cb7c4ffb35..c32245c3d1e9 100644 --- a/arch/arc/include/asm/barrier.h +++ b/arch/arc/include/asm/barrier.h @@ -30,11 +30,6 @@ #define smp_wmb() barrier() #endif -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - #define smp_read_barrier_depends() do { } while (0) #endif diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h index eefc29f08cdb..5d06eee43ea9 100644 --- a/arch/arc/include/asm/smp.h +++ b/arch/arc/include/asm/smp.h @@ -46,14 +46,14 @@ extern int smp_ipi_irq_setup(int cpu, int irq); * * @info: SoC SMP specific info for /proc/cpuinfo etc * @cpu_kick: For Master to kickstart a cpu (optionally at a PC) - * @ipi_send: To send IPI to a @cpumask - * @ips_clear: To clear IPI received by @cpu at @irq + * @ipi_send: To send IPI to a @cpu + * @ips_clear: To clear IPI received at @irq */ struct plat_smp_ops { const char *info; void (*cpu_kick)(int cpu, unsigned long pc); - void (*ipi_send)(void *callmap); - void (*ipi_clear)(int cpu, int irq); + void (*ipi_send)(int cpu); + void (*ipi_clear)(int irq); }; /* TBD: stop exporting it for direct population by platform */ diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 2c878e964a64..991997269d02 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -49,25 +49,13 @@ stext: st.ab 0, [r5,4] brlt r5, r6, 1b -#ifdef CONFIG_CMDLINE_UBOOT - ; support for bootloader provided cmdline - ; If cmdline passed by u-boot, then - ; r0 = 1 (because ATAGS parsing, now retired, used to use 0) - ; r1 = magic number (board identity) - ; r2 = addr of cmdline string (somewhere in memory/flash) - - brne r0, 1, .Lother_bootup_chores ; u-boot didn't pass cmdline - breq r2, 0, .Lother_bootup_chores ; or cmdline is NULL - - mov r5, @command_line -1: - ldb.ab r6, [r2, 1] - breq r6, 0, .Lother_bootup_chores - b.d 1b - stb.ab r6, [r5, 1] -#endif - -.Lother_bootup_chores: + ; Uboot - kernel ABI + ; r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2 + ; r1 = magic number (board identity, unused as of now + ; r2 = pointer to uboot provided cmdline or external DTB in mem + ; These are handled later in setup_arch() + st r0, [@uboot_tag] + st r2, [@uboot_arg] ; Identify if running on ISS vs Silicon ; IDENTITY Reg [ 3 2 1 0 ] diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 643eae4436e0..119dddb752b2 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -29,7 +29,10 @@ int running_on_hw = 1; /* vs. on ISS */ -char __initdata command_line[COMMAND_LINE_SIZE]; +/* Part of U-boot ABI: see head.S */ +int __initdata uboot_tag; +char __initdata *uboot_arg; + const struct machine_desc *machine_desc; struct task_struct *_current_task[NR_CPUS]; /* For stack switching */ @@ -311,19 +314,40 @@ void setup_processor(void) arc_chk_fpu(); } +static inline int is_kernel(unsigned long addr) +{ + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) + return 1; + return 0; +} + void __init setup_arch(char **cmdline_p) { - /* This also populates @boot_command_line from /bootargs */ - machine_desc = setup_machine_fdt(__dtb_start); - if (!machine_desc) - panic("Embedded DT invalid\n"); + /* make sure that uboot passed pointer to cmdline/dtb is valid */ + if (uboot_tag && is_kernel((unsigned long)uboot_arg)) + panic("Invalid uboot arg\n"); - /* Append any u-boot provided cmdline */ -#ifdef CONFIG_CMDLINE_UBOOT - /* Add a whitespace seperator between the 2 cmdlines */ - strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); - strlcat(boot_command_line, command_line, COMMAND_LINE_SIZE); -#endif + /* See if u-boot passed an external Device Tree blob */ + machine_desc = setup_machine_fdt(uboot_arg); /* uboot_tag == 2 */ + if (!machine_desc) { + /* No, so try the embedded one */ + machine_desc = setup_machine_fdt(__dtb_start); + if (!machine_desc) + panic("Embedded DT invalid\n"); + + /* + * If we are here, it is established that @uboot_arg didn't + * point to DT blob. Instead if u-boot says it is cmdline, + * Appent to embedded DT cmdline. + * setup_machine_fdt() would have populated @boot_command_line + */ + if (uboot_tag == 1) { + /* Ensure a whitespace between the 2 cmdlines */ + strlcat(boot_command_line, " ", COMMAND_LINE_SIZE); + strlcat(boot_command_line, uboot_arg, + COMMAND_LINE_SIZE); + } + } /* Save unparsed command line copy for /proc/cmdline */ *cmdline_p = boot_command_line; diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index c2f9ebbc38f6..40859e5619f9 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -197,51 +197,65 @@ int __init setup_profiling_timer(unsigned int multiplier) /* Inter Processor Interrupt Handling */ /*****************************************************************************/ -/* - * structures for inter-processor calls - * A Collection of single bit ipi messages - * - */ - -/* - * TODO_rajesh investigate tlb message types. - * IPI Timer not needed because each ARC has an individual Interrupting Timer - */ enum ipi_msg_type { - IPI_NOP = 0, + IPI_EMPTY = 0, IPI_RESCHEDULE = 1, IPI_CALL_FUNC, - IPI_CPU_STOP + IPI_CPU_STOP, }; -struct ipi_data { - unsigned long bits; -}; +/* + * In arches with IRQ for each msg type (above), receiver can use IRQ-id to + * figure out what msg was sent. For those which don't (ARC has dedicated IPI + * IRQ), the msg-type needs to be conveyed via per-cpu data + */ -static DEFINE_PER_CPU(struct ipi_data, ipi_data); +static DEFINE_PER_CPU(unsigned long, ipi_data); -static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg) +static void ipi_send_msg_one(int cpu, enum ipi_msg_type msg) { + unsigned long __percpu *ipi_data_ptr = per_cpu_ptr(&ipi_data, cpu); + unsigned long old, new; unsigned long flags; - unsigned int cpu; + + pr_debug("%d Sending msg [%d] to %d\n", smp_processor_id(), msg, cpu); local_irq_save(flags); - for_each_cpu(cpu, callmap) { - struct ipi_data *ipi = &per_cpu(ipi_data, cpu); - set_bit(msg, &ipi->bits); - } + /* + * Atomically write new msg bit (in case others are writing too), + * and read back old value + */ + do { + new = old = *ipi_data_ptr; + new |= 1U << msg; + } while (cmpxchg(ipi_data_ptr, old, new) != old); - /* Call the platform specific cross-CPU call function */ - if (plat_smp_ops.ipi_send) - plat_smp_ops.ipi_send((void *)callmap); + /* + * Call the platform specific IPI kick function, but avoid if possible: + * Only do so if there's no pending msg from other concurrent sender(s). + * Otherwise, recevier will see this msg as well when it takes the + * IPI corresponding to that msg. This is true, even if it is already in + * IPI handler, because !@old means it has not yet dequeued the msg(s) + * so @new msg can be a free-loader + */ + if (plat_smp_ops.ipi_send && !old) + plat_smp_ops.ipi_send(cpu); local_irq_restore(flags); } +static void ipi_send_msg(const struct cpumask *callmap, enum ipi_msg_type msg) +{ + unsigned int cpu; + + for_each_cpu(cpu, callmap) + ipi_send_msg_one(cpu, msg); +} + void smp_send_reschedule(int cpu) { - ipi_send_msg(cpumask_of(cpu), IPI_RESCHEDULE); + ipi_send_msg_one(cpu, IPI_RESCHEDULE); } void smp_send_stop(void) @@ -254,7 +268,7 @@ void smp_send_stop(void) void arch_send_call_function_single_ipi(int cpu) { - ipi_send_msg(cpumask_of(cpu), IPI_CALL_FUNC); + ipi_send_msg_one(cpu, IPI_CALL_FUNC); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -265,33 +279,29 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) /* * ipi_cpu_stop - handle IPI from smp_send_stop() */ -static void ipi_cpu_stop(unsigned int cpu) +static void ipi_cpu_stop(void) { machine_halt(); } -static inline void __do_IPI(unsigned long *ops, struct ipi_data *ipi, int cpu) +static inline void __do_IPI(unsigned long msg) { - unsigned long msg = 0; + switch (msg) { + case IPI_RESCHEDULE: + scheduler_ipi(); + break; - do { - msg = find_next_bit(ops, BITS_PER_LONG, msg+1); + case IPI_CALL_FUNC: + generic_smp_call_function_interrupt(); + break; - switch (msg) { - case IPI_RESCHEDULE: - scheduler_ipi(); - break; - - case IPI_CALL_FUNC: - generic_smp_call_function_interrupt(); - break; - - case IPI_CPU_STOP: - ipi_cpu_stop(cpu); - break; - } - } while (msg < BITS_PER_LONG); + case IPI_CPU_STOP: + ipi_cpu_stop(); + break; + default: + pr_warn("IPI with unexpected msg %ld\n", msg); + } } /* @@ -300,19 +310,25 @@ static inline void __do_IPI(unsigned long *ops, struct ipi_data *ipi, int cpu) */ irqreturn_t do_IPI(int irq, void *dev_id) { - int cpu = smp_processor_id(); - struct ipi_data *ipi = &per_cpu(ipi_data, cpu); - unsigned long ops; + unsigned long pending; + + pr_debug("IPI [%ld] received on cpu %d\n", + *this_cpu_ptr(&ipi_data), smp_processor_id()); if (plat_smp_ops.ipi_clear) - plat_smp_ops.ipi_clear(cpu, irq); + plat_smp_ops.ipi_clear(irq); /* - * XXX: is this loop really needed - * And do we need to move ipi_clean inside + * "dequeue" the msg corresponding to this IPI (and possibly other + * piggybacked msg from elided IPIs: see ipi_send_msg_one() above) */ - while ((ops = xchg(&ipi->bits, 0)) != 0) - __do_IPI(&ops, ipi, cpu); + pending = xchg(this_cpu_ptr(&ipi_data), 0); + + do { + unsigned long msg = __ffs(pending); + __do_IPI(msg); + pending &= ~(1U << msg); + } while (pending); return IRQ_HANDLED; } diff --git a/arch/arc/plat-arcfpga/smp.c b/arch/arc/plat-arcfpga/smp.c index 91b55349a5f8..8a12741f5f7a 100644 --- a/arch/arc/plat-arcfpga/smp.c +++ b/arch/arc/plat-arcfpga/smp.c @@ -88,18 +88,14 @@ void iss_model_init_smp(unsigned int cpu) smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu); } -static void iss_model_ipi_send(void *arg) +static void iss_model_ipi_send(int cpu) { - struct cpumask *callmap = arg; - unsigned int cpu; - - for_each_cpu(cpu, callmap) - idu_irq_assert(cpu); + idu_irq_assert(cpu); } -static void iss_model_ipi_clear(int cpu, int irq) +static void iss_model_ipi_clear(int irq) { - idu_irq_clear(IDU_INTERRUPT_0 + cpu); + idu_irq_clear(IDU_INTERRUPT_0 + smp_processor_id()); } void iss_model_init_early_smp(void) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c1f1a7eee953..dc6ef9a2c649 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -6,12 +6,13 @@ config ARM select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_MIGHT_HAVE_PC_PARPORT + select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_EXTABLE_SORT if MMU select CLONE_BACKWARDS select CPU_PM if (SUSPEND || CPU_IDLE) - select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU + select DCACHE_WORD_ACCESS if HAVE_EFFICIENT_UNALIGNED_ACCESS select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IDLE_POLL_SETUP @@ -30,11 +31,13 @@ config ARM select HAVE_BPF_JIT select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT + select HAVE_CC_STACKPROTECTOR select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG select HAVE_DMA_ATTRS select HAVE_DMA_CONTIGUOUS if MMU select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) + select HAVE_EFFICIENT_UNALIGNED_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && MMU select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) @@ -62,6 +65,7 @@ config ARM select IRQ_FORCED_THREADING select KTIME_SCALAR select MODULES_USE_ELF_REL + select NO_BOOTMEM select OLD_SIGACTION select OLD_SIGSUSPEND3 select PERF_USE_VMALLOC @@ -313,6 +317,8 @@ config ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" select ARCH_HAS_CPUFREQ select ARM_AMBA + select ARM_PATCH_PHYS_VIRT + select AUTO_ZRELADDR select COMMON_CLK select COMMON_CLK_VERSATILE select GENERIC_CLOCKEVENTS @@ -410,6 +416,26 @@ config ARCH_EBSA110 Ethernet interface, two PCMCIA sockets, two serial ports and a parallel port. +config ARCH_EFM32 + bool "Energy Micro efm32" + depends on !MMU + select ARCH_REQUIRE_GPIOLIB + select ARM_NVIC + # CLKSRC_MMIO is wrong here, but needed until a proper fix is merged, + # i.e. CLKSRC_EFM32 selecting CLKSRC_MMIO + select CLKSRC_MMIO + select CLKSRC_OF + select COMMON_CLK + select CPU_V7M + select GENERIC_CLOCKEVENTS + select NO_DMA + select NO_IOPORT + select SPARSE_IRQ + select USE_OF + help + Support for Energy Micro's (now Silicon Labs) efm32 Giant Gecko + processors. + config ARCH_EP93XX bool "EP93xx-based" select ARCH_HAS_HOLES_MEMORYMODEL @@ -631,10 +657,10 @@ config ARCH_PXA help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. -config ARCH_MSM +config ARCH_MSM_NODT bool "Qualcomm MSM" + select ARCH_MSM select ARCH_REQUIRE_GPIOLIB - select CLKSRC_OF if OF select COMMON_CLK select GENERIC_CLOCKEVENTS help @@ -644,8 +670,9 @@ config ARCH_MSM stack and controls some vital subsystems (clock and power control, etc). -config ARCH_SHMOBILE - bool "Renesas SH-Mobile / R-Mobile" +config ARCH_SHMOBILE_LEGACY + bool "Renesas ARM SoCs (non-multiplatform)" + select ARCH_SHMOBILE select ARM_PATCH_PHYS_VIRT select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS @@ -660,7 +687,9 @@ config ARCH_SHMOBILE select PM_GENERIC_DOMAINS if PM select SPARSE_IRQ help - Support for Renesas's SH-Mobile and R-Mobile ARM platforms. + Support for Renesas ARM SoC platforms using a non-multiplatform + kernel. This includes the SH-Mobile, R-Mobile, EMMA-Mobile, R-Car + and RZ families. config ARCH_RPC bool "RiscPC" @@ -710,7 +739,6 @@ config ARCH_S3C24XX select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select MULTI_IRQ_HANDLER - select NEED_MACH_GPIO_H select NEED_MACH_IO_H select SAMSUNG_ATAGS help @@ -723,24 +751,23 @@ config ARCH_S3C64XX bool "Samsung S3C64XX" select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB + select ARM_AMBA select ARM_VIC select CLKDEV_LOOKUP select CLKSRC_SAMSUNG_PWM select COMMON_CLK - select CPU_V6 + select CPU_V6K select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_TCM - select NEED_MACH_GPIO_H select NO_IOPORT select PLAT_SAMSUNG select PM_GENERIC_DOMAINS select S3C_DEV_NAND select S3C_GPIO_TRACK select SAMSUNG_ATAGS - select SAMSUNG_GPIOLIB_4BIT select SAMSUNG_WAKEMASK select SAMSUNG_WDT_RESET select USB_ARCH_HAS_OHCI @@ -911,6 +938,8 @@ source "arch/arm/mach-bcm/Kconfig" source "arch/arm/mach-bcm2835/Kconfig" +source "arch/arm/mach-berlin/Kconfig" + source "arch/arm/mach-clps711x/Kconfig" source "arch/arm/mach-cns3xxx/Kconfig" @@ -927,6 +956,8 @@ source "arch/arm/mach-gemini/Kconfig" source "arch/arm/mach-highbank/Kconfig" +source "arch/arm/mach-hisi/Kconfig" + source "arch/arm/mach-integrator/Kconfig" source "arch/arm/mach-iop32x/Kconfig" @@ -945,6 +976,8 @@ source "arch/arm/mach-ks8695/Kconfig" source "arch/arm/mach-msm/Kconfig" +source "arch/arm/mach-moxart/Kconfig" + source "arch/arm/mach-mv78xx0/Kconfig" source "arch/arm/mach-imx/Kconfig" @@ -1053,6 +1086,8 @@ config ARM_TIMER_SP804 select CLKSRC_MMIO select CLKSRC_OF if OF +source "arch/arm/firmware/Kconfig" + source arch/arm/mm/Kconfig config ARM_NR_BANKS @@ -1435,14 +1470,14 @@ config SMP depends on MMU || ARM_MPU help This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. + a system with only one CPU, say N. If you have a system with more + than one CPU, say Y. - If you say N here, the kernel will run on single and multiprocessor + If you say N here, the kernel will run on uni- and multiprocessor machines, but will use only one CPU of a multiprocessor machine. If - you say Y here, the kernel will run on many, but not all, single - processor machines. On a single processor machine, the kernel will - run faster if you say N here. + you say Y here, the kernel will run on many, but not all, + uniprocessor machines. On a uniprocessor machine, the kernel + will run faster if you say N here. See also , and the SMP-HOWTO available at @@ -1593,7 +1628,7 @@ config ARM_PSCI config ARCH_NR_GPIO int default 1024 if ARCH_SHMOBILE || ARCH_TEGRA - default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || SOC_DRA7XX + default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX default 392 if ARCH_U8500 default 352 if ARCH_VT8500 default 288 if ARCH_SUNXI @@ -1611,7 +1646,7 @@ config HZ_FIXED default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \ ARCH_S5PV210 || ARCH_EXYNOS4 default AT91_TIMER_HZ if ARCH_AT91 - default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE + default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE_LEGACY default 0 choice @@ -1651,9 +1686,6 @@ config HZ config SCHED_HRTICK def_bool HIGH_RES_TIMERS -config SCHED_HRTICK - def_bool HIGH_RES_TIMERS - config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K @@ -1796,10 +1828,10 @@ config ARCH_WANT_GENERAL_HUGETLB source "mm/Kconfig" config FORCE_MAX_ZONEORDER - int "Maximum zone order" if ARCH_SHMOBILE - range 11 64 if ARCH_SHMOBILE + int "Maximum zone order" if ARCH_SHMOBILE_LEGACY + range 11 64 if ARCH_SHMOBILE_LEGACY default "12" if SOC_AM33XX - default "9" if SA1111 + default "9" if SA1111 || ARCH_EFM32 default "11" help The kernel memory allocator divides physically contiguous memory @@ -1856,18 +1888,6 @@ config SECCOMP and the task is only allowed to execute a few safe syscalls defined by each seccomp mode. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of functions, a canary value on - the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - This feature requires gcc version 4.2 or above. - config SWIOTLB def_bool y @@ -1946,6 +1966,7 @@ config ZBOOT_ROM_BSS config ZBOOT_ROM bool "Compressed boot loader in ROM/flash" depends on ZBOOT_ROM_TEXT != ZBOOT_ROM_BSS + depends on !ARM_APPENDED_DTB && !XIP_KERNEL && !AUTO_ZRELADDR help Say Y here if you intend to execute your compressed kernel image (zImage) directly from ROM or flash. If unsure, say N. @@ -1981,7 +2002,7 @@ endchoice config ARM_APPENDED_DTB bool "Use appended device tree blob to zImage (EXPERIMENTAL)" - depends on OF && !ZBOOT_ROM + depends on OF help With this option, the boot code will look for a device tree binary (DTB) appended to zImage @@ -2069,7 +2090,7 @@ endchoice config XIP_KERNEL bool "Kernel Execute-In-Place from ROM" - depends on !ZBOOT_ROM && !ARM_LPAE && !ARCH_MULTIPLATFORM + depends on !ARM_LPAE && !ARCH_MULTIPLATFORM help Execute-In-Place allows the kernel to run from non-volatile storage directly addressable by the CPU, such as NOR flash. This saves RAM @@ -2132,7 +2153,6 @@ config CRASH_DUMP config AUTO_ZRELADDR bool "Auto calculation of the decompressed kernel image address" - depends on !ZBOOT_ROM help ZRELADDR is the physical address where the decompressed kernel image will be placed. If AUTO_ZRELADDR is selected, the address diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 5765abf5ce84..0531da8e5216 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -2,6 +2,18 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config ARM_PTDUMP + bool "Export kernel pagetable layout to userspace via debugfs" + depends on DEBUG_KERNEL + select DEBUG_FS + ---help--- + Say Y here if you want to show the kernel pagetable layout in a + debugfs file. This information is only useful for kernel developers + who are working in architecture specific areas of the kernel. + It is probably not a good idea to enable this feature in a production + kernel. + If in doubt, say "N" + config STRICT_DEVMEM bool "Filter access to /dev/mem" depends on MMU @@ -94,6 +106,25 @@ choice depends on ARCH_BCM2835 select DEBUG_UART_PL01X + config DEBUG_BCM_KONA_UART + bool "Kernel low-level debugging messages via BCM KONA UART" + depends on ARCH_BCM + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Broadcom SoC platforms. + This low level debug works for Broadcom + mobile SoCs in the Kona family of chips (e.g. bcm28155, + bcm11351, etc...) + + config DEBUG_BERLIN_UART + bool "Marvell Berlin SoC Debug UART" + depends on ARCH_BERLIN + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Marvell Berlin SoC based platforms. + config DEBUG_CLPS711X_UART1 bool "Kernel low-level debugging messages via UART1" depends on ARCH_CLPS711X @@ -255,6 +286,13 @@ choice Say Y here if you want kernel low-level debugging support on i.MX35. + config DEBUG_IMX50_UART + bool "i.MX50 Debug UART" + depends on SOC_IMX50 + help + Say Y here if you want kernel low-level debugging support + on i.MX50. + config DEBUG_IMX51_UART bool "i.MX51 Debug UART" depends on SOC_IMX51 @@ -897,6 +935,7 @@ config DEBUG_IMX_UART_PORT DEBUG_IMX21_IMX27_UART || \ DEBUG_IMX31_UART || \ DEBUG_IMX35_UART || \ + DEBUG_IMX50_UART || \ DEBUG_IMX51_UART || \ DEBUG_IMX53_UART || \ DEBUG_IMX6Q_UART || \ @@ -931,6 +970,7 @@ config DEBUG_LL_INCLUDE DEBUG_IMX21_IMX27_UART || \ DEBUG_IMX31_UART || \ DEBUG_IMX35_UART || \ + DEBUG_IMX50_UART || \ DEBUG_IMX51_UART || \ DEBUG_IMX53_UART ||\ DEBUG_IMX6Q_UART || \ @@ -988,6 +1028,7 @@ config DEBUG_UART_PHYS default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 default 0x20201000 if DEBUG_BCM2835 + default 0x3e000000 if DEBUG_BCM_KONA_UART default 0x4000e400 if DEBUG_LL_UART_EFM32 default 0x40090000 if ARCH_LPC32XX default 0x40100000 if DEBUG_PXA_UART1 @@ -1011,6 +1052,7 @@ config DEBUG_UART_PHYS default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \ ARCH_ORION5X + default 0xf7fc9000 if DEBUG_BERLIN_UART default 0xf8b00000 if DEBUG_HI3716_UART default 0xfcb00000 if DEBUG_HI3620_UART default 0xfe800000 if ARCH_IOP32X @@ -1036,6 +1078,7 @@ config DEBUG_UART_VIRT default 0xf2100000 if DEBUG_PXA_UART1 default 0xf4090000 if ARCH_LPC32XX default 0xf4200000 if ARCH_GEMINI + default 0xf7fc9000 if DEBUG_BERLIN_UART default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9 default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 default 0xfb009000 if DEBUG_REALVIEW_STD_PORT @@ -1049,6 +1092,7 @@ config DEBUG_UART_VIRT default 0xfe018000 if DEBUG_MMP_UART3 default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART default 0xfe230000 if DEBUG_PICOXCELL_UART + default 0xfe300000 if DEBUG_BCM_KONA_UART default 0xfe800000 if ARCH_IOP32X default 0xfeb00000 if DEBUG_HI3620_UART || DEBUG_HI3716_UART default 0xfeb24000 if DEBUG_RK3X_UART0 @@ -1091,7 +1135,8 @@ config DEBUG_UART_8250_WORD default y if DEBUG_PICOXCELL_UART || DEBUG_SOCFPGA_UART || \ ARCH_KEYSTONE || \ DEBUG_DAVINCI_DMx_UART0 || DEBUG_DAVINCI_DA8XX_UART1 || \ - DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 + DEBUG_DAVINCI_DA8XX_UART2 || DEBUG_DAVINCI_TNETV107X_UART1 || \ + DEBUG_BCM_KONA_UART config DEBUG_UART_8250_FLOW_CONTROL bool "Enable flow control for 8250 UART" @@ -1150,4 +1195,15 @@ config PID_IN_CONTEXTIDR additional instructions during context switch. Say Y here only if you are planning to use hardware trace tools with this kernel. +config DEBUG_SET_MODULE_RONX + bool "Set loadable kernel module data as NX and text as RO" + depends on MODULES + ---help--- + This option helps catch unintended modifications to loadable + kernel module's text and read-only data. It also prevents execution + of module data. Such protection may interfere with run-time code + patching and dynamic kernel tracing - and they might also protect + against certain classes of kernel exploits. + If in doubt, say "N". + endmenu diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c99b1086d83d..23d5e3946589 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -40,10 +40,6 @@ ifeq ($(CONFIG_FRAME_POINTER),y) KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif -ifeq ($(CONFIG_CC_STACKPROTECTOR),y) -KBUILD_CFLAGS +=-fstack-protector -endif - ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) KBUILD_CPPFLAGS += -mbig-endian AS += -EB @@ -148,15 +144,18 @@ textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000 machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_BCM) += bcm machine-$(CONFIG_ARCH_BCM2835) += bcm2835 +machine-$(CONFIG_ARCH_BERLIN) += berlin machine-$(CONFIG_ARCH_CLPS711X) += clps711x machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx machine-$(CONFIG_ARCH_DAVINCI) += davinci machine-$(CONFIG_ARCH_DOVE) += dove machine-$(CONFIG_ARCH_EBSA110) += ebsa110 +machine-$(CONFIG_ARCH_EFM32) += efm32 machine-$(CONFIG_ARCH_EP93XX) += ep93xx machine-$(CONFIG_ARCH_EXYNOS) += exynos machine-$(CONFIG_ARCH_GEMINI) += gemini machine-$(CONFIG_ARCH_HIGHBANK) += highbank +machine-$(CONFIG_ARCH_HI3xxx) += hisi machine-$(CONFIG_ARCH_INTEGRATOR) += integrator machine-$(CONFIG_ARCH_IOP13XX) += iop13xx machine-$(CONFIG_ARCH_IOP32X) += iop32x @@ -167,6 +166,7 @@ machine-$(CONFIG_ARCH_KIRKWOOD) += kirkwood machine-$(CONFIG_ARCH_KS8695) += ks8695 machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx machine-$(CONFIG_ARCH_MMP) += mmp +machine-$(CONFIG_ARCH_MOXART) += moxart machine-$(CONFIG_ARCH_MSM) += msm machine-$(CONFIG_ARCH_MV78XX0) += mv78xx0 machine-$(CONFIG_ARCH_MVEBU) += mvebu @@ -190,7 +190,6 @@ machine-$(CONFIG_ARCH_S5PC100) += s5pc100 machine-$(CONFIG_ARCH_S5PV210) += s5pv210 machine-$(CONFIG_ARCH_SA1100) += sa1100 machine-$(CONFIG_ARCH_SHMOBILE) += shmobile -machine-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile machine-$(CONFIG_ARCH_SIRF) += prima2 machine-$(CONFIG_ARCH_SOCFPGA) += socfpga machine-$(CONFIG_ARCH_STI) += sti @@ -268,6 +267,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/ core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ core-y += arch/arm/net/ core-y += arch/arm/crypto/ +core-y += arch/arm/firmware/ core-y += $(machdirs) $(platdirs) drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index e7190bb5998e..68c918362b79 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -64,7 +64,7 @@ else endif endif -ifeq ($(CONFIG_ARCH_SHMOBILE),y) +ifeq ($(CONFIG_ARCH_SHMOBILE_LEGACY),y) OBJS += head-shmobile.o endif @@ -108,12 +108,12 @@ endif targets := vmlinux vmlinux.lds \ piggy.$(suffix_y) piggy.$(suffix_y).o \ - lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \ - font.o font.c head.o misc.o $(OBJS) + lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \ + bswapsdi2.S font.o font.c head.o misc.o $(OBJS) # Make sure files are removed during clean extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \ - lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) \ + lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \ hyp-stub.S ifeq ($(CONFIG_FUNCTION_TRACER),y) @@ -156,6 +156,12 @@ ashldi3 = $(obj)/ashldi3.o $(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S $(call cmd,shipped) +# For __bswapsi2, __bswapdi2 +bswapsdi2 = $(obj)/bswapsdi2.o + +$(obj)/bswapsdi2.S: $(srctree)/arch/$(SRCARCH)/lib/bswapsdi2.S + $(call cmd,shipped) + # We need to prevent any GOTOFF relocs being used with references # to symbols in the .bss section since we cannot relocate them # independently from the rest at run time. This can be achieved by @@ -177,7 +183,8 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \ fi $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ - $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE + $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \ + $(bswapsdi2) FORCE @$(check_for_multiple_zreladdr) $(call if_changed,ld) @$(check_for_bad_syms) diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 31bd43b82095..d4f891f56996 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -127,6 +127,18 @@ asmlinkage void __div0(void) error("Attempting division by 0!"); } +unsigned long __stack_chk_guard; + +void __stack_chk_guard_setup(void) +{ + __stack_chk_guard = 0x000a0dff; +} + +void __stack_chk_fail(void) +{ + error("stack-protector: Kernel stack is corrupted\n"); +} + extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)); @@ -137,6 +149,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p, { int ret; + __stack_chk_guard_setup(); + output_data = (unsigned char *)output_start; free_mem_ptr = free_mem_ptr_p; free_mem_end_ptr = free_mem_ptr_end_p; diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index d57c1a65b24f..ede21c16fdc0 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -6,6 +6,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb dtb-$(CONFIG_ARCH_AT91) += mpa1600.dtb # sam9260 dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb +dtb-$(CONFIG_ARCH_AT91) += at91-qil_a9260.dtb dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb @@ -30,6 +31,7 @@ dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb # sam9x5 dtb-$(CONFIG_ARCH_AT91) += at91-ariag25.dtb +dtb-$(CONFIG_ARCH_AT91) += at91-cosino_mega2560.dtb dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb @@ -40,11 +42,16 @@ dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb +dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb + dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \ bcm28155-ap.dtb dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb +dtb-$(CONFIG_ARCH_BERLIN) += \ + berlin2-sony-nsz-gs7.dtb \ + berlin2cd-google-chromecast.dtb dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \ da850-evm.dtb dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ @@ -52,6 +59,7 @@ dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ dove-d2plug.dtb \ dove-d3plug.dtb \ dove-dove-db.dtb +dtb-$(CONFIG_ARCH_EFM32) += efm32gg-dk3750.dtb dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ exynos4210-smdkv310.dtb \ exynos4210-trats.dtb \ @@ -59,13 +67,16 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ exynos4412-odroidx.dtb \ exynos4412-origen.dtb \ exynos4412-smdk4412.dtb \ + exynos4412-tiny4412.dtb \ exynos4412-trats2.dtb \ exynos5250-arndale.dtb \ exynos5250-smdk5250.dtb \ exynos5250-snow.dtb \ + exynos5420-arndale-octa.dtb \ exynos5420-smdk5420.dtb \ exynos5440-sd5v1.dtb \ exynos5440-ssdk5440.dtb +dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \ ecx-2000.dtb dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ @@ -85,11 +96,13 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \ kirkwood-iomega_ix2_200.dtb \ kirkwood-is2.dtb \ kirkwood-km_kirkwood.dtb \ + kirkwood-laplug.dtb \ kirkwood-lschlv2.dtb \ kirkwood-lsxhl.dtb \ kirkwood-mplcec4.dtb \ kirkwood-mv88f6281gtw-ge.dtb \ kirkwood-netgear_readynas_duo_v2.dtb \ + kirkwood-netgear_readynas_nv+_v2.dtb \ kirkwood-ns2.dtb \ kirkwood-ns2lite.dtb \ kirkwood-ns2max.dtb \ @@ -104,8 +117,10 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-cloudbox.dtb \ kirkwood-ts219-6281.dtb \ kirkwood-ts219-6282.dtb dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb +dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \ - qcom-msm8960-cdp.dtb + qcom-msm8960-cdp.dtb \ + qcom-apq8074-dragonboard.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ armada-370-mirabox.dtb \ armada-370-netgear-rn102.dtb \ @@ -114,6 +129,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ armada-xp-axpwifiap.dtb \ armada-xp-db.dtb \ armada-xp-gp.dtb \ + armada-xp-netgear-rn2120.dtb \ armada-xp-matrix.dtb \ armada-xp-openblocks-ax3-4.dtb dtb-$(CONFIG_ARCH_MXC) += \ @@ -173,12 +189,19 @@ dtb-$(CONFIG_ARCH_NSPIRE) += nspire-cx.dtb \ nspire-tp.dtb \ nspire-clp.dtb dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ + omap2430-sdp.dtb \ + omap2420-n800.dtb \ + omap2420-n810.dtb \ + omap2420-n810-wimax.dtb \ omap3430-sdp.dtb \ omap3-beagle.dtb \ + omap3-cm-t3730.dtb \ + omap3-sbc-t3730.dtb \ omap3-devkit8000.dtb \ omap3-beagle-xm.dtb \ omap3-evm.dtb \ omap3-evm-37xx.dtb \ + omap3-ldp.dtb \ omap3-n900.dtb \ omap3-n9.dtb \ omap3-n950.dtb \ @@ -216,8 +239,9 @@ dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \ s3c6410-smdk6410.dtb -dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ +dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += emev2-kzm9d.dtb \ r7s72100-genmai.dtb \ + r7s72100-genmai-reference.dtb \ r8a7740-armadillo800eva.dtb \ r8a7778-bockw.dtb \ r8a7778-bockw-reference.dtb \ @@ -226,13 +250,15 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ r8a7779-marzen-reference.dtb \ r8a7791-koelsch.dtb \ r8a7790-lager.dtb \ - r8a7790-lager-reference.dtb \ sh73a0-kzm9g.dtb \ sh73a0-kzm9g-reference.dtb \ r8a73a4-ape6evm.dtb \ r8a73a4-ape6evm-reference.dtb \ sh7372-mackerel.dtb -dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb +dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb \ + r7s72100-genmai-reference.dtb \ + r8a7791-koelsch.dtb \ + r8a7790-lager.dtb dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_arria5_socdk.dtb \ socfpga_cyclone5_socdk.dtb \ socfpga_cyclone5_sockit.dtb \ @@ -255,6 +281,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ sun4i-a10-hackberry.dtb \ sun5i-a10s-olinuxino-micro.dtb \ sun5i-a13-olinuxino.dtb \ + sun5i-a13-olinuxino-micro.dtb \ sun6i-a31-colombus.dtb \ sun7i-a20-cubieboard2.dtb \ sun7i-a20-cubietruck.dtb \ diff --git a/arch/arm/boot/dts/am3517-evm.dts b/arch/arm/boot/dts/am3517-evm.dts index 03fcbf0a88a8..b4127c6493a2 100644 --- a/arch/arm/boot/dts/am3517-evm.dts +++ b/arch/arm/boot/dts/am3517-evm.dts @@ -17,6 +17,21 @@ device_type = "memory"; reg = <0x80000000 0x10000000>; /* 256 MB */ }; + + vmmc_fixed: vmmc { + compatible = "regulator-fixed"; + regulator-name = "vmmc_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; +}; + +&davinci_emac { + status = "okay"; +}; + +&davinci_mdio { + status = "okay"; }; &i2c1 { @@ -30,3 +45,17 @@ &i2c3 { clock-frequency = <400000>; }; + +&mmc1 { + vmmc-supply = <&vmmc_fixed>; + bus-width = <4>; +}; + +&mmc2 { + status = "disabled"; +}; + +&mmc3 { + status = "disabled"; +}; + diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts index 3a1de9eb5111..3c4f6d983cbd 100644 --- a/arch/arm/boot/dts/animeo_ip.dts +++ b/arch/arm/boot/dts/animeo_ip.dts @@ -90,34 +90,19 @@ nand-on-flash-bbt; status = "okay"; - at91bootstrap@0 { - label = "at91bootstrap"; - reg = <0x0 0x8000>; - }; - - barebox@8000 { + barebox@0 { label = "barebox"; - reg = <0x8000 0x40000>; + reg = <0x0 0x58000>; }; - bareboxenv@48000 { - label = "bareboxenv"; - reg = <0x48000 0x8000>; + u_boot_env@58000 { + label = "u_boot_env"; + reg = <0x58000 0x8000>; }; - user_block@0x50000 { - label = "user_block"; - reg = <0x50000 0xb0000>; - }; - - kernel@100000 { - label = "kernel"; - reg = <0x100000 0x1b0000>; - }; - - root@2b0000 { - label = "root"; - reg = <0x2b0000 0x1D50000>; + ubi@60000 { + label = "ubi"; + reg = <0x60000 0x1FA0000>; }; }; diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index 2471d9da767b..944e8785b308 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -74,13 +74,13 @@ green_pwr_led { label = "mirabox:green:pwr"; gpios = <&gpio1 31 1>; - linux,default-trigger = "heartbeat"; + default-state = "keep"; }; blue_stat_led { label = "mirabox:blue:stat"; gpios = <&gpio2 0 1>; - linux,default-trigger = "cpu0"; + default-state = "off"; }; green_stat_led { @@ -139,6 +139,27 @@ reg = <0x25>; }; }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partition@0 { + label = "U-Boot"; + reg = <0 0x400000>; + }; + partition@400000 { + label = "Linux"; + reg = <0x400000 0x400000>; + }; + partition@800000 { + label = "Filesystem"; + reg = <0x800000 0x3f800000>; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts index 8ac2ac1f69cc..651aeb5ef439 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts @@ -11,6 +11,8 @@ /dts-v1/; +#include +#include #include "armada-370.dtsi" / { @@ -62,6 +64,7 @@ marvell,pins = "mpp57"; marvell,function = "gpio"; }; + sata1_led_pin: sata1-led-pin { marvell,pins = "mpp15"; marvell,function = "gpio"; @@ -77,6 +80,21 @@ marvell,function = "gpio"; }; + backup_button_pin: backup-button-pin { + marvell,pins = "mpp58"; + marvell,function = "gpio"; + }; + + power_button_pin: power-button-pin { + marvell,pins = "mpp62"; + marvell,function = "gpio"; + }; + + reset_button_pin: reset-button-pin { + marvell,pins = "mpp6"; + marvell,function = "gpio"; + }; + poweroff: poweroff { marvell,pins = "mpp8"; marvell,function = "gpio"; @@ -84,7 +102,7 @@ }; mdio { - phy0: ethernet-phy@0 { + phy0: ethernet-phy@0 { /* Marvell 88E1318 */ reg = <0>; }; }; @@ -104,6 +122,11 @@ clock-frequency = <100000>; status = "okay"; + isl12057: isl12057@68 { + compatible = "isl,isl12057"; + reg = <0x68>; + }; + g762: g762@3e { compatible = "gmt,g762"; reg = <0x3e>; @@ -113,82 +136,116 @@ pwm_polarity = <0>; }; }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; /* 1.5MB */ + read-only; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; /* 128KB */ + read-only; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; /* 6MB */ + }; + + partition@800000 { + label = "minirootfs"; + reg = <0x0800000 0x400000>; /* 4MB */ + }; + + /* Last MB is for the BBT, i.e. not writable */ + partition@c00000 { + label = "ubifs"; + reg = <0x0c00000 0x7400000>; /* 116MB */ + }; + }; }; }; clocks { - #address-cells = <1>; - #size-cells = <0>; - - g762_clk: fixedclk { + g762_clk: g762-oscillator { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <8192>; }; }; - gpio_leds { + gpio-leds { compatible = "gpio-leds"; - pinctrl-0 = < &power_led_pin - &sata1_led_pin - &sata2_led_pin - &backup_led_pin >; + pinctrl-0 = <&power_led_pin + &sata1_led_pin + &sata2_led_pin + &backup_led_pin>; pinctrl-names = "default"; - blue_power_led { + blue-power-led { label = "rn102:blue:pwr"; - gpios = <&gpio1 25 1>; /* GPIO 57 Active Low */ - linux,default-trigger = "heartbeat"; + gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; - green_sata1_led { + green-sata1-led { label = "rn102:green:sata1"; - gpios = <&gpio0 15 1>; /* GPIO 15 Active Low */ + gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; default-state = "on"; }; - green_sata2_led { + green-sata2-led { label = "rn102:green:sata2"; - gpios = <&gpio0 14 1>; /* GPIO 14 Active Low */ + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; default-state = "on"; }; - green_backup_led { + green-backup-led { label = "rn102:green:backup"; - gpios = <&gpio1 24 1>; /* GPIO 56 Active Low */ + gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; default-state = "on"; }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; + pinctrl-0 = <&power_button_pin + &reset_button_pin + &backup_button_pin>; + pinctrl-names = "default"; - button@1 { + power-button { label = "Power Button"; - linux,code = <116>; /* KEY_POWER */ - gpios = <&gpio1 30 0>; + linux,code = ; + gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; }; - button@2 { + reset-button { label = "Reset Button"; - linux,code = <0x198>; /* KEY_RESTART */ - gpios = <&gpio0 6 1>; + linux,code = ; + gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; }; - button@3 { + backup-button { label = "Backup Button"; - linux,code = <133>; /* KEY_COPY */ - gpios = <&gpio1 26 1>; + linux,code = ; + gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; }; }; - gpio_poweroff { + gpio-poweroff { compatible = "gpio-poweroff"; pinctrl-0 = <&poweroff>; pinctrl-names = "default"; - gpios = <&gpio0 8 1>; + gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; }; - }; diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts index b0b32f5fbeb4..4e27587667bf 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -11,6 +11,8 @@ /dts-v1/; +#include +#include #include "armada-370.dtsi" / { @@ -58,12 +60,12 @@ marvell,function = "gpio"; }; - backup_key_pin: backup-key-pin { + backup_button_pin: backup-button-pin { marvell,pins = "mpp52"; marvell,function = "gpio"; }; - power_key_pin: power-key-pin { + power_button_pin: power-button-pin { marvell,pins = "mpp62"; marvell,function = "gpio"; }; @@ -78,18 +80,18 @@ marvell,function = "gpio"; }; - reset_key_pin: reset-key-pin { + reset_button_pin: reset-button-pin { marvell,pins = "mpp65"; marvell,function = "gpio"; }; }; mdio { - phy0: ethernet-phy@0 { + phy0: ethernet-phy@0 { /* Marvell 88E1318 */ reg = <0>; }; - phy1: ethernet-phy@1 { + phy1: ethernet-phy@1 { /* Marvell 88E1318 */ reg = <1>; }; }; @@ -115,6 +117,11 @@ clock-frequency = <100000>; status = "okay"; + isl12057: isl12057@68 { + compatible = "isl,isl12057"; + reg = <0x68>; + }; + g762: g762@3e { compatible = "gmt,g762"; reg = <0x3e>; @@ -123,71 +130,133 @@ fan_startv = <1>; pwm_polarity = <0>; }; + + pca9554: pca9554@23 { + compatible = "nxp,pca9554"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x23>; + }; + }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; /* 1.5MB */ + read-only; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; /* 128KB */ + read-only; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; /* 6MB */ + }; + + partition@800000 { + label = "minirootfs"; + reg = <0x0800000 0x400000>; /* 4MB */ + }; + + /* Last MB is for the BBT, i.e. not writable */ + partition@c00000 { + label = "ubifs"; + reg = <0x0c00000 0x7400000>; /* 116MB */ + }; }; }; }; clocks { - #address-cells = <1>; - #size-cells = <0>; - - g762_clk: fixedclk { + g762_clk: g762-oscillator { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <8192>; }; }; - gpio_leds { + gpio-leds { compatible = "gpio-leds"; pinctrl-0 = <&backup_led_pin &power_led_pin>; pinctrl-names = "default"; - blue_backup_led { + blue-backup-led { label = "rn104:blue:backup"; - gpios = <&gpio1 31 0>; /* GPIO 63 Active High */ + gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>; default-state = "off"; }; - blue_power_led { + blue-power-led { label = "rn104:blue:pwr"; - gpios = <&gpio2 0 1>; /* GPIO 64 Active Low */ + gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; linux,default-trigger = "keep"; }; + + blue-sata1-led { + label = "rn104:blue:sata1"; + gpios = <&pca9554 0 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + blue-sata2-led { + label = "rn104:blue:sata2"; + gpios = <&pca9554 1 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + blue-sata3-led { + label = "rn104:blue:sata3"; + gpios = <&pca9554 2 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + blue-sata4-led { + label = "rn104:blue:sata4"; + gpios = <&pca9554 3 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&backup_key_pin - &power_key_pin - &reset_key_pin>; + pinctrl-0 = <&backup_button_pin + &power_button_pin + &reset_button_pin>; pinctrl-names = "default"; - button@1 { + backup-button { label = "Backup Button"; - linux,code = <133>; /* KEY_COPY */ - gpios = <&gpio1 20 1>; + linux,code = ; + gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; }; - button@2 { + power-button { label = "Power Button"; - linux,code = <116>; /* KEY_POWER */ - gpios = <&gpio1 30 0>; + linux,code = ; + gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; }; - button@3 { + reset-button { label = "Reset Button"; - linux,code = <0x198>; /* KEY_RESTART */ - gpios = <&gpio2 1 1>; + linux,code = ; + gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; }; }; - gpio_poweroff { + gpio-poweroff { compatible = "gpio-poweroff"; pinctrl-0 = <&poweroff>; pinctrl-names = "default"; - gpios = <&gpio1 28 1>; + gpios = <&gpio1 28 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts index f81810a59629..abbb807459d2 100644 --- a/arch/arm/boot/dts/armada-370-rd.dts +++ b/arch/arm/boot/dts/armada-370-rd.dts @@ -104,6 +104,27 @@ gpios = <&gpio0 6 1>; }; }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partition@0 { + label = "U-Boot"; + reg = <0 0x800000>; + }; + partition@800000 { + label = "Linux"; + reg = <0x800000 0x800000>; + }; + partition@1000000 { + label = "Filesystem"; + reg = <0x1000000 0x3f000000>; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index 7f10f627ae5b..74b5964430ac 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -103,22 +103,52 @@ #size-cells = <1>; ranges = <0 MBUS_ID(0xf0, 0x01) 0 0x100000>; - mbusc: mbus-controller@20000 { - compatible = "marvell,mbus-controller"; - reg = <0x20000 0x100>, <0x20180 0x20>; + rtc@10300 { + compatible = "marvell,orion-rtc"; + reg = <0x10300 0x20>; + interrupts = <50>; }; - mpic: interrupt-controller@20000 { - compatible = "marvell,mpic"; - #interrupt-cells = <1>; - #size-cells = <1>; - interrupt-controller; - msi-controller; + spi0: spi@10600 { + compatible = "marvell,orion-spi"; + reg = <0x10600 0x28>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <30>; + clocks = <&coreclk 0>; + status = "disabled"; }; - coherency-fabric@20200 { - compatible = "marvell,coherency-fabric"; - reg = <0x20200 0xb0>, <0x21010 0x1c>; + spi1: spi@10680 { + compatible = "marvell,orion-spi"; + reg = <0x10680 0x28>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + interrupts = <92>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c0: i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <31>; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; + }; + + i2c1: i2c@11100 { + compatible = "marvell,mv64xxx-i2c"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <32>; + timeout-ms = <1000>; + clocks = <&coreclk 0>; + status = "disabled"; }; serial@12000 { @@ -146,81 +176,29 @@ clock-output-names = "nand"; }; + mbusc: mbus-controller@20000 { + compatible = "marvell,mbus-controller"; + reg = <0x20000 0x100>, <0x20180 0x20>; + }; + + mpic: interrupt-controller@20000 { + compatible = "marvell,mpic"; + #interrupt-cells = <1>; + #size-cells = <1>; + interrupt-controller; + msi-controller; + }; + + coherency-fabric@20200 { + compatible = "marvell,coherency-fabric"; + reg = <0x20200 0xb0>, <0x21010 0x1c>; + }; + timer@20300 { reg = <0x20300 0x30>, <0x21040 0x30>; interrupts = <37>, <38>, <39>, <40>, <5>, <6>; }; - sata@a0000 { - compatible = "marvell,orion-sata"; - reg = <0xa0000 0x5000>; - interrupts = <55>; - clocks = <&gateclk 15>, <&gateclk 30>; - clock-names = "0", "1"; - status = "disabled"; - }; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - compatible = "marvell,orion-mdio"; - reg = <0x72004 0x4>; - }; - - eth0: ethernet@70000 { - compatible = "marvell,armada-370-neta"; - reg = <0x70000 0x4000>; - interrupts = <8>; - clocks = <&gateclk 4>; - status = "disabled"; - }; - - eth1: ethernet@74000 { - compatible = "marvell,armada-370-neta"; - reg = <0x74000 0x4000>; - interrupts = <10>; - clocks = <&gateclk 3>; - status = "disabled"; - }; - - i2c0: i2c@11000 { - compatible = "marvell,mv64xxx-i2c"; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <31>; - timeout-ms = <1000>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - i2c1: i2c@11100 { - compatible = "marvell,mv64xxx-i2c"; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <32>; - timeout-ms = <1000>; - clocks = <&coreclk 0>; - status = "disabled"; - }; - - rtc@10300 { - compatible = "marvell,orion-rtc"; - reg = <0x10300 0x20>; - interrupts = <50>; - }; - - mvsdio@d4000 { - compatible = "marvell,orion-sdio"; - reg = <0xd4000 0x200>; - interrupts = <54>; - clocks = <&gateclk 17>; - bus-width = <4>; - cap-sdio-irq; - cap-sd-highspeed; - cap-mmc-highspeed; - status = "disabled"; - }; - usb@50000 { compatible = "marvell,orion-ehci"; reg = <0x50000 0x500>; @@ -235,28 +213,59 @@ status = "disabled"; }; - spi0: spi@10600 { - compatible = "marvell,orion-spi"; - reg = <0x10600 0x28>; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <30>; - clocks = <&coreclk 0>; + eth0: ethernet@70000 { + compatible = "marvell,armada-370-neta"; + reg = <0x70000 0x4000>; + interrupts = <8>; + clocks = <&gateclk 4>; status = "disabled"; }; - spi1: spi@10680 { - compatible = "marvell,orion-spi"; - reg = <0x10680 0x28>; + mdio { #address-cells = <1>; #size-cells = <0>; - cell-index = <1>; - interrupts = <92>; - clocks = <&coreclk 0>; + compatible = "marvell,orion-mdio"; + reg = <0x72004 0x4>; + }; + + eth1: ethernet@74000 { + compatible = "marvell,armada-370-neta"; + reg = <0x74000 0x4000>; + interrupts = <10>; + clocks = <&gateclk 3>; status = "disabled"; }; + sata@a0000 { + compatible = "marvell,armada-370-sata"; + reg = <0xa0000 0x5000>; + interrupts = <55>; + clocks = <&gateclk 15>, <&gateclk 30>; + clock-names = "0", "1"; + status = "disabled"; + }; + + nand@d0000 { + compatible = "marvell,armada370-nand"; + reg = <0xd0000 0x54>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <113>; + clocks = <&coredivclk 0>; + status = "disabled"; + }; + + mvsdio@d4000 { + compatible = "marvell,orion-sdio"; + reg = <0xd4000 0x200>; + interrupts = <54>; + clocks = <&gateclk 17>; + bus-width = <4>; + cap-sdio-irq; + cap-sd-highspeed; + cap-mmc-highspeed; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index 7a4b82e71aaf..0d8530c98cf5 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -91,11 +91,6 @@ }; internal-regs { - system-controller@18200 { - compatible = "marvell,armada-370-xp-system-controller"; - reg = <0x18200 0x100>; - }; - L2: l2-cache { compatible = "marvell,aurora-outer-cache"; reg = <0x08000 0x1000>; @@ -103,8 +98,17 @@ wt-override; }; - interrupt-controller@20000 { - reg = <0x20a00 0x1d0>, <0x21870 0x58>; + i2c0: i2c@11000 { + reg = <0x11000 0x20>; + }; + + i2c1: i2c@11100 { + reg = <0x11100 0x20>; + }; + + system-controller@18200 { + compatible = "marvell,armada-370-xp-system-controller"; + reg = <0x18200 0x100>; }; pinctrl { @@ -163,9 +167,11 @@ interrupts = <91>; }; - timer@20300 { - compatible = "marvell,armada-370-timer"; - clocks = <&coreclk 2>; + gateclk: clock-gating-control@18220 { + compatible = "marvell,armada-370-gating-clock"; + reg = <0x18220 0x4>; + clocks = <&coreclk 0>; + #clock-cells = <1>; }; coreclk: mvebu-sar@18230 { @@ -174,11 +180,28 @@ #clock-cells = <1>; }; - gateclk: clock-gating-control@18220 { - compatible = "marvell,armada-370-gating-clock"; - reg = <0x18220 0x4>; + thermal@18300 { + compatible = "marvell,armada370-thermal"; + reg = <0x18300 0x4 + 0x18304 0x4>; + status = "okay"; + }; + + interrupt-controller@20000 { + reg = <0x20a00 0x1d0>, <0x21870 0x58>; + }; + + timer@20300 { + compatible = "marvell,armada-370-timer"; + clocks = <&coreclk 2>; + }; + + usb@50000 { + clocks = <&coreclk 0>; + }; + + usb@51000 { clocks = <&coreclk 0>; - #clock-cells = <1>; }; xor@60800 { @@ -218,29 +241,6 @@ dmacap,memset; }; }; - - i2c0: i2c@11000 { - reg = <0x11000 0x20>; - }; - - i2c1: i2c@11100 { - reg = <0x11100 0x20>; - }; - - usb@50000 { - clocks = <&coreclk 0>; - }; - - usb@51000 { - clocks = <&coreclk 0>; - }; - - thermal@18300 { - compatible = "marvell,armada370-thermal"; - reg = <0x18300 0x4 - 0x18304 0x4>; - status = "okay"; - }; }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 2298e4a910e2..274e2ad5f51c 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -175,6 +175,14 @@ spi-max-frequency = <108000000>; }; }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + }; }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts new file mode 100644 index 000000000000..ff049ee862eb --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts @@ -0,0 +1,327 @@ +/* + * Device Tree file for NETGEAR ReadyNAS 2120 + * + * Copyright (C) 2013, Arnaud EBALARD + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/dts-v1/; + +#include +#include +#include "armada-xp-mv78230.dtsi" + +/ { + model = "NETGEAR ReadyNAS 2120"; + compatible = "netgear,readynas-2120", "marvell,armadaxp-mv78230", "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0 0x00000000 0 0x80000000>; /* 2GB */ + }; + + soc { + ranges = ; + + pcie-controller { + status = "okay"; + + /* Connected to first Marvell 88SE9170 SATA controller */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + /* Connected to second Marvell 88SE9170 SATA controller */ + pcie@2,0 { + /* Port 0, Lane 1 */ + status = "okay"; + }; + + /* Connected to Fresco Logic FL1009 USB 3.0 controller */ + pcie@5,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; + }; + + internal-regs { + pinctrl { + poweroff: poweroff { + marvell,pins = "mpp42"; + marvell,function = "gpio"; + }; + + power_button_pin: power-button-pin { + marvell,pins = "mpp27"; + marvell,function = "gpio"; + }; + + reset_button_pin: reset-button-pin { + marvell,pins = "mpp41"; + marvell,function = "gpio"; + }; + + sata1_led_pin: sata1-led-pin { + marvell,pins = "mpp31"; + marvell,function = "gpio"; + }; + + sata2_led_pin: sata2-led-pin { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + + sata3_led_pin: sata3-led-pin { + marvell,pins = "mpp44"; + marvell,function = "gpio"; + }; + + sata4_led_pin: sata4-led-pin { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + + sata1_power_pin: sata1-power-pin { + marvell,pins = "mpp24"; + marvell,function = "gpio"; + }; + + sata2_power_pin: sata2-power-pin { + marvell,pins = "mpp25"; + marvell,function = "gpio"; + }; + + sata3_power_pin: sata3-power-pin { + marvell,pins = "mpp26"; + marvell,function = "gpio"; + }; + + sata4_power_pin: sata4-power-pin { + marvell,pins = "mpp28"; + marvell,function = "gpio"; + }; + + sata1_pres_pin: sata1-pres-pin { + marvell,pins = "mpp32"; + marvell,function = "gpio"; + }; + + sata2_pres_pin: sata2-pres-pin { + marvell,pins = "mpp33"; + marvell,function = "gpio"; + }; + + sata3_pres_pin: sata3-pres-pin { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + + sata4_pres_pin: sata4-pres-pin { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + + err_led_pin: err-led-pin { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + }; + + serial@12000 { + clocks = <&coreclk 0>; + status = "okay"; + }; + + mdio { + phy0: ethernet-phy@0 { /* Marvell 88E1318 */ + reg = <0>; + }; + + phy1: ethernet-phy@1 { /* Marvell 88E1318 */ + reg = <1>; + }; + }; + + ethernet@70000 { + status = "okay"; + phy = <&phy0>; + phy-mode = "rgmii-id"; + }; + + ethernet@74000 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; + + /* Front USB 2.0 port */ + usb@50000 { + status = "okay"; + }; + + i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + clock-frequency = <400000>; + status = "okay"; + + isl12057: isl12057@68 { + compatible = "isl,isl12057"; + reg = <0x68>; + }; + + /* Controller for rear fan #1 of 3 (Protechnic + * MGT4012XB-O20, 8000RPM) near eSATA port */ + g762_fan1: g762@3e { + compatible = "gmt,g762"; + reg = <0x3e>; + clocks = <&g762_clk>; /* input clock */ + fan_gear_mode = <0>; + fan_startv = <1>; + pwm_polarity = <0>; + }; + + /* Controller for rear (center) fan #2 of 3 */ + g762_fan2: g762@48 { + compatible = "gmt,g762"; + reg = <0x48>; + clocks = <&g762_clk>; /* input clock */ + fan_gear_mode = <0>; + fan_startv = <1>; + pwm_polarity = <0>; + }; + + /* Controller for rear fan #3 of 3 */ + g762_fan3: g762@49 { + compatible = "gmt,g762"; + reg = <0x49>; + clocks = <&g762_clk>; /* input clock */ + fan_gear_mode = <0>; + fan_startv = <1>; + pwm_polarity = <0>; + }; + + /* Temperature sensor */ + g751: g751@4c { + compatible = "gmt,g751"; + reg = <0x4c>; + }; + }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; /* 1.5MB */ + read-only; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; /* 128KB */ + read-only; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; /* 6MB */ + }; + + partition@800000 { + label = "minirootfs"; + reg = <0x0800000 0x400000>; /* 4MB */ + }; + + /* Last MB is for the BBT, i.e. not writable */ + partition@c00000 { + label = "ubifs"; + reg = <0x0c00000 0x7400000>; /* 116MB */ + }; + }; + }; + }; + + clocks { + g762_clk: g762-oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = <&sata1_led_pin &sata2_led_pin &err_led_pin + &sata3_led_pin &sata4_led_pin>; + pinctrl-names = "default"; + + red-sata1-led { + label = "rn2120:red:sata1"; + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red-sata2-led { + label = "rn2120:red:sata2"; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red-sata3-led { + label = "rn2120:red:sata3"; + gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red-sata4-led { + label = "rn2120:red:sata4"; + gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red-err-led { + label = "rn2120:red:err"; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&power_button_pin &reset_button_pin>; + pinctrl-names = "default"; + + power-button { + label = "Power Button"; + linux,code = ; + gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; + }; + + reset-button { + label = "Reset Button"; + linux,code = ; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-poweroff { + compatible = "gpio-poweroff"; + pinctrl-0 = <&poweroff>; + pinctrl-names = "default"; + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index 5695afcc04bf..99bcf76e6953 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -103,8 +103,7 @@ green_led { label = "green_led"; gpios = <&gpio1 21 1>; - default-state = "off"; - linux,default-trigger = "heartbeat"; + default-state = "keep"; }; }; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index 281c6447e872..b8b84a22f0f3 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -42,13 +42,14 @@ wt-override; }; - interrupt-controller@20000 { - reg = <0x20a00 0x2d0>, <0x21070 0x58>; + i2c0: i2c@11000 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11000 0x100>; }; - armada-370-xp-pmsu@22000 { - compatible = "marvell,armada-370-xp-pmsu"; - reg = <0x22100 0x430>, <0x20800 0x20>; + i2c1: i2c@11100 { + compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; + reg = <0x11100 0x100>; }; serial@12200 { @@ -68,23 +69,9 @@ status = "disabled"; }; - timer@20300 { - compatible = "marvell,armada-xp-timer"; - clocks = <&coreclk 2>, <&refclk>; - clock-names = "nbclk", "fixed"; - }; - - coreclk: mvebu-sar@18230 { - compatible = "marvell,armada-xp-core-clock"; - reg = <0x18230 0x08>; - #clock-cells = <1>; - }; - - cpuclk: clock-complex@18700 { - #clock-cells = <1>; - compatible = "marvell,armada-xp-cpu-clock"; - reg = <0x18700 0xA0>; - clocks = <&coreclk 1>; + system-controller@18200 { + compatible = "marvell,armada-370-xp-system-controller"; + reg = <0x18200 0x500>; }; gateclk: clock-gating-control@18220 { @@ -94,9 +81,39 @@ #clock-cells = <1>; }; - system-controller@18200 { - compatible = "marvell,armada-370-xp-system-controller"; - reg = <0x18200 0x500>; + coreclk: mvebu-sar@18230 { + compatible = "marvell,armada-xp-core-clock"; + reg = <0x18230 0x08>; + #clock-cells = <1>; + }; + + thermal@182b0 { + compatible = "marvell,armadaxp-thermal"; + reg = <0x182b0 0x4 + 0x184d0 0x4>; + status = "okay"; + }; + + cpuclk: clock-complex@18700 { + #clock-cells = <1>; + compatible = "marvell,armada-xp-cpu-clock"; + reg = <0x18700 0xA0>; + clocks = <&coreclk 1>; + }; + + interrupt-controller@20000 { + reg = <0x20a00 0x2d0>, <0x21070 0x58>; + }; + + timer@20300 { + compatible = "marvell,armada-xp-timer"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; + }; + + armada-370-xp-pmsu@22000 { + compatible = "marvell,armada-370-xp-pmsu"; + reg = <0x22100 0x400>, <0x20800 0x20>; }; eth2: ethernet@30000 { @@ -107,6 +124,22 @@ status = "disabled"; }; + usb@50000 { + clocks = <&gateclk 18>; + }; + + usb@51000 { + clocks = <&gateclk 19>; + }; + + usb@52000 { + compatible = "marvell,orion-ehci"; + reg = <0x52000 0x500>; + interrupts = <47>; + clocks = <&gateclk 20>; + status = "disabled"; + }; + xor@60900 { compatible = "marvell,orion-xor"; reg = <0x60900 0x100 @@ -146,39 +179,6 @@ dmacap,memset; }; }; - - i2c0: i2c@11000 { - compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11000 0x100>; - }; - - i2c1: i2c@11100 { - compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11100 0x100>; - }; - - usb@50000 { - clocks = <&gateclk 18>; - }; - - usb@51000 { - clocks = <&gateclk 19>; - }; - - usb@52000 { - compatible = "marvell,orion-ehci"; - reg = <0x52000 0x500>; - interrupts = <47>; - clocks = <&gateclk 20>; - status = "disabled"; - }; - - thermal@182b0 { - compatible = "marvell,armadaxp-thermal"; - reg = <0x182b0 0x4 - 0x184d0 0x4>; - status = "okay"; - }; }; }; diff --git a/arch/arm/boot/dts/armv7-m.dtsi b/arch/arm/boot/dts/armv7-m.dtsi new file mode 100644 index 000000000000..5a660d0faf42 --- /dev/null +++ b/arch/arm/boot/dts/armv7-m.dtsi @@ -0,0 +1,18 @@ +#include "skeleton.dtsi" + +/ { + nvic: nv-interrupt-controller { + compatible = "arm,armv7m-nvic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xe000e100 0xc00>; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&nvic>; + ranges; + }; +}; diff --git a/arch/arm/boot/dts/at91-cosino.dtsi b/arch/arm/boot/dts/at91-cosino.dtsi new file mode 100644 index 000000000000..2093c4d7cd6a --- /dev/null +++ b/arch/arm/boot/dts/at91-cosino.dtsi @@ -0,0 +1,122 @@ +/* + * at91-cosino.dtsi - Device Tree file for Cosino core module + * + * Copyright (C) 2013 - Rodolfo Giometti + * HCE Engineering + * + * Derived from at91sam9x5ek.dtsi by: + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ + +#include "at91sam9g35.dtsi" + +/ { + model = "HCE Cosino core module"; + compatible = "hce,cosino", "atmel,at91sam9x5", "atmel,at91sam9"; + + chosen { + bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait"; + }; + + memory { + reg = <0x20000000 0x8000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + mmc0: mmc@f0008000 { + pinctrl-0 = < + &pinctrl_board_mmc0 + &pinctrl_mmc0_slot0_clk_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>; + }; + }; + + dbgu: serial@fffff200 { + status = "okay"; + }; + + usart0: serial@f801c000 { + status = "okay"; + }; + + i2c0: i2c@f8010000 { + status = "okay"; + }; + + adc0: adc@f804c000 { + atmel,adc-clock-rate = <1000000>; + atmel,adc-ts-wires = <4>; + atmel,adc-ts-pressure-threshold = <10000>; + status = "okay"; + }; + + pinctrl@fffff400 { + mmc0 { + pinctrl_board_mmc0: mmc0-board { + atmel,pins = + ; /* PD15 gpio CD pin pull up and deglitch */ + }; + }; + }; + + watchdog@fffffe40 { + status = "okay"; + }; + }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "hw"; + atmel,has-pmecc; /* Enable PMECC */ + atmel,pmecc-cap = <4>; + atmel,pmecc-sector-size = <512>; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x40000>; + }; + + uboot@40000 { + label = "u-boot"; + reg = <0x40000 0x80000>; + }; + + ubootenv@c0000 { + label = "U-Boot Env"; + reg = <0xc0000 0x140000>; + }; + + kernel@200000 { + label = "kernel"; + reg = <0x200000 0x600000>; + }; + + rootfs@800000 { + label = "rootfs"; + reg = <0x800000 0x0f800000>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-cosino_mega2560.dts b/arch/arm/boot/dts/at91-cosino_mega2560.dts new file mode 100644 index 000000000000..f9415dd11f17 --- /dev/null +++ b/arch/arm/boot/dts/at91-cosino_mega2560.dts @@ -0,0 +1,84 @@ +/* + * at91-cosino_mega2560.dts - Device Tree file for Cosino board with + * Mega 2560 extension + * + * Copyright (C) 2013 - Rodolfo Giometti + * HCE Engineering + * + * Derived from at91sam9g35ek.dts by: + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ + +/dts-v1/; +#include "at91-cosino.dtsi" + +/ { + model = "HCE Cosino Mega 2560"; + compatible = "hce,cosino_mega2560", "atmel,at91sam9x5", "atmel,at91sam9"; + + ahb { + apb { + macb0: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + + adc0: adc@f804c000 { + atmel,adc-clock-rate = <1000000>; + atmel,adc-ts-wires = <4>; + atmel,adc-ts-pressure-threshold = <10000>; + status = "okay"; + }; + + + tsadcc: tsadcc@f804c000 { + status = "okay"; + }; + + rtc@fffffeb0 { + status = "okay"; + }; + + usart1: serial@f8020000 { + status = "okay"; + }; + + usart2: serial@f8024000 { + status = "okay"; + }; + + usb2: gadget@f803c000 { + atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + mmc1: mmc@f000c000 { + pinctrl-0 = < + &pinctrl_mmc1_slot0_clk_cmd_dat0 + &pinctrl_mmc1_slot0_dat1_3>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + non-removable; + }; + }; + }; + + usb0: ohci@00600000 { + status = "okay"; + num-ports = <3>; + atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW */ + &pioD 19 GPIO_ACTIVE_LOW + &pioD 20 GPIO_ACTIVE_LOW + >; + }; + + usb1: ehci@00700000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-qil_a9260.dts b/arch/arm/boot/dts/at91-qil_a9260.dts new file mode 100644 index 000000000000..5576ae8786c0 --- /dev/null +++ b/arch/arm/boot/dts/at91-qil_a9260.dts @@ -0,0 +1,185 @@ +/* + * at91-qil_a9260.dts - Device Tree file for Calao QIL A9260 board + * + * Copyright (C) 2011-2013 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ +/dts-v1/; +#include "at91sam9260.dtsi" +/ { + model = "Calao QIL A9260"; + compatible = "calao,qil-a9260", "atmel,at91sam9260", "atmel,at91sam9"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x20000000 0x4000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + usb1: gadget@fffa4000 { + atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + mmc0: mmc@fffa8000 { + pinctrl-0 = < + &pinctrl_mmc0_clk + &pinctrl_mmc0_slot0_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + }; + }; + + usart0: serial@fffb0000 { + pinctrl-0 = + <&pinctrl_usart0 + &pinctrl_usart0_rts + &pinctrl_usart0_cts + &pinctrl_usart0_dtr_dsr + &pinctrl_usart0_dcd + &pinctrl_usart0_ri>; + status = "okay"; + }; + + usart1: serial@fffb4000 { + pinctrl-0 = + <&pinctrl_usart1 + &pinctrl_usart1_rts + &pinctrl_usart1_cts>; + status = "okay"; + }; + + usart2: serial@fffb8000 { + pinctrl-0 = + <&pinctrl_usart2 + &pinctrl_usart2_rts + &pinctrl_usart2_cts>; + status = "okay"; + }; + + macb0: ethernet@fffc4000 { + phy-mode = "rmii"; + status = "okay"; + }; + + spi0: spi@fffc8000 { + status = "okay"; + cs-gpios = <&pioA 3 GPIO_ACTIVE_HIGH>; + + m41t94@0 { + compatible = "st,m41t94"; + reg = <0>; + spi-max-frequency = <1000000>; + }; + + }; + + dbgu: serial@fffff200 { + status = "okay"; + }; + + shdwc@fffffd10 { + atmel,wakeup-counter = <10>; + atmel,wakeup-rtt-timer; + }; + }; + + usb0: ohci@00500000 { + num-ports = <2>; + status = "okay"; + }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; + + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; + + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x20000>; + }; + + bareboxenv2@80000 { + label = "bareboxenv2"; + reg = <0x80000 0x20000>; + }; + + oftree@a0000 { + label = "oftree"; + reg = <0xa0000 0x20000>; + }; + + kernel@c0000 { + label = "kernel"; + reg = <0xc0000 0x400000>; + }; + + rootfs@4c0000 { + label = "rootfs"; + reg = <0x4c0000 0x7800000>; + }; + + data@7cc0000 { + label = "data"; + reg = <0x7cc0000 0x8340000>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + user_led { + label = "user_led"; + gpios = <&pioB 21 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + user_pb { + label = "user_pb"; + gpios = <&pioB 10 GPIO_ACTIVE_LOW>; + linux,code = <28>; + gpio-key,wakeup; + }; + }; + + i2c@0 { + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi index f77065506f1e..c61b16fba79b 100644 --- a/arch/arm/boot/dts/at91rm9200.dtsi +++ b/arch/arm/boot/dts/at91rm9200.dtsi @@ -191,12 +191,12 @@ AT91_PIOA 18 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA18 periph A */ }; - pinctrl_uart0_rts: uart0_rts-0 { + pinctrl_uart0_cts: uart0_cts-0 { atmel,pins = ; /* PA20 periph A */ }; - pinctrl_uart0_cts: uart0_cts-0 { + pinctrl_uart0_rts: uart0_rts-0 { atmel,pins = ; /* PA21 periph A */ }; diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts index d2d72c3b44c4..df6b0aa0e4dd 100644 --- a/arch/arm/boot/dts/at91rm9200ek.dts +++ b/arch/arm/boot/dts/at91rm9200ek.dts @@ -29,10 +29,22 @@ ahb { apb { - dbgu: serial@fffff200 { + usb1: gadget@fffb0000 { + atmel,vbus-gpio = <&pioD 4 GPIO_ACTIVE_HIGH>; + atmel,pullup-gpio = <&pioD 5 GPIO_ACTIVE_HIGH>; status = "okay"; }; + macb0: ethernet@fffbc000 { + phy-mode = "rmii"; + status = "okay"; + + phy0: ethernet-phy { + interrupt-parent = <&pioC>; + interrupts = <4 IRQ_TYPE_EDGE_BOTH>; + }; + }; + usart1: serial@fffc4000 { pinctrl-0 = <&pinctrl_uart1 @@ -44,16 +56,6 @@ status = "okay"; }; - macb0: ethernet@fffbc000 { - phy-mode = "rmii"; - status = "okay"; - }; - - usb1: gadget@fffb0000 { - atmel,vbus-gpio = <&pioD 4 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; - spi0: spi@fffe0000 { status = "okay"; cs-gpios = <&pioA 3 0>, <0>, <0>, <0>; @@ -63,12 +65,45 @@ reg = <0>; }; }; + + dbgu: serial@fffff200 { + status = "okay"; + }; }; usb0: ohci@00300000 { num-ports = <2>; status = "okay"; }; + + nor_flash@10000000 { + compatible = "cfi-flash"; + reg = <0x10000000 0x800000>; + linux,mtd-name = "physmap-flash.0"; + bank-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + + barebox@0 { + label = "barebox"; + reg = <0x00000 0x40000>; + }; + + bareboxenv@40000 { + label = "bareboxenv"; + reg = <0x40000 0x10000>; + }; + + kernel@50000 { + label = "kernel"; + reg = <0x50000 0x300000>; + }; + + root@350000 { + label = "root"; + reg = <0x350000 0x4B0000>; + }; + }; }; leds { diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index d5bd65f74602..c8fa9b9f07e3 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -30,6 +30,7 @@ i2c0 = &i2c0; ssc0 = &ssc0; ssc1 = &ssc1; + pwm0 = &pwm0; }; cpus { #address-cells = <0>; @@ -366,6 +367,34 @@ }; }; + fb { + pinctrl_fb: fb-0 { + atmel,pins = + ; /* PC27 periph A */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -547,6 +576,23 @@ pinctrl-0 = <&pinctrl_spi1>; status = "disabled"; }; + + pwm0: pwm@fffb8000 { + compatible = "atmel,at91sam9rl-pwm"; + reg = <0xfffb8000 0x300>; + interrupts = <20 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + status = "disabled"; + }; + }; + + fb0: fb@0x00700000 { + compatible = "atmel,at91sam9263-lcdc"; + reg = <0x00700000 0x1000>; + interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fb>; + status = "disabled"; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 70f835b55c0b..15009c9f2293 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -95,6 +95,36 @@ }; }; + fb0: fb@0x00700000 { + display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + atmel,lcdcon-backlight; + atmel,dmacon = <0x1>; + atmel,lcdcon2 = <0x80008002>; + atmel,guard-time = <1>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <4965000>; + hactive = <240>; + vactive = <320>; + hback-porch = <1>; + hfront-porch = <33>; + vback-porch = <1>; + vfront-porch = <0>; + hsync-len = <5>; + vsync-len = <1>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; + }; + nand0: nand@40000000 { nand-bus-width = <8>; nand-ecc-mode = "soft"; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index c3e514837074..ef0857cb171c 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -37,6 +37,7 @@ i2c1 = &i2c1; ssc0 = &ssc0; ssc1 = &ssc1; + pwm0 = &pwm0; }; cpus { #address-cells = <0>; @@ -143,6 +144,22 @@ }; }; + i2c0 { + pinctrl_i2c0: i2c0-0 { + atmel,pins = + ; /* PA20 periph A TWD0 */ + }; + }; + + i2c1 { + pinctrl_i2c1: i2c1-0 { + atmel,pins = + ; /* PB10 periph A TWD1 */ + }; + }; + usart0 { pinctrl_usart0: usart0-0 { atmel,pins = @@ -425,6 +442,42 @@ }; }; + fb { + pinctrl_fb: fb-0 { + atmel,pins = + ; /* PE30 periph A */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -542,6 +595,8 @@ compatible = "atmel,at91sam9g10-i2c"; reg = <0xfff84000 0x100>; interrupts = <12 IRQ_TYPE_LEVEL_HIGH 6>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -551,6 +606,8 @@ compatible = "atmel,at91sam9g10-i2c"; reg = <0xfff88000 0x100>; interrupts = <13 IRQ_TYPE_LEVEL_HIGH 6>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -614,10 +671,19 @@ }; }; + pwm0: pwm@fffb8000 { + compatible = "atmel,at91sam9rl-pwm"; + reg = <0xfffb8000 0x300>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + status = "disabled"; + }; + mmc0: mmc@fff80000 { compatible = "atmel,hsmci"; reg = <0xfff80000 0x600>; interrupts = <11 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; dmas = <&dma 1 AT91_DMA_CFG_PER_ID(0)>; dma-names = "rxtx"; #address-cells = <1>; @@ -629,6 +695,7 @@ compatible = "atmel,hsmci"; reg = <0xfffd0000 0x600>; interrupts = <29 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; dmas = <&dma 1 AT91_DMA_CFG_PER_ID(13)>; dma-names = "rxtx"; #address-cells = <1>; @@ -727,6 +794,15 @@ }; }; + fb0: fb@0x00500000 { + compatible = "atmel,at91sam9g45-lcdc"; + reg = <0x00500000 0x1000>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fb>; + status = "disabled"; + }; + nand0: nand@40000000 { compatible = "atmel,at91rm9200-nand"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index a4b00e5c61c0..7ff665a8c708 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -105,6 +105,14 @@ AT91_PIOD 29 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>; /* PD29 gpio WP pin pull up */ }; }; + + pwm0 { + pinctrl_pwm_leds: pwm-led { + atmel,pins = + ; /* PD31 periph B */ + }; + }; }; spi0: spi@fffa4000{ @@ -121,6 +129,42 @@ atmel,vbus-gpio = <&pioB 19 GPIO_ACTIVE_HIGH>; status = "okay"; }; + + pwm0: pwm@fffb8000 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm_leds>; + }; + }; + + fb0: fb@0x00500000 { + display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <32>; + atmel,lcdcon-backlight; + atmel,dmacon = <0x1>; + atmel,lcdcon2 = <0x80008002>; + atmel,guard-time = <9>; + atmel,lcd-wiring-mode = "RGB"; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <9000000>; + hactive = <480>; + vactive = <272>; + hback-porch = <1>; + hfront-porch = <1>; + vback-porch = <40>; + vfront-porch = <1>; + hsync-len = <45>; + vsync-len = <1>; + }; + }; + }; }; nand0: nand@40000000 { @@ -165,16 +209,22 @@ gpios = <&pioD 30 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; + }; + + pwmleds { + compatible = "pwm-leds"; d6 { label = "d6"; - gpios = <&pioD 0 GPIO_ACTIVE_LOW>; + pwms = <&pwm0 3 5000 0>; + max-brightness = <255>; linux,default-trigger = "nand-disk"; }; d7 { label = "d7"; - gpios = <&pioD 31 GPIO_ACTIVE_LOW>; + pwms = <&pwm0 1 5000 0>; + max-brightness = <255>; linux,default-trigger = "mmc0"; }; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 6224f9fe2f2b..7248270a3ea6 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -33,6 +33,7 @@ i2c0 = &i2c0; i2c1 = &i2c1; ssc0 = &ssc0; + pwm0 = &pwm0; }; cpus { #address-cells = <0>; @@ -542,6 +543,14 @@ reg = <0xfffffe40 0x10>; status = "disabled"; }; + + pwm0: pwm@f8034000 { + compatible = "atmel,at91sam9rl-pwm"; + reg = <0xf8034000 0x300>; + interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + status = "disabled"; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 40267a116c3c..6e5e9cfc3c49 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -35,6 +35,7 @@ i2c1 = &i2c1; i2c2 = &i2c2; ssc0 = &ssc0; + pwm0 = &pwm0; }; cpus { #address-cells = <0>; @@ -762,6 +763,14 @@ interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; status = "disabled"; }; + + pwm0: pwm@f8034000 { + compatible = "atmel,at91sam9rl-pwm"; + reg = <0xf8034000 0x300>; + interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + status = "disabled"; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index 978bab4991df..f8674bcc4489 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi @@ -27,6 +27,15 @@ timebase-frequency = <0>; bus-frequency = <0>; clock-frequency = <0>; + clocks = <&clks 12>; + operating-points = < + /* kHz uV */ + 200000 1025000 + 400000 1025000 + 600000 1050000 + 800000 1100000 + >; + clock-latency = <150000>; }; }; @@ -69,6 +78,7 @@ cphifbg@88030000 { compatible = "sirf,prima2-cphifbg"; reg = <0x88030000 0x1000>; + clocks = <&clks 42>; }; }; @@ -546,6 +556,12 @@ sirf,function = "usp1"; }; }; + usp1_uart_nostreamctrl_pins_a: usp1@1 { + usp1 { + sirf,pins = "usp1_uart_nostreamctrl_grp"; + sirf,function = "usp1_uart_nostreamctrl"; + }; + }; usb0_upli_drvbus_pins_a: usb0_upli_drvbus@0 { usb0_upli_drvbus { sirf,pins = "usb0_upli_drvbusgrp"; @@ -636,6 +652,7 @@ reg = <0x56100000 0x100000>; interrupts = <38>; status = "disabled"; + bus-width = <4>; clocks = <&clks 36>; }; @@ -645,6 +662,7 @@ reg = <0x56200000 0x100000>; interrupts = <23>; status = "disabled"; + bus-width = <4>; clocks = <&clks 37>; }; @@ -654,6 +672,7 @@ reg = <0x56300000 0x100000>; interrupts = <23>; status = "disabled"; + bus-width = <4>; clocks = <&clks 37>; }; @@ -663,6 +682,7 @@ reg = <0x56500000 0x100000>; interrupts = <39>; status = "disabled"; + bus-width = <4>; clocks = <&clks 38>; }; @@ -697,6 +717,12 @@ interrupts = <52 53 54>; }; + minigpsrtc@2000 { + compatible = "sirf,prima2-minigpsrtc"; + reg = <0x2000 0x1000>; + interrupts = <54>; + }; + pwrc@3000 { compatible = "sirf,prima2-pwrc"; reg = <0x3000 0x1000>; diff --git a/arch/arm/boot/dts/bcm11351.dtsi b/arch/arm/boot/dts/bcm11351.dtsi index b0c0610d1395..dd8e878741c0 100644 --- a/arch/arm/boot/dts/bcm11351.dtsi +++ b/arch/arm/boot/dts/bcm11351.dtsi @@ -142,4 +142,8 @@ status = "disabled"; }; + pinctrl@35004800 { + compatible = "brcm,capri-pinctrl"; + reg = <0x35004800 0x430>; + }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts index 6e9deb786a7d..2a3b1c1313a0 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts @@ -23,10 +23,15 @@ &gpio { pinctrl-names = "default"; - pinctrl-0 = <&alt0 &alt3>; + pinctrl-0 = <&gpioout &alt0 &alt3>; + + gpioout: gpioout { + brcm,pins = <6>; + brcm,function = <1>; /* GPIO out */ + }; alt0: alt0 { - brcm,pins = <0 1 2 3 4 5 6 7 8 9 10 11 14 15 40 45>; + brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; brcm,function = <4>; /* alt0 */ }; diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi index aa537ed13f0a..b021c96d3ba1 100644 --- a/arch/arm/boot/dts/bcm2835.dtsi +++ b/arch/arm/boot/dts/bcm2835.dtsi @@ -107,6 +107,12 @@ clocks = <&clk_mmc>; status = "disabled"; }; + + usb { + compatible = "brcm,bcm2835-usb"; + reg = <0x7e980000 0x10000>; + interrupts = <1 9>; + }; }; clocks { diff --git a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts new file mode 100644 index 000000000000..c72bfd468d10 --- /dev/null +++ b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts @@ -0,0 +1,29 @@ +/* + * Device Tree file for Sony NSZ-GS7 + * + * Sebastian Hesselbarth + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; + +#include "berlin2.dtsi" + +/ { + model = "Sony NSZ-GS7"; + compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; /* 1 GB */ + }; +}; + +&uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi new file mode 100644 index 000000000000..56a1af2f1052 --- /dev/null +++ b/arch/arm/boot/dts/berlin2.dtsi @@ -0,0 +1,227 @@ +/* + * Device Tree Include file for Marvell Armada 1500 (Berlin BG2) SoC + * + * Sebastian Hesselbarth + * + * based on GPL'ed 2.6 kernel sources + * (c) Marvell International Ltd. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include "skeleton.dtsi" +#include + +/ { + model = "Marvell Armada 1500 (BG2) SoC"; + compatible = "marvell,berlin2", "marvell,berlin"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "marvell,pj4b"; + device_type = "cpu"; + next-level-cache = <&l2>; + reg = <0>; + }; + + cpu@1 { + compatible = "marvell,pj4b"; + device_type = "cpu"; + next-level-cache = <&l2>; + reg = <1>; + }; + }; + + clocks { + smclk: sysmgr-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + cfgclk: cfg-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <400000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + ranges = <0 0xf7000000 0x1000000>; + + l2: l2-cache-controller@ac0000 { + compatible = "marvell,tauros3-cache", "arm,pl310-cache"; + reg = <0xac0000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + gic: interrupt-controller@ad1000 { + compatible = "arm,cortex-a9-gic"; + reg = <0xad1000 0x1000>, <0xad0100 0x0100>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + local-timer@ad0600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xad0600 0x20>; + interrupts = ; + clocks = <&sysclk>; + }; + + apb@e80000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0 0xe80000 0x10000>; + interrupt-parent = <&aic>; + + timer0: timer@2c00 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c00 0x14>; + interrupts = <8>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "okay"; + }; + + timer1: timer@2c14 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c14 0x14>; + interrupts = <9>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "okay"; + }; + + timer2: timer@2c28 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c28 0x14>; + interrupts = <10>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer3: timer@2c3c { + compatible = "snps,dw-apb-timer"; + reg = <0x2c3c 0x14>; + interrupts = <11>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer4: timer@2c50 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c50 0x14>; + interrupts = <12>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer5: timer@2c64 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c64 0x14>; + interrupts = <13>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer6: timer@2c78 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c78 0x14>; + interrupts = <14>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer7: timer@2c8c { + compatible = "snps,dw-apb-timer"; + reg = <0x2c8c 0x14>; + interrupts = <15>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + aic: interrupt-controller@3000 { + compatible = "snps,dw-apb-ictl"; + reg = <0x3000 0xc00>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic>; + interrupts = ; + }; + }; + + apb@fc0000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0 0xfc0000 0x10000>; + interrupt-parent = <&sic>; + + uart0: serial@9000 { + compatible = "snps,dw-apb-uart"; + reg = <0x9000 0x100>; + reg-shift = <2>; + reg-io-width = <1>; + interrupts = <8>; + clocks = <&smclk>; + status = "disabled"; + }; + + uart1: serial@a000 { + compatible = "snps,dw-apb-uart"; + reg = <0xa000 0x100>; + reg-shift = <2>; + reg-io-width = <1>; + interrupts = <9>; + clocks = <&smclk>; + status = "disabled"; + }; + + uart2: serial@b000 { + compatible = "snps,dw-apb-uart"; + reg = <0xb000 0x100>; + reg-shift = <2>; + reg-io-width = <1>; + interrupts = <10>; + clocks = <&smclk>; + status = "disabled"; + }; + + sic: interrupt-controller@e000 { + compatible = "snps,dw-apb-ictl"; + reg = <0xe000 0x400>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic>; + interrupts = ; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts new file mode 100644 index 000000000000..bcd81ffc495d --- /dev/null +++ b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts @@ -0,0 +1,29 @@ +/* + * Device Tree file for Google Chromecast + * + * Sebastian Hesselbarth + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; + +#include "berlin2cd.dtsi" + +/ { + model = "Google Chromecast"; + compatible = "google,chromecast", "marvell,berlin2cd", "marvell,berlin"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512 MB */ + }; +}; + +&uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi new file mode 100644 index 000000000000..094968c27533 --- /dev/null +++ b/arch/arm/boot/dts/berlin2cd.dtsi @@ -0,0 +1,210 @@ +/* + * Device Tree Include file for Marvell Armada 1500-mini (Berlin BG2CD) SoC + * + * Sebastian Hesselbarth + * + * based on GPL'ed 2.6 kernel sources + * (c) Marvell International Ltd. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include "skeleton.dtsi" +#include + +/ { + model = "Marvell Armada 1500-mini (BG2CD) SoC"; + compatible = "marvell,berlin2cd", "marvell,berlin"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + next-level-cache = <&l2>; + reg = <0>; + }; + }; + + clocks { + smclk: sysmgr-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + cfgclk: cfg-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <75000000>; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <300000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + ranges = <0 0xf7000000 0x1000000>; + + l2: l2-cache-controller@ac0000 { + compatible = "arm,pl310-cache"; + reg = <0xac0000 0x1000>; + cache-unified; + cache-level = <2>; + }; + + gic: interrupt-controller@ad1000 { + compatible = "arm,cortex-a9-gic"; + reg = <0xad1000 0x1000>, <0xad0100 0x0100>; + interrupt-controller; + #interrupt-cells = <3>; + }; + + local-timer@ad0600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xad0600 0x20>; + interrupts = ; + clocks = <&sysclk>; + }; + + apb@e80000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0 0xe80000 0x10000>; + interrupt-parent = <&aic>; + + timer0: timer@2c00 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c00 0x14>; + interrupts = <8>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "okay"; + }; + + timer1: timer@2c14 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c14 0x14>; + interrupts = <9>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "okay"; + }; + + timer2: timer@2c28 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c28 0x14>; + interrupts = <10>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer3: timer@2c3c { + compatible = "snps,dw-apb-timer"; + reg = <0x2c3c 0x14>; + interrupts = <11>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer4: timer@2c50 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c50 0x14>; + interrupts = <12>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer5: timer@2c64 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c64 0x14>; + interrupts = <13>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer6: timer@2c78 { + compatible = "snps,dw-apb-timer"; + reg = <0x2c78 0x14>; + interrupts = <14>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + timer7: timer@2c8c { + compatible = "snps,dw-apb-timer"; + reg = <0x2c8c 0x14>; + interrupts = <15>; + clocks = <&cfgclk>; + clock-names = "timer"; + status = "disabled"; + }; + + aic: interrupt-controller@3000 { + compatible = "snps,dw-apb-ictl"; + reg = <0x3000 0xc00>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic>; + interrupts = ; + }; + }; + + apb@fc0000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0 0xfc0000 0x10000>; + interrupt-parent = <&sic>; + + uart0: serial@9000 { + compatible = "snps,dw-apb-uart"; + reg = <0x9000 0x100>; + reg-shift = <2>; + reg-io-width = <1>; + interrupts = <8>; + clocks = <&smclk>; + status = "disabled"; + }; + + uart1: serial@a000 { + compatible = "snps,dw-apb-uart"; + reg = <0xa000 0x100>; + reg-shift = <2>; + reg-io-width = <1>; + interrupts = <9>; + clocks = <&smclk>; + status = "disabled"; + }; + + sic: interrupt-controller@e000 { + compatible = "snps,dw-apb-ictl"; + reg = <0xe000 0x400>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&gic>; + interrupts = ; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts index 588ce58a2959..1e11e5a5f723 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -101,6 +101,9 @@ pinctrl-names = "default"; pinctrl-0 = <&mii_pins>; }; + gpio: gpio@1e26000 { + status = "okay"; + }; }; nand_cs3@62000000 { status = "okay"; diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index 8d17346f9702..b695548dbb4e 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi @@ -8,6 +8,7 @@ * option) any later version. */ #include "skeleton.dtsi" +#include / { arm { @@ -256,6 +257,19 @@ 36 >; }; + gpio: gpio@1e26000 { + compatible = "ti,dm6441-gpio"; + gpio-controller; + reg = <0x226000 0x1000>; + interrupts = <42 IRQ_TYPE_EDGE_BOTH + 43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH + 45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH + 47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH + 49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + status = "disabled"; + }; }; nand_cs3@62000000 { compatible = "ti,davinci-nand"; diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts index 8349a248ecea..7a70f4ca502a 100644 --- a/arch/arm/boot/dts/dove-cubox.dts +++ b/arch/arm/boot/dts/dove-cubox.dts @@ -23,7 +23,7 @@ power { label = "Power"; gpios = <&gpio0 18 1>; - linux,default-trigger = "default-on"; + default-state = "keep"; }; }; diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 113a8bc7bee7..2b76524f4aa7 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi @@ -107,51 +107,29 @@ 0xffffe000 MBUS_ID(0x03, 0x01) 0 0x0000800 /* CESA SRAM 2k */ 0xfffff000 MBUS_ID(0x0d, 0x00) 0 0x0000800>; /* PMU SRAM 2k */ - mbusc: mbus-ctrl@20000 { - compatible = "marvell,mbus-controller"; - reg = <0x20000 0x80>, <0x800100 0x8>; - }; - - timer: timer@20300 { - compatible = "marvell,orion-timer"; - reg = <0x20300 0x20>; - interrupt-parent = <&bridge_intc>; - interrupts = <1>, <2>; + spi0: spi-ctrl@10600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <6>; + reg = <0x10600 0x28>; clocks = <&core_clk 0>; + pinctrl-0 = <&pmx_spi0>; + pinctrl-names = "default"; + status = "disabled"; }; - intc: main-interrupt-ctrl@20200 { - compatible = "marvell,orion-intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x20200 0x10>, <0x20210 0x10>; - }; - - bridge_intc: bridge-interrupt-ctrl@20110 { - compatible = "marvell,orion-bridge-intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x20110 0x8>; - interrupts = <0>; - marvell,#interrupts = <5>; - }; - - core_clk: core-clocks@d0214 { - compatible = "marvell,dove-core-clock"; - reg = <0xd0214 0x4>; - #clock-cells = <1>; - }; - - gate_clk: clock-gating-ctrl@d0038 { - compatible = "marvell,dove-gating-clock"; - reg = <0xd0038 0x4>; + i2c0: i2c-ctrl@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <11>; + clock-frequency = <400000>; + timeout-ms = <1000>; clocks = <&core_clk 0>; - #clock-cells = <1>; - }; - - thermal: thermal-diode@d001c { - compatible = "marvell,dove-thermal"; - reg = <0xd001c 0x0c>, <0xd005c 0x08>; + status = "disabled"; }; uart0: serial@12000 { @@ -192,34 +170,222 @@ status = "disabled"; }; - gpio0: gpio-ctrl@d0400 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0xd0400 0x20>; - ngpios = <32>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <12>, <13>, <14>, <60>; + spi1: spi-ctrl@14600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + interrupts = <5>; + reg = <0x14600 0x28>; + clocks = <&core_clk 0>; + status = "disabled"; }; - gpio1: gpio-ctrl@d0420 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0xd0420 0x20>; - ngpios = <32>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = <61>; + mbusc: mbus-ctrl@20000 { + compatible = "marvell,mbus-controller"; + reg = <0x20000 0x80>, <0x800100 0x8>; }; - gpio2: gpio-ctrl@e8400 { - compatible = "marvell,orion-gpio"; - #gpio-cells = <2>; - gpio-controller; - reg = <0xe8400 0x0c>; - ngpios = <8>; + bridge_intc: bridge-interrupt-ctrl@20110 { + compatible = "marvell,orion-bridge-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x20110 0x8>; + interrupts = <0>; + marvell,#interrupts = <5>; + }; + + intc: main-interrupt-ctrl@20200 { + compatible = "marvell,orion-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x20200 0x10>, <0x20210 0x10>; + }; + + timer: timer@20300 { + compatible = "marvell,orion-timer"; + reg = <0x20300 0x20>; + interrupt-parent = <&bridge_intc>; + interrupts = <1>, <2>; + clocks = <&core_clk 0>; + }; + + crypto: crypto-engine@30000 { + compatible = "marvell,orion-crypto"; + reg = <0x30000 0x10000>, + <0xffffe000 0x800>; + reg-names = "regs", "sram"; + interrupts = <31>; + clocks = <&gate_clk 15>; + status = "okay"; + }; + + ehci0: usb-host@50000 { + compatible = "marvell,orion-ehci"; + reg = <0x50000 0x1000>; + interrupts = <24>; + clocks = <&gate_clk 0>; + status = "okay"; + }; + + ehci1: usb-host@51000 { + compatible = "marvell,orion-ehci"; + reg = <0x51000 0x1000>; + interrupts = <25>; + clocks = <&gate_clk 1>; + status = "okay"; + }; + + xor0: dma-engine@60800 { + compatible = "marvell,orion-xor"; + reg = <0x60800 0x100 + 0x60a00 0x100>; + clocks = <&gate_clk 23>; + status = "okay"; + + channel0 { + interrupts = <39>; + dmacap,memcpy; + dmacap,xor; + }; + + channel1 { + interrupts = <40>; + dmacap,memcpy; + dmacap,xor; + }; + }; + + xor1: dma-engine@60900 { + compatible = "marvell,orion-xor"; + reg = <0x60900 0x100 + 0x60b00 0x100>; + clocks = <&gate_clk 24>; + status = "okay"; + + channel0 { + interrupts = <42>; + dmacap,memcpy; + dmacap,xor; + }; + + channel1 { + interrupts = <43>; + dmacap,memcpy; + dmacap,xor; + }; + }; + + sdio1: sdio-host@90000 { + compatible = "marvell,dove-sdhci"; + reg = <0x90000 0x100>; + interrupts = <36>, <38>; + clocks = <&gate_clk 9>; + pinctrl-0 = <&pmx_sdio1>; + pinctrl-names = "default"; + status = "disabled"; + }; + + eth: ethernet-ctrl@72000 { + compatible = "marvell,orion-eth"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72000 0x4000>; + clocks = <&gate_clk 2>; + marvell,tx-checksum-limit = <1600>; + status = "disabled"; + + ethernet-port@0 { + compatible = "marvell,orion-eth-port"; + reg = <0>; + interrupts = <29>; + /* overwrite MAC address in bootloader */ + local-mac-address = [00 00 00 00 00 00]; + phy-handle = <ðphy>; + }; + }; + + mdio: mdio-bus@72004 { + compatible = "marvell,orion-mdio"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72004 0x84>; + interrupts = <30>; + clocks = <&gate_clk 2>; + status = "disabled"; + + ethphy: ethernet-phy { + /* set phy address in board file */ + }; + }; + + sdio0: sdio-host@92000 { + compatible = "marvell,dove-sdhci"; + reg = <0x92000 0x100>; + interrupts = <35>, <37>; + clocks = <&gate_clk 8>; + pinctrl-0 = <&pmx_sdio0>; + pinctrl-names = "default"; + status = "disabled"; + }; + + sata0: sata-host@a0000 { + compatible = "marvell,orion-sata"; + reg = <0xa0000 0x2400>; + interrupts = <62>; + clocks = <&gate_clk 3>; + phys = <&sata_phy0>; + phy-names = "port0"; + nr-ports = <1>; + status = "disabled"; + }; + + sata_phy0: sata-phy@a2000 { + compatible = "marvell,mvebu-sata-phy"; + reg = <0xa2000 0x0334>; + clocks = <&gate_clk 3>; + clock-names = "sata"; + #phy-cells = <0>; + status = "ok"; + }; + + audio0: audio-controller@b0000 { + compatible = "marvell,dove-audio"; + reg = <0xb0000 0x2210>; + interrupts = <19>, <20>; + clocks = <&gate_clk 12>; + clock-names = "internal"; + status = "disabled"; + }; + + audio1: audio-controller@b4000 { + compatible = "marvell,dove-audio"; + reg = <0xb4000 0x2210>; + interrupts = <21>, <22>; + clocks = <&gate_clk 13>; + clock-names = "internal"; + status = "disabled"; + }; + + thermal: thermal-diode@d001c { + compatible = "marvell,dove-thermal"; + reg = <0xd001c 0x0c>, <0xd005c 0x08>; + }; + + gate_clk: clock-gating-ctrl@d0038 { + compatible = "marvell,dove-gating-clock"; + reg = <0xd0038 0x4>; + clocks = <&core_clk 0>; + #clock-cells = <1>; + }; + + pmu_intc: pmu-interrupt-ctrl@d0050 { + compatible = "marvell,dove-pmu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0xd0050 0x8>; + interrupts = <33>; + marvell,#interrupts = <7>; }; pinctrl: pin-ctrl@d0200 { @@ -413,193 +579,47 @@ }; }; - spi0: spi-ctrl@10600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <6>; - reg = <0x10600 0x28>; - clocks = <&core_clk 0>; - pinctrl-0 = <&pmx_spi0>; - pinctrl-names = "default"; - status = "disabled"; + core_clk: core-clocks@d0214 { + compatible = "marvell,dove-core-clock"; + reg = <0xd0214 0x4>; + #clock-cells = <1>; }; - spi1: spi-ctrl@14600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - interrupts = <5>; - reg = <0x14600 0x28>; - clocks = <&core_clk 0>; - status = "disabled"; + gpio0: gpio-ctrl@d0400 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0xd0400 0x20>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <12>, <13>, <14>, <60>; }; - i2c0: i2c-ctrl@11000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <11>; - clock-frequency = <400000>; - timeout-ms = <1000>; - clocks = <&core_clk 0>; - status = "disabled"; - }; - - ehci0: usb-host@50000 { - compatible = "marvell,orion-ehci"; - reg = <0x50000 0x1000>; - interrupts = <24>; - clocks = <&gate_clk 0>; - status = "okay"; - }; - - ehci1: usb-host@51000 { - compatible = "marvell,orion-ehci"; - reg = <0x51000 0x1000>; - interrupts = <25>; - clocks = <&gate_clk 1>; - status = "okay"; - }; - - sdio0: sdio-host@92000 { - compatible = "marvell,dove-sdhci"; - reg = <0x92000 0x100>; - interrupts = <35>, <37>; - clocks = <&gate_clk 8>; - pinctrl-0 = <&pmx_sdio0>; - pinctrl-names = "default"; - status = "disabled"; - }; - - sdio1: sdio-host@90000 { - compatible = "marvell,dove-sdhci"; - reg = <0x90000 0x100>; - interrupts = <36>, <38>; - clocks = <&gate_clk 9>; - pinctrl-0 = <&pmx_sdio1>; - pinctrl-names = "default"; - status = "disabled"; - }; - - sata0: sata-host@a0000 { - compatible = "marvell,orion-sata"; - reg = <0xa0000 0x2400>; - interrupts = <62>; - clocks = <&gate_clk 3>; - nr-ports = <1>; - status = "disabled"; + gpio1: gpio-ctrl@d0420 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0xd0420 0x20>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <61>; }; rtc: real-time-clock@d8500 { compatible = "marvell,orion-rtc"; reg = <0xd8500 0x20>; + interrupt-parent = <&pmu_intc>; + interrupts = <5>; }; - crypto: crypto-engine@30000 { - compatible = "marvell,orion-crypto"; - reg = <0x30000 0x10000>, - <0xffffe000 0x800>; - reg-names = "regs", "sram"; - interrupts = <31>; - clocks = <&gate_clk 15>; - status = "okay"; - }; - - xor0: dma-engine@60800 { - compatible = "marvell,orion-xor"; - reg = <0x60800 0x100 - 0x60a00 0x100>; - clocks = <&gate_clk 23>; - status = "okay"; - - channel0 { - interrupts = <39>; - dmacap,memcpy; - dmacap,xor; - }; - - channel1 { - interrupts = <40>; - dmacap,memcpy; - dmacap,xor; - }; - }; - - xor1: dma-engine@60900 { - compatible = "marvell,orion-xor"; - reg = <0x60900 0x100 - 0x60b00 0x100>; - clocks = <&gate_clk 24>; - status = "okay"; - - channel0 { - interrupts = <42>; - dmacap,memcpy; - dmacap,xor; - }; - - channel1 { - interrupts = <43>; - dmacap,memcpy; - dmacap,xor; - }; - }; - - mdio: mdio-bus@72004 { - compatible = "marvell,orion-mdio"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x72004 0x84>; - interrupts = <30>; - clocks = <&gate_clk 2>; - status = "disabled"; - - ethphy: ethernet-phy { - device-type = "ethernet-phy"; - /* set phy address in board file */ - }; - }; - - eth: ethernet-ctrl@72000 { - compatible = "marvell,orion-eth"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x72000 0x4000>; - clocks = <&gate_clk 2>; - marvell,tx-checksum-limit = <1600>; - status = "disabled"; - - ethernet-port@0 { - device_type = "network"; - compatible = "marvell,orion-eth-port"; - reg = <0>; - interrupts = <29>; - /* overwrite MAC address in bootloader */ - local-mac-address = [00 00 00 00 00 00]; - phy-handle = <ðphy>; - }; - }; - - audio0: audio-controller@b0000 { - compatible = "marvell,dove-audio"; - reg = <0xb0000 0x2210>; - interrupts = <19>, <20>; - clocks = <&gate_clk 12>; - clock-names = "internal"; - status = "disabled"; - }; - - audio1: audio-controller@b4000 { - compatible = "marvell,dove-audio"; - reg = <0xb4000 0x2210>; - interrupts = <21>, <22>; - clocks = <&gate_clk 13>; - clock-names = "internal"; - status = "disabled"; + gpio2: gpio-ctrl@e8400 { + compatible = "marvell,orion-gpio"; + #gpio-cells = <2>; + gpio-controller; + reg = <0xe8400 0x0c>; + ngpios = <8>; }; }; }; diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts new file mode 100644 index 000000000000..aa5c0f6363d6 --- /dev/null +++ b/arch/arm/boot/dts/efm32gg-dk3750.dts @@ -0,0 +1,86 @@ +/* + * Device tree for EFM32GG-DK3750 development board. + * + * Documentation available from + * http://www.silabs.com/Support%20Documents/TechnicalDocs/efm32gg-dk3750-ug.pdf + */ + +/dts-v1/; +#include "efm32gg.dtsi" + +/ { + model = "Energy Micro Giant Gecko Development Kit"; + compatible = "efm32,dk3750"; + + chosen { + bootargs = "console=ttyefm4,115200 init=/linuxrc ignore_loglevel ihash_entries=64 dhash_entries=64 earlyprintk uclinux.physaddr=0x8c400000 root=/dev/mtdblock0"; + }; + + memory { + reg = <0x88000000 0x400000>; + }; + + soc { + adc@40002000 { + status = "ok"; + }; + + i2c@4000a000 { + location = <3>; + status = "ok"; + + temp@48 { + compatible = "st,stds75"; + reg = <0x48>; + }; + + eeprom@50 { + compatible = "microchip,24c02"; + reg = <0x50>; + pagesize = <16>; + }; + }; + + spi0: spi@4000c000 { /* USART0 */ + cs-gpios = <&gpio 68 1>; // E4 + location = <1>; + status = "ok"; + + microsd@0 { + compatible = "mmc-spi-slot"; + spi-max-frequency = <100000>; + voltage-ranges = <3200 3400>; + broken-cd; + reg = <0>; + }; + }; + + spi1: spi@4000c400 { /* USART1 */ + cs-gpios = <&gpio 51 1>; // D3 + location = <1>; + status = "ok"; + + ks8851@0 { + compatible = "ks8851"; + spi-max-frequency = <6000000>; + reg = <0>; + interrupt-parent = <&boardfpga>; + interrupts = <4>; + }; + }; + + uart4: uart@4000e400 { /* UART1 */ + location = <2>; + status = "ok"; + }; + + boardfpga: boardfpga { + compatible = "efm32board"; + reg = <0x80000000 0x400>; + irq-gpios = <&gpio 64 1>; + interrupt-controller; + #interrupt-cells = <1>; + status = "ok"; + }; + }; +}; diff --git a/arch/arm/boot/dts/efm32gg.dtsi b/arch/arm/boot/dts/efm32gg.dtsi new file mode 100644 index 000000000000..a342ab0e6e4f --- /dev/null +++ b/arch/arm/boot/dts/efm32gg.dtsi @@ -0,0 +1,172 @@ +/* + * Device tree for Energy Micro EFM32 Giant Gecko SoC. + * + * Documentation available from + * http://www.silabs.com/Support%20Documents/TechnicalDocs/EFM32GG-RM.pdf + */ +#include "armv7-m.dtsi" +#include "dt-bindings/clock/efm32-cmu.h" + +/ { + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &spi2; + }; + + soc { + adc: adc@40002000 { + compatible = "efm32,adc"; + reg = <0x40002000 0x400>; + interrupts = <7>; + clocks = <&cmu clk_HFPERCLKADC0>; + status = "disabled"; + }; + + gpio: gpio@40006000 { + compatible = "efm32,gpio"; + reg = <0x40006000 0x1000>; + interrupts = <1 11>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <1>; + clocks = <&cmu clk_HFPERCLKGPIO>; + status = "ok"; + }; + + i2c0: i2c@4000a000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "efm32,i2c"; + reg = <0x4000a000 0x400>; + interrupts = <9>; + clocks = <&cmu clk_HFPERCLKI2C0>; + clock-frequency = <100000>; + status = "disabled"; + }; + + i2c1: i2c@4000a400 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "efm32,i2c"; + reg = <0x4000a400 0x400>; + interrupts = <10>; + clocks = <&cmu clk_HFPERCLKI2C1>; + clock-frequency = <100000>; + status = "disabled"; + }; + + spi0: spi@4000c000 { /* USART0 */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "efm32,spi"; + reg = <0x4000c000 0x400>; + interrupts = <3 4>; + clocks = <&cmu clk_HFPERCLKUSART0>; + status = "disabled"; + }; + + spi1: spi@4000c400 { /* USART1 */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "efm32,spi"; + reg = <0x4000c400 0x400>; + interrupts = <15 16>; + clocks = <&cmu clk_HFPERCLKUSART1>; + status = "disabled"; + }; + + spi2: spi@40x4000c800 { /* USART2 */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "efm32,spi"; + reg = <0x4000c800 0x400>; + interrupts = <18 19>; + clocks = <&cmu clk_HFPERCLKUSART2>; + status = "disabled"; + }; + + uart0: uart@4000c000 { /* USART0 */ + compatible = "efm32,uart"; + reg = <0x4000c000 0x400>; + interrupts = <3 4>; + clocks = <&cmu clk_HFPERCLKUSART0>; + status = "disabled"; + }; + + uart1: uart@4000c400 { /* USART1 */ + compatible = "efm32,uart"; + reg = <0x4000c400 0x400>; + interrupts = <15 16>; + clocks = <&cmu clk_HFPERCLKUSART1>; + status = "disabled"; + }; + + uart2: uart@40x4000c800 { /* USART2 */ + compatible = "efm32,uart"; + reg = <0x4000c800 0x400>; + interrupts = <18 19>; + clocks = <&cmu clk_HFPERCLKUSART2>; + status = "disabled"; + }; + + uart3: uart@4000e000 { /* UART0 */ + compatible = "efm32,uart"; + reg = <0x4000e000 0x400>; + interrupts = <20 21>; + clocks = <&cmu clk_HFPERCLKUART0>; + status = "disabled"; + }; + + uart4: uart@4000e400 { /* UART1 */ + compatible = "efm32,uart"; + reg = <0x4000e400 0x400>; + interrupts = <22 23>; + clocks = <&cmu clk_HFPERCLKUART1>; + status = "disabled"; + }; + + timer0: timer@40010000 { + compatible = "efm32,timer"; + reg = <0x40010000 0x400>; + interrupts = <2>; + clocks = <&cmu clk_HFPERCLKTIMER0>; + }; + + timer1: timer@40010400 { + compatible = "efm32,timer"; + reg = <0x40010400 0x400>; + interrupts = <12>; + clocks = <&cmu clk_HFPERCLKTIMER1>; + }; + + timer2: timer@40010800 { + compatible = "efm32,timer"; + reg = <0x40010800 0x400>; + interrupts = <13>; + clocks = <&cmu clk_HFPERCLKTIMER2>; + }; + + timer3: timer@40010c00 { + compatible = "efm32,timer"; + reg = <0x40010c00 0x400>; + interrupts = <14>; + clocks = <&cmu clk_HFPERCLKTIMER3>; + }; + + cmu: cmu@400c8000 { + compatible = "efm32gg,cmu"; + reg = <0x400c8000 0x400>; + interrupts = <32>; + #clock-cells = <1>; + }; + }; +}; diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts index 861aa7d6fc7d..50ccd151091e 100644 --- a/arch/arm/boot/dts/emev2-kzm9d.dts +++ b/arch/arm/boot/dts/emev2-kzm9d.dts @@ -9,7 +9,10 @@ */ /dts-v1/; -/include/ "emev2.dtsi" +#include "emev2.dtsi" +#include +#include +#include / { model = "EMEV2 KZM9D Board"; @@ -47,11 +50,46 @@ reg = <0x20000000 0x10000>; phy-mode = "mii"; interrupt-parent = <&gpio0>; - interrupts = <1 1>; /* active high */ + interrupts = <1 IRQ_TYPE_EDGE_RISING>; reg-io-width = <4>; smsc,irq-active-high; smsc,irq-push-pull; vddvario-supply = <®_1p8v>; vdd33a-supply = <®_3p3v>; }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@1 { + debounce_interval = <50>; + wakeup = <1>; + label = "DSW2-1"; + linux,code = ; + gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; + }; + button@2 { + debounce_interval = <50>; + wakeup = <1>; + label = "DSW2-2"; + linux,code = ; + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + }; + button@3 { + debounce_interval = <50>; + wakeup = <1>; + label = "DSW2-3"; + linux,code = ; + gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + }; + button@4 { + debounce_interval = <50>; + wakeup = <1>; + label = "DSW2-4"; + linux,code = ; + gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; + }; + }; }; diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index 9063a4434d6a..e37985fa10e2 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -8,7 +8,8 @@ * kind, whether express or implied. */ -/include/ "skeleton.dtsi" +#include "skeleton.dtsi" +#include / { compatible = "renesas,emev2"; @@ -48,44 +49,129 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 120 4>, - <0 121 4>; + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, + <0 121 IRQ_TYPE_LEVEL_HIGH>; + }; + + smu@e0110000 { + compatible = "renesas,emev2-smu"; + reg = <0xe0110000 0x10000>; + #address-cells = <2>; + #size-cells = <0>; + + c32ki: c32ki { + compatible = "fixed-clock"; + clock-frequency = <32768>; + #clock-cells = <0>; + }; + pll3_fo: pll3_fo { + compatible = "fixed-factor-clock"; + clocks = <&c32ki>; + clock-div = <1>; + clock-mult = <7000>; + #clock-cells = <0>; + }; + usia_u0_sclkdiv: usia_u0_sclkdiv { + compatible = "renesas,emev2-smu-clkdiv"; + reg = <0x610 0>; + clocks = <&pll3_fo>; + #clock-cells = <0>; + }; + usib_u1_sclkdiv: usib_u1_sclkdiv { + compatible = "renesas,emev2-smu-clkdiv"; + reg = <0x65c 0>; + clocks = <&pll3_fo>; + #clock-cells = <0>; + }; + usib_u2_sclkdiv: usib_u2_sclkdiv { + compatible = "renesas,emev2-smu-clkdiv"; + reg = <0x65c 16>; + clocks = <&pll3_fo>; + #clock-cells = <0>; + }; + usib_u3_sclkdiv: usib_u3_sclkdiv { + compatible = "renesas,emev2-smu-clkdiv"; + reg = <0x660 0>; + clocks = <&pll3_fo>; + #clock-cells = <0>; + }; + usia_u0_sclk: usia_u0_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x4a0 1>; + clocks = <&usia_u0_sclkdiv>; + #clock-cells = <0>; + }; + usib_u1_sclk: usib_u1_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x4b8 1>; + clocks = <&usib_u1_sclkdiv>; + #clock-cells = <0>; + }; + usib_u2_sclk: usib_u2_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x4bc 1>; + clocks = <&usib_u2_sclkdiv>; + #clock-cells = <0>; + }; + usib_u3_sclk: usib_u3_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x4c0 1>; + clocks = <&usib_u3_sclkdiv>; + #clock-cells = <0>; + }; + sti_sclk: sti_sclk { + compatible = "renesas,emev2-smu-gclk"; + reg = <0x528 1>; + clocks = <&c32ki>; + #clock-cells = <0>; + }; }; sti@e0180000 { compatible = "renesas,em-sti"; reg = <0xe0180000 0x54>; - interrupts = <0 125 0>; + interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&sti_sclk>; + clock-names = "sclk"; }; uart@e1020000 { compatible = "renesas,em-uart"; reg = <0xe1020000 0x38>; - interrupts = <0 8 0>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&usia_u0_sclk>; + clock-names = "sclk"; }; uart@e1030000 { compatible = "renesas,em-uart"; reg = <0xe1030000 0x38>; - interrupts = <0 9 0>; + interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&usib_u1_sclk>; + clock-names = "sclk"; }; uart@e1040000 { compatible = "renesas,em-uart"; reg = <0xe1040000 0x38>; - interrupts = <0 10 0>; + interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&usib_u2_sclk>; + clock-names = "sclk"; }; uart@e1050000 { compatible = "renesas,em-uart"; reg = <0xe1050000 0x38>; - interrupts = <0 11 0>; + interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&usib_u3_sclk>; + clock-names = "sclk"; }; gpio0: gpio@e0050000 { compatible = "renesas,em-gio"; reg = <0xe0050000 0x2c>, <0xe0050040 0x20>; - interrupts = <0 67 0>, <0 68 0>; + interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>, + <0 68 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; ngpios = <32>; @@ -95,7 +181,8 @@ gpio1: gpio@e0050080 { compatible = "renesas,em-gio"; reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>; - interrupts = <0 69 0>, <0 70 0>; + interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>, + <0 70 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; ngpios = <32>; @@ -105,7 +192,8 @@ gpio2: gpio@e0050100 { compatible = "renesas,em-gio"; reg = <0xe0050100 0x2c>, <0xe0050140 0x20>; - interrupts = <0 71 0>, <0 72 0>; + interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>, + <0 72 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; ngpios = <32>; @@ -115,7 +203,8 @@ gpio3: gpio@e0050180 { compatible = "renesas,em-gio"; reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>; - interrupts = <0 73 0>, <0 74 0>; + interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>, + <0 74 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; ngpios = <32>; @@ -125,7 +214,8 @@ gpio4: gpio@e0050200 { compatible = "renesas,em-gio"; reg = <0xe0050200 0x2c>, <0xe0050240 0x20>; - interrupts = <0 75 0>, <0 76 0>; + interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>, + <0 76 IRQ_TYPE_LEVEL_HIGH>; gpio-controller; #gpio-cells = <2>; ngpios = <31>; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index a73eeb5f258f..08452e183b57 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -85,21 +85,21 @@ reg = <0x10023CE0 0x20>; }; - gic:interrupt-controller@10490000 { + gic: interrupt-controller@10490000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; reg = <0x10490000 0x1000>, <0x10480000 0x100>; }; - combiner:interrupt-controller@10440000 { + combiner: interrupt-controller@10440000 { compatible = "samsung,exynos4210-combiner"; #interrupt-cells = <2>; interrupt-controller; reg = <0x10440000 0x1000>; }; - sys_reg: sysreg { + sys_reg: syscon@10010000 { compatible = "samsung,exynos4-sysreg", "syscon"; reg = <0x10010000 0x400>; }; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 1a12fb23767c..2aa13cb3bbed 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -313,7 +313,7 @@ display-timings { native-mode = <&timing0>; timing0: timing { - clock-frequency = <50000>; + clock-frequency = <47500000>; hactive = <1024>; vactive = <600>; hfront-porch = <64>; diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index 057d6829d319..48ecd7a755ab 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -36,11 +36,11 @@ reg = <0x10023CA0 0x20>; }; - gic:interrupt-controller@10490000 { + gic: interrupt-controller@10490000 { cpu-offset = <0x8000>; }; - combiner:interrupt-controller@10440000 { + combiner: interrupt-controller@10440000 { samsung,combiner-nr = <16>; interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, @@ -51,24 +51,21 @@ mct@10050000 { compatible = "samsung,exynos4210-mct"; reg = <0x10050000 0x800>; - interrupt-controller; - #interrups-cells = <2>; interrupt-parent = <&mct_map>; - interrupts = <0 0>, <1 0>, <2 0>, <3 0>, - <4 0>, <5 0>; + interrupts = <0>, <1>, <2>, <3>, <4>, <5>; clocks = <&clock 3>, <&clock 344>; clock-names = "fin_pll", "mct"; mct_map: mct-map { - #interrupt-cells = <2>; + #interrupt-cells = <1>; #address-cells = <0>; #size-cells = <0>; - interrupt-map = <0x0 0 &gic 0 57 0>, - <0x1 0 &gic 0 69 0>, - <0x2 0 &combiner 12 6>, - <0x3 0 &combiner 12 7>, - <0x4 0 &gic 0 42 0>, - <0x5 0 &gic 0 48 0>; + interrupt-map = <0 &gic 0 57 0>, + <1 &gic 0 69 0>, + <2 &combiner 12 6>, + <3 &combiner 12 7>, + <4 &gic 0 42 0>, + <5 &gic 0 48 0>; }; }; diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi index 6f34d7f6ba7e..94a43f9a05e2 100644 --- a/arch/arm/boot/dts/exynos4212.dtsi +++ b/arch/arm/boot/dts/exynos4212.dtsi @@ -22,7 +22,7 @@ / { compatible = "samsung,exynos4212"; - gic:interrupt-controller@10490000 { + gic: interrupt-controller@10490000 { cpu-offset = <0x8000>; }; @@ -34,26 +34,4 @@ <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, <0 107 0>, <0 108 0>; }; - - mct@10050000 { - compatible = "samsung,exynos4412-mct"; - reg = <0x10050000 0x800>; - interrupt-controller; - #interrups-cells = <2>; - interrupt-parent = <&mct_map>; - interrupts = <0 0>, <1 0>, <2 0>, <3 0>, - <4 0>, <5 0>; - - mct_map: mct-map { - #interrupt-cells = <2>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = <0x0 0 &gic 0 57 0>, - <0x1 0 &combiner 12 5>, - <0x2 0 &combiner 12 6>, - <0x3 0 &combiner 12 7>, - <0x4 0 &gic 1 12 0>, - <0x5 0 &gic 1 12 0>; - }; - }; }; diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts index 46c678ee119c..9804fcb71f8c 100644 --- a/arch/arm/boot/dts/exynos4412-odroidx.dts +++ b/arch/arm/boot/dts/exynos4412-odroidx.dts @@ -38,9 +38,7 @@ }; }; - mshc@12550000 { - #address-cells = <1>; - #size-cells = <0>; + mmc@12550000 { pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; pinctrl-names = "default"; vmmc-supply = <&ldo20_reg &buck8_reg>; @@ -49,7 +47,6 @@ num-slots = <1>; supports-highspeed; broken-cd; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -119,6 +116,7 @@ max77686: pmic@09 { compatible = "maxim,max77686"; reg = <0x09>; + #clock-cells = <1>; voltage-regulators { ldo1_reg: LDO1 { diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index d65984c440f6..6bc053924e9e 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -122,9 +122,7 @@ status = "okay"; }; - mshc@12550000 { - #address-cells = <1>; - #size-cells = <0>; + mmc@12550000 { pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; pinctrl-names = "default"; status = "okay"; @@ -132,7 +130,6 @@ num-slots = <1>; supports-highspeed; broken-cd; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -159,7 +156,7 @@ display-timings { native-mode = <&timing0>; timing0: timing { - clock-frequency = <50000>; + clock-frequency = <47500000>; hactive = <1024>; vactive = <600>; hfront-porch = <64>; diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts new file mode 100644 index 000000000000..0a9831256b33 --- /dev/null +++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts @@ -0,0 +1,93 @@ +/* + * FriendlyARM's Exynos4412 based TINY4412 board device tree source + * + * Copyright (c) 2013 Alex Ling + * + * Device tree source file for FriendlyARM's TINY4412 board which is based on + * Samsung's Exynos4412 SoC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +#include "exynos4412.dtsi" + +/ { + model = "FriendlyARM TINY4412 board based on Exynos4412"; + compatible = "friendlyarm,tiny4412", "samsung,exynos4412"; + + memory { + reg = <0x40000000 0x40000000>; + }; + + leds { + compatible = "gpio-leds"; + + led1 { + label = "led1"; + gpios = <&gpm4 0 1>; + default-state = "off"; + linux,default-trigger = "heartbeat"; + }; + + led2 { + label = "led2"; + gpios = <&gpm4 1 1>; + default-state = "off"; + }; + + led3 { + label = "led3"; + gpios = <&gpm4 2 1>; + default-state = "off"; + }; + + led4 { + label = "led4"; + gpios = <&gpm4 3 1>; + default-state = "off"; + linux,default-trigger = "mmc0"; + }; + }; + + rtc@10070000 { + status = "okay"; + }; + + sdhci@12530000 { + bus-width = <4>; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + pinctrl-names = "default"; + status = "okay"; + }; + + serial@13800000 { + status = "okay"; + }; + + serial@13810000 { + status = "okay"; + }; + + serial@13820000 { + status = "okay"; + }; + + serial@13830000 { + status = "okay"; + }; + + fixed-rate-clocks { + xxti { + compatible = "samsung,clock-xxti"; + clock-frequency = <0>; + }; + + xusbxti { + compatible = "samsung,clock-xusbxti"; + clock-frequency = <24000000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index fb7b9ae5f399..4f851ccf40eb 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -139,6 +139,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x09>; + #clock-cells = <1>; voltage-regulators { ldo1_reg: ldo1 { @@ -442,13 +443,25 @@ }; }; - sdhci@12510000 { - bus-width = <8>; + mmc@12550000 { + num-slots = <1>; + supports-highspeed; + broken-cd; non-removable; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus8>; - pinctrl-names = "default"; + card-detect-delay = <200>; vmmc-supply = <&vemmc_reg>; + clock-frequency = <400000000>; + samsung,dw-mshc-ciu-div = <0>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; + pinctrl-names = "default"; status = "okay"; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; }; serial@13800000 { diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi index e743e677a9e2..87b339c739de 100644 --- a/arch/arm/boot/dts/exynos4412.dtsi +++ b/arch/arm/boot/dts/exynos4412.dtsi @@ -22,7 +22,7 @@ / { compatible = "samsung,exynos4412"; - gic:interrupt-controller@10490000 { + gic: interrupt-controller@10490000 { cpu-offset = <0x4000>; }; @@ -35,37 +35,4 @@ <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>; }; - mct@10050000 { - compatible = "samsung,exynos4412-mct"; - reg = <0x10050000 0x800>; - interrupt-controller; - #interrups-cells = <2>; - interrupt-parent = <&mct_map>; - interrupts = <0 0>, <1 0>, <2 0>, <3 0>, - <4 0>, <5 0>, <6 0>, <7 0>; - clocks = <&clock 3>, <&clock 344>; - clock-names = "fin_pll", "mct"; - - mct_map: mct-map { - #interrupt-cells = <2>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = <0x0 0 &gic 0 57 0>, - <0x1 0 &combiner 12 5>, - <0x2 0 &combiner 12 6>, - <0x3 0 &combiner 12 7>, - <0x4 0 &gic 1 12 0>, - <0x5 0 &gic 1 12 0>, - <0x6 0 &gic 1 12 0>, - <0x7 0 &gic 1 12 0>; - }; - }; - - mshc@12550000 { - compatible = "samsung,exynos4412-dw-mshc"; - reg = <0x12550000 0x1000>; - interrupts = <0 77 0>; - #address-cells = <1>; - #size-cells = <0>; - }; }; diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index ad531fe6ab95..5c412aa14738 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi @@ -28,6 +28,7 @@ pinctrl3 = &pinctrl_3; fimc-lite0 = &fimc_lite_0; fimc-lite1 = &fimc_lite_1; + mshc0 = &mshc_0; }; pd_isp: isp-power-domain@10023CA0 { @@ -41,6 +42,26 @@ #clock-cells = <1>; }; + mct@10050000 { + compatible = "samsung,exynos4412-mct"; + reg = <0x10050000 0x800>; + interrupt-parent = <&mct_map>; + interrupts = <0>, <1>, <2>, <3>, <4>; + clocks = <&clock 3>, <&clock 344>; + clock-names = "fin_pll", "mct"; + + mct_map: mct-map { + #interrupt-cells = <1>; + #address-cells = <0>; + #size-cells = <0>; + interrupt-map = <0 &gic 0 57 0>, + <1 &combiner 12 5>, + <2 &combiner 12 6>, + <3 &combiner 12 7>, + <4 &gic 1 12 0>; + }; + }; + pinctrl_0: pinctrl@11400000 { compatible = "samsung,exynos4x12-pinctrl"; reg = <0x11400000 0x1000>; @@ -176,4 +197,16 @@ }; }; }; + + mshc_0: mmc@12550000 { + compatible = "samsung,exynos4412-dw-mshc"; + reg = <0x12550000 0x1000>; + interrupts = <0 77 0>; + #address-cells = <1>; + #size-cells = <0>; + fifo-depth = <0x80>; + clocks = <&clock 301>, <&clock 149>; + clock-names = "biu", "ciu"; + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi index 074739d39e2d..258dca441f36 100644 --- a/arch/arm/boot/dts/exynos5.dtsi +++ b/arch/arm/boot/dts/exynos5.dtsi @@ -23,7 +23,7 @@ reg = <0x10000000 0x100>; }; - combiner:interrupt-controller@10440000 { + combiner: interrupt-controller@10440000 { compatible = "samsung,exynos4210-combiner"; #interrupt-cells = <2>; interrupt-controller; @@ -39,7 +39,7 @@ <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; }; - gic:interrupt-controller@10481000 { + gic: interrupt-controller@10481000 { compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; @@ -50,27 +50,6 @@ interrupts = <1 9 0xf04>; }; - dwmmc_0: dwmmc0@12200000 { - compatible = "samsung,exynos5250-dw-mshc"; - interrupts = <0 75 0>; - #address-cells = <1>; - #size-cells = <0>; - }; - - dwmmc_1: dwmmc1@12210000 { - compatible = "samsung,exynos5250-dw-mshc"; - interrupts = <0 76 0>; - #address-cells = <1>; - #size-cells = <0>; - }; - - dwmmc_2: dwmmc2@12220000 { - compatible = "samsung,exynos5250-dw-mshc"; - interrupts = <0 77 0>; - #address-cells = <1>; - #size-cells = <0>; - }; - serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 684527087aa4..b42e658876e5 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -34,6 +34,7 @@ samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <20000>; samsung,i2c-slave-addr = <0x66>; + status = "okay"; s5m8767_pmic@66 { compatible = "samsung,s5m8767-pmic"; @@ -266,7 +267,7 @@ buck2_reg: BUCK2 { regulator-name = "vdd_arm"; - regulator-min-microvolt = <925000>; + regulator-min-microvolt = <912500>; regulator-max-microvolt = <1300000>; regulator-always-on; regulator-boot-on; @@ -302,11 +303,13 @@ buck7_reg: BUCK7 { regulator-name = "PVDD_BUCK7"; regulator-always-on; + op_mode = <1>; }; buck8_reg: BUCK8 { regulator-name = "PVDD_BUCK8"; regulator-always-on; + op_mode = <1>; }; buck9_reg: BUCK9 { @@ -319,11 +322,9 @@ }; }; - i2c@12C70000 { - status = "disabled"; - }; - i2c@12C80000 { + status = "okay"; + samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; samsung,i2c-slave-addr = <0x50>; @@ -335,7 +336,10 @@ }; i2c@12C90000 { + status = "okay"; + wm1811a@1a { + compatible = "wlf,wm1811"; reg = <0x1a>; @@ -353,23 +357,9 @@ }; }; - i2c@12CA0000 { - status = "disabled"; - }; - - i2c@12CB0000 { - status = "disabled"; - }; - - i2c@12CC0000 { - status = "disabled"; - }; - - i2c@12CD0000 { - status = "disabled"; - }; - i2c@12CE0000 { + status = "okay"; + samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; samsung,i2c-slave-addr = <0x38>; @@ -380,15 +370,11 @@ }; }; - i2c@121D0000 { - status = "disabled"; - }; - - dwmmc_0: dwmmc0@12200000 { + mmc_0: mmc@12200000 { + status = "okay"; num-slots = <1>; supports-highspeed; broken-cd; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -403,14 +389,10 @@ }; }; - dwmmc_1: dwmmc1@12210000 { - status = "disabled"; - }; - - dwmmc_2: dwmmc2@12220000 { + mmc_2: mmc@12220000 { + status = "okay"; num-slots = <1>; supports-highspeed; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -426,26 +408,10 @@ }; }; - dwmmc_3: dwmmc3@12230000 { - status = "disabled"; - }; - i2s0: i2s@03830000 { status = "okay"; }; - spi_0: spi@12d20000 { - status = "disabled"; - }; - - spi_1: spi@12d30000 { - status = "disabled"; - }; - - spi_2: spi@12d40000 { - status = "disabled"; - }; - gpio_keys { compatible = "gpio-keys"; diff --git a/arch/arm/boot/dts/cros5250-common.dtsi b/arch/arm/boot/dts/exynos5250-cros-common.dtsi similarity index 95% rename from arch/arm/boot/dts/cros5250-common.dtsi rename to arch/arm/boot/dts/exynos5250-cros-common.dtsi index 9b186ac06c8b..2c1560d52f1a 100644 --- a/arch/arm/boot/dts/cros5250-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-cros-common.dtsi @@ -37,6 +37,7 @@ }; i2c@12C60000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; @@ -48,6 +49,7 @@ pinctrl-0 = <&max77686_irq>; wakeup-source; reg = <0x09>; + #clock-cells = <1>; voltage-regulators { ldo1_reg: LDO1 { @@ -185,6 +187,7 @@ }; i2c@12C70000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; @@ -198,6 +201,7 @@ }; i2c@12C80000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; @@ -208,30 +212,31 @@ }; i2c@12C90000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; }; i2c@12CA0000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; }; i2c@12CB0000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; }; - i2c@12CC0000 { - status = "disabled"; - }; - i2c@12CD0000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; }; i2c@12CE0000 { + status = "okay"; samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <378000>; @@ -241,11 +246,10 @@ }; }; - dwmmc0@12200000 { + mmc@12200000 { num-slots = <1>; supports-highspeed; broken-cd; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -259,14 +263,9 @@ }; }; - dwmmc1@12210000 { - status = "disabled"; - }; - - dwmmc2@12220000 { + mmc@12220000 { num-slots = <1>; supports-highspeed; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -281,11 +280,10 @@ }; }; - dwmmc3@12230000 { + mmc@12230000 { num-slots = <1>; supports-highspeed; broken-cd; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -298,19 +296,12 @@ }; }; - spi_0: spi@12d20000 { - status = "disabled"; - }; - spi_1: spi@12d30000 { + status = "okay"; samsung,spi-src-clk = <0>; num-cs = <1>; }; - spi_2: spi@12d40000 { - status = "disabled"; - }; - hdmi { hpd-gpio = <&gpx3 7 0>; }; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index f86d56760a45..3e69837c435c 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -30,6 +30,7 @@ i2c@12C60000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <20000>; + status = "okay"; eeprom@50 { compatible = "samsung,s524ad0xd1"; @@ -37,7 +38,7 @@ }; }; - vdd:fixed-regulator@0 { + vdd: fixed-regulator@0 { compatible = "regulator-fixed"; regulator-name = "vdd-supply"; regulator-min-microvolt = <1800000>; @@ -45,7 +46,7 @@ regulator-always-on; }; - dbvdd:fixed-regulator@1 { + dbvdd: fixed-regulator@1 { compatible = "regulator-fixed"; regulator-name = "dbvdd-supply"; regulator-min-microvolt = <3300000>; @@ -53,7 +54,7 @@ regulator-always-on; }; - spkvdd:fixed-regulator@2 { + spkvdd: fixed-regulator@2 { compatible = "regulator-fixed"; regulator-name = "spkvdd-supply"; regulator-min-microvolt = <5000000>; @@ -64,6 +65,7 @@ i2c@12C70000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <20000>; + status = "okay"; eeprom@51 { compatible = "samsung,s524ad0xd1"; @@ -77,6 +79,9 @@ gpio-controller; #gpio-cells = <2>; + clocks = <&codec_mclk>; + clock-names = "MCLK1"; + AVDD2-supply = <&vdd>; CPVDD-supply = <&vdd>; DBVDD-supply = <&dbvdd>; @@ -89,6 +94,7 @@ samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <40000>; samsung,i2c-slave-addr = <0x38>; + status = "okay"; sata-phy { compatible = "samsung,sata-phy"; @@ -103,6 +109,7 @@ i2c@12C80000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; + status = "okay"; hdmiddc@50 { compatible = "samsung,exynos4210-hdmiddc"; @@ -110,29 +117,10 @@ }; }; - i2c@12C90000 { - status = "disabled"; - }; - - i2c@12CA0000 { - status = "disabled"; - }; - - i2c@12CB0000 { - status = "disabled"; - }; - - i2c@12CC0000 { - status = "disabled"; - }; - - i2c@12CD0000 { - status = "disabled"; - }; - i2c@12CE0000 { samsung,i2c-sda-delay = <100>; samsung,i2c-max-bus-freq = <66000>; + status = "okay"; hdmiphy@38 { compatible = "samsung,exynos4212-hdmiphy"; @@ -140,11 +128,11 @@ }; }; - dwmmc0@12200000 { + mmc@12200000 { + status = "okay"; num-slots = <1>; supports-highspeed; broken-cd; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -158,14 +146,10 @@ }; }; - dwmmc1@12210000 { - status = "disabled"; - }; - - dwmmc2@12220000 { + mmc@12220000 { + status = "okay"; num-slots = <1>; supports-highspeed; - fifo-depth = <0x80>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -180,15 +164,13 @@ }; }; - dwmmc3@12230000 { - status = "disabled"; - }; - spi_0: spi@12d20000 { status = "disabled"; }; spi_1: spi@12d30000 { + status = "okay"; + w25q80bw@0 { #address-cells = <1>; #size-cells = <1>; @@ -214,10 +196,6 @@ }; }; - spi_2: spi@12d40000 { - status = "disabled"; - }; - hdmi { hpd-gpio = <&gpx3 7 0>; }; @@ -279,5 +257,11 @@ compatible = "samsung,clock-xxti"; clock-frequency = <24000000>; }; + + codec_mclk: codec-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <16934000>; + }; }; }; diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index fd711e245e8d..7e45eea2d78f 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -10,7 +10,7 @@ /dts-v1/; #include "exynos5250.dtsi" -#include "cros5250-common.dtsi" +#include "exynos5250-cros-common.dtsi" / { model = "Google Snow"; @@ -85,7 +85,7 @@ keypad,num-rows = <8>; keypad,num-columns = <13>; google,needs-ghost-filter; - linux,keymap = <0x0001003a /* CAPSLK */ + linux,keymap = <0x0001007d /* L_META */ 0x0002003b /* F1 */ 0x00030030 /* B */ 0x00040044 /* F10 */ @@ -130,6 +130,7 @@ 0x04060024 /* J */ 0x04080027 /* ; */ 0x04090026 /* L */ + 0x040a002b /* \ */ 0x040b001c /* ENTER */ 0x0501002c /* Z */ @@ -171,11 +172,20 @@ }; }; + mmc@12200000 { + status = "okay"; + }; + + mmc@12220000 { + status = "okay"; + }; + /* * On Snow we've got SIP WiFi and so can keep drive strengths low to * reduce EMI. */ - dwmmc3@12230000 { + mmc@12230000 { + status = "okay"; slot@0 { pinctrl-names = "default"; pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 9db5047812f3..b7dec41e32af 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -33,10 +33,10 @@ gsc1 = &gsc_1; gsc2 = &gsc_2; gsc3 = &gsc_3; - mshc0 = &dwmmc_0; - mshc1 = &dwmmc_1; - mshc2 = &dwmmc_2; - mshc3 = &dwmmc_3; + mshc0 = &mmc_0; + mshc1 = &mmc_1; + mshc2 = &mmc_2; + mshc3 = &mmc_3; i2c0 = &i2c_0; i2c1 = &i2c_1; i2c2 = &i2c_2; @@ -60,11 +60,13 @@ device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <0>; + clock-frequency = <1700000000>; }; cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a15"; reg = <1>; + clock-frequency = <1700000000>; }; }; @@ -88,6 +90,8 @@ compatible = "samsung,exynos5250-audss-clock"; reg = <0x03810000 0x0C>; #clock-cells = <1>; + clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>; + clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in"; }; timer { @@ -242,6 +246,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c0_bus>; + status = "disabled"; }; i2c_1: i2c@12C70000 { @@ -254,6 +259,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c1_bus>; + status = "disabled"; }; i2c_2: i2c@12C80000 { @@ -266,6 +272,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c2_bus>; + status = "disabled"; }; i2c_3: i2c@12C90000 { @@ -278,6 +285,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c3_bus>; + status = "disabled"; }; i2c_4: i2c@12CA0000 { @@ -290,6 +298,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c4_bus>; + status = "disabled"; }; i2c_5: i2c@12CB0000 { @@ -302,6 +311,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c5_bus>; + status = "disabled"; }; i2c_6: i2c@12CC0000 { @@ -314,6 +324,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c6_bus>; + status = "disabled"; }; i2c_7: i2c@12CD0000 { @@ -326,6 +337,7 @@ clock-names = "i2c"; pinctrl-names = "default"; pinctrl-0 = <&i2c7_bus>; + status = "disabled"; }; i2c_8: i2c@12CE0000 { @@ -336,6 +348,7 @@ #size-cells = <0>; clocks = <&clock 302>; clock-names = "i2c"; + status = "disabled"; }; i2c@121D0000 { @@ -345,10 +358,12 @@ #size-cells = <0>; clocks = <&clock 288>; clock-names = "i2c"; + status = "disabled"; }; spi_0: spi@12d20000 { compatible = "samsung,exynos4210-spi"; + status = "disabled"; reg = <0x12d20000 0x100>; interrupts = <0 66 0>; dmas = <&pdma0 5 @@ -364,6 +379,7 @@ spi_1: spi@12d30000 { compatible = "samsung,exynos4210-spi"; + status = "disabled"; reg = <0x12d30000 0x100>; interrupts = <0 67 0>; dmas = <&pdma1 5 @@ -379,6 +395,7 @@ spi_2: spi@12d40000 { compatible = "samsung,exynos4210-spi"; + status = "disabled"; reg = <0x12d40000 0x100>; interrupts = <0 68 0>; dmas = <&pdma0 7 @@ -392,25 +409,43 @@ pinctrl-0 = <&spi2_bus>; }; - dwmmc_0: dwmmc0@12200000 { + mmc_0: mmc@12200000 { + compatible = "samsung,exynos5250-dw-mshc"; + interrupts = <0 75 0>; + #address-cells = <1>; + #size-cells = <0>; reg = <0x12200000 0x1000>; clocks = <&clock 280>, <&clock 139>; clock-names = "biu", "ciu"; + fifo-depth = <0x80>; + status = "disabled"; }; - dwmmc_1: dwmmc1@12210000 { + mmc_1: mmc@12210000 { + compatible = "samsung,exynos5250-dw-mshc"; + interrupts = <0 76 0>; + #address-cells = <1>; + #size-cells = <0>; reg = <0x12210000 0x1000>; clocks = <&clock 281>, <&clock 140>; clock-names = "biu", "ciu"; + fifo-depth = <0x80>; + status = "disabled"; }; - dwmmc_2: dwmmc2@12220000 { + mmc_2: mmc@12220000 { + compatible = "samsung,exynos5250-dw-mshc"; + interrupts = <0 77 0>; + #address-cells = <1>; + #size-cells = <0>; reg = <0x12220000 0x1000>; clocks = <&clock 282>, <&clock 141>; clock-names = "biu", "ciu"; + fifo-depth = <0x80>; + status = "disabled"; }; - dwmmc_3: dwmmc3@12230000 { + mmc_3: mmc@12230000 { compatible = "samsung,exynos5250-dw-mshc"; reg = <0x12230000 0x1000>; interrupts = <0 78 0>; @@ -418,6 +453,8 @@ #size-cells = <0>; clocks = <&clock 283>, <&clock 142>; clock-names = "biu", "ciu"; + fifo-depth = <0x80>; + status = "disabled"; }; i2s0: i2s@03830000 { @@ -526,6 +563,15 @@ }; }; + pwm: pwm@12dd0000 { + compatible = "samsung,exynos4210-pwm"; + reg = <0x12dd0000 0x100>; + samsung,pwm-outputs = <0>, <1>, <2>, <3>; + #pwm-cells = <3>; + clocks = <&clock 311>; + clock-names = "timers"; + }; + amba { #address-cells = <1>; #size-cells = <1>; @@ -559,7 +605,7 @@ compatible = "arm,pl330", "arm,primecell"; reg = <0x10800000 0x1000>; interrupts = <0 33 0>; - clocks = <&clock 271>; + clocks = <&clock 346>; clock-names = "apb_pclk"; #dma-cells = <1>; #dma-channels = <8>; diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts new file mode 100644 index 000000000000..7340745ff979 --- /dev/null +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -0,0 +1,66 @@ +/* + * Samsung's Exynos5420 based Arndale Octa board device tree source + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/dts-v1/; +#include "exynos5420.dtsi" + +/ { + model = "Insignal Arndale Octa evaluation board based on EXYNOS5420"; + compatible = "insignal,arndale-octa", "samsung,exynos5420"; + + memory { + reg = <0x20000000 0x80000000>; + }; + + chosen { + bootargs = "console=ttySAC3,115200"; + }; + + fixed-rate-clocks { + oscclk { + compatible = "samsung,exynos5420-oscclk"; + clock-frequency = <24000000>; + }; + }; + + mmc@12200000 { + status = "okay"; + broken-cd; + supports-highspeed; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 4>; + samsung,dw-mshc-ddr-timing = <0 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; + }; + + mmc@12220000 { + status = "okay"; + supports-highspeed; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + + slot@0 { + reg = <0>; + bus-width = <4>; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi index e695aba5f73c..e62c8eb57438 100644 --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi @@ -64,7 +64,7 @@ samsung,pins = "gpx0-7"; samsung,pin-function = <3>; samsung,pin-pud = <0>; - samaung,pin-drv = <0>; + samsung,pin-drv = <0>; }; }; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 79524c74c603..fb5a1e25c632 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -31,6 +31,39 @@ }; }; + mmc@12200000 { + status = "okay"; + broken-cd; + supports-highspeed; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 4>; + samsung,dw-mshc-ddr-timing = <0 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; + }; + + mmc@12220000 { + status = "okay"; + supports-highspeed; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + + slot@0 { + reg = <0>; + bus-width = <4>; + }; + }; + dp-controller@145B0000 { pinctrl-names = "default"; pinctrl-0 = <&dp_hpd>; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 09aa06cb3d3a..8db792b26f79 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -22,6 +22,9 @@ compatible = "samsung,exynos5420"; aliases { + mshc0 = &mmc_0; + mshc1 = &mmc_1; + mshc2 = &mmc_2; pinctrl0 = &pinctrl_0; pinctrl1 = &pinctrl_1; pinctrl2 = &pinctrl_2; @@ -31,6 +34,18 @@ i2c1 = &i2c_1; i2c2 = &i2c_2; i2c3 = &i2c_3; + i2c4 = &hsi2c_4; + i2c5 = &hsi2c_5; + i2c6 = &hsi2c_6; + i2c7 = &hsi2c_7; + i2c8 = &hsi2c_8; + i2c9 = &hsi2c_9; + i2c10 = &hsi2c_10; + gsc0 = &gsc_0; + gsc1 = &gsc_1; + spi0 = &spi_0; + spi1 = &spi_1; + spi2 = &spi_2; }; cpus { @@ -64,6 +79,34 @@ reg = <0x3>; clock-frequency = <1800000000>; }; + + cpu4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clock-frequency = <1000000000>; + }; + + cpu5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + }; + + cpu6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + }; + + cpu7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + }; }; clock: clock-controller@10010000 { @@ -76,8 +119,8 @@ compatible = "samsung,exynos5420-audss-clock"; reg = <0x03810000 0x0C>; #clock-cells = <1>; - clocks = <&clock 148>; - clock-names = "sclk_audio"; + clocks = <&clock 1>, <&clock 5>, <&clock 148>, <&clock 149>; + clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in"; }; codec@11000000 { @@ -88,13 +131,50 @@ clock-names = "mfc"; }; + mmc_0: mmc@12200000 { + compatible = "samsung,exynos5420-dw-mshc-smu"; + interrupts = <0 75 0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x12200000 0x2000>; + clocks = <&clock 351>, <&clock 132>; + clock-names = "biu", "ciu"; + fifo-depth = <0x40>; + status = "disabled"; + }; + + mmc_1: mmc@12210000 { + compatible = "samsung,exynos5420-dw-mshc-smu"; + interrupts = <0 76 0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x12210000 0x2000>; + clocks = <&clock 352>, <&clock 133>; + clock-names = "biu", "ciu"; + fifo-depth = <0x40>; + status = "disabled"; + }; + + mmc_2: mmc@12220000 { + compatible = "samsung,exynos5420-dw-mshc"; + interrupts = <0 77 0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x12220000 0x1000>; + clocks = <&clock 353>, <&clock 134>; + clock-names = "biu", "ciu"; + fifo-depth = <0x40>; + status = "disabled"; + }; + mct@101C0000 { compatible = "samsung,exynos4210-mct"; reg = <0x101C0000 0x800>; interrupt-controller; #interrups-cells = <1>; interrupt-parent = <&mct_map>; - interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>; + interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, + <8>, <9>, <10>, <11>; clocks = <&clock 1>, <&clock 315>; clock-names = "fin_pll", "mct"; @@ -109,7 +189,11 @@ <4 &gic 0 120 0>, <5 &gic 0 121 0>, <6 &gic 0 122 0>, - <7 &gic 0 123 0>; + <7 &gic 0 123 0>, + <8 &gic 0 128 0>, + <9 &gic 0 129 0>, + <10 &gic 0 130 0>, + <11 &gic 0 131 0>; }; }; @@ -190,6 +274,106 @@ status = "okay"; }; + amba { + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus"; + interrupt-parent = <&gic>; + ranges; + + pdma0: pdma@121A0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x121A0000 0x1000>; + interrupts = <0 34 0>; + clocks = <&clock 362>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; + }; + + pdma1: pdma@121B0000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x121B0000 0x1000>; + interrupts = <0 35 0>; + clocks = <&clock 363>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; + }; + + mdma0: mdma@10800000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x10800000 0x1000>; + interrupts = <0 33 0>; + clocks = <&clock 473>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <1>; + }; + + mdma1: mdma@11C10000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x11C10000 0x1000>; + interrupts = <0 124 0>; + clocks = <&clock 442>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <1>; + }; + }; + + spi_0: spi@12d20000 { + compatible = "samsung,exynos4210-spi"; + reg = <0x12d20000 0x100>; + interrupts = <0 66 0>; + dmas = <&pdma0 5 + &pdma0 4>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_bus>; + clocks = <&clock 271>, <&clock 135>; + clock-names = "spi", "spi_busclk0"; + status = "disabled"; + }; + + spi_1: spi@12d30000 { + compatible = "samsung,exynos4210-spi"; + reg = <0x12d30000 0x100>; + interrupts = <0 67 0>; + dmas = <&pdma1 5 + &pdma1 4>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_bus>; + clocks = <&clock 272>, <&clock 136>; + clock-names = "spi", "spi_busclk0"; + status = "disabled"; + }; + + spi_2: spi@12d40000 { + compatible = "samsung,exynos4210-spi"; + reg = <0x12d40000 0x100>; + interrupts = <0 68 0>; + dmas = <&pdma0 7 + &pdma0 6>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_bus>; + clocks = <&clock 273>, <&clock 137>; + clock-names = "spi", "spi_busclk0"; + status = "disabled"; + }; + serial@12C00000 { clocks = <&clock 257>, <&clock 128>; clock-names = "uart", "clk_uart_baud0"; @@ -210,6 +394,15 @@ clock-names = "uart", "clk_uart_baud0"; }; + pwm: pwm@12dd0000 { + compatible = "samsung,exynos4210-pwm"; + reg = <0x12dd0000 0x100>; + samsung,pwm-outputs = <0>, <1>, <2>, <3>; + #pwm-cells = <3>; + clocks = <&clock 279>; + clock-names = "timers"; + }; + dp_phy: video-phy@10040728 { compatible = "samsung,exynos5250-dp-video-phy"; reg = <0x10040728 4>; @@ -292,6 +485,97 @@ status = "disabled"; }; + hsi2c_4: i2c@12CA0000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12CA0000 0x1000>; + interrupts = <0 60 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_hs_bus>; + clocks = <&clock 265>; + clock-names = "hsi2c"; + status = "disabled"; + }; + + hsi2c_5: i2c@12CB0000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12CB0000 0x1000>; + interrupts = <0 61 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_hs_bus>; + clocks = <&clock 266>; + clock-names = "hsi2c"; + status = "disabled"; + }; + + hsi2c_6: i2c@12CC0000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12CC0000 0x1000>; + interrupts = <0 62 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_hs_bus>; + clocks = <&clock 267>; + clock-names = "hsi2c"; + status = "disabled"; + }; + + hsi2c_7: i2c@12CD0000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12CD0000 0x1000>; + interrupts = <0 63 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_hs_bus>; + clocks = <&clock 268>; + clock-names = "hsi2c"; + status = "disabled"; + }; + + hsi2c_8: i2c@12E00000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12E00000 0x1000>; + interrupts = <0 87 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_hs_bus>; + clocks = <&clock 281>; + clock-names = "hsi2c"; + status = "disabled"; + }; + + hsi2c_9: i2c@12E10000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12E10000 0x1000>; + interrupts = <0 88 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c9_hs_bus>; + clocks = <&clock 282>; + clock-names = "hsi2c"; + status = "disabled"; + }; + + hsi2c_10: i2c@12E20000 { + compatible = "samsung,exynos5-hsi2c"; + reg = <0x12E20000 0x1000>; + interrupts = <0 203 0>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c10_hs_bus>; + clocks = <&clock 283>; + clock-names = "hsi2c"; + status = "disabled"; + }; + hdmi@14530000 { compatible = "samsung,exynos4212-hdmi"; reg = <0x14530000 0x70000>; @@ -310,4 +594,62 @@ clocks = <&clock 431>, <&clock 143>; clock-names = "mixer", "sclk_hdmi"; }; + + gsc_0: video-scaler@13e00000 { + compatible = "samsung,exynos5-gsc"; + reg = <0x13e00000 0x1000>; + interrupts = <0 85 0>; + clocks = <&clock 465>; + clock-names = "gscl"; + samsung,power-domain = <&gsc_pd>; + }; + + gsc_1: video-scaler@13e10000 { + compatible = "samsung,exynos5-gsc"; + reg = <0x13e10000 0x1000>; + interrupts = <0 86 0>; + clocks = <&clock 466>; + clock-names = "gscl"; + samsung,power-domain = <&gsc_pd>; + }; + + tmu_cpu0: tmu@10060000 { + compatible = "samsung,exynos5420-tmu"; + reg = <0x10060000 0x100>; + interrupts = <0 65 0>; + clocks = <&clock 318>; + clock-names = "tmu_apbif"; + }; + + tmu_cpu1: tmu@10064000 { + compatible = "samsung,exynos5420-tmu"; + reg = <0x10064000 0x100>; + interrupts = <0 183 0>; + clocks = <&clock 318>; + clock-names = "tmu_apbif"; + }; + + tmu_cpu2: tmu@10068000 { + compatible = "samsung,exynos5420-tmu-ext-triminfo"; + reg = <0x10068000 0x100>, <0x1006c000 0x4>; + interrupts = <0 184 0>; + clocks = <&clock 318>, <&clock 318>; + clock-names = "tmu_apbif", "tmu_triminfo_apbif"; + }; + + tmu_cpu3: tmu@1006c000 { + compatible = "samsung,exynos5420-tmu-ext-triminfo"; + reg = <0x1006c000 0x100>, <0x100a0000 0x4>; + interrupts = <0 185 0>; + clocks = <&clock 318>, <&clock 319>; + clock-names = "tmu_apbif", "tmu_triminfo_apbif"; + }; + + tmu_gpu: tmu@100a0000 { + compatible = "samsung,exynos5420-tmu-ext-triminfo"; + reg = <0x100a0000 0x100>, <0x10068000 0x4>; + interrupts = <0 215 0>; + clocks = <&clock 319>, <&clock 318>; + clock-names = "tmu_apbif", "tmu_triminfo_apbif"; + }; }; diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index 8da107088ce4..02a0a1226cef 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi @@ -29,7 +29,7 @@ #clock-cells = <1>; }; - gic:interrupt-controller@2E0000 { + gic: interrupt-controller@2E0000 { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; interrupt-controller; diff --git a/arch/arm/boot/dts/hi3620-hi4511.dts b/arch/arm/boot/dts/hi3620-hi4511.dts new file mode 100644 index 000000000000..fe623928f687 --- /dev/null +++ b/arch/arm/boot/dts/hi3620-hi4511.dts @@ -0,0 +1,649 @@ +/* + * Copyright (C) 2012-2013 Linaro Ltd. + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; + +#include "hi3620.dtsi" + +/ { + model = "Hisilicon Hi4511 Development Board"; + compatible = "hisilicon,hi3620-hi4511"; + + chosen { + bootargs = "console=ttyAMA0,115200 root=/dev/ram0 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x40000000 0x20000000>; + }; + + amba { + dual_timer0: dual_timer@800000 { + status = "ok"; + }; + + uart0: uart@b00000 { /* console */ + pinctrl-names = "default", "idle"; + pinctrl-0 = <&uart0_pmx_func &uart0_cfg_func>; + pinctrl-1 = <&uart0_pmx_idle &uart0_cfg_idle>; + status = "ok"; + }; + + uart1: uart@b01000 { /* modem */ + pinctrl-names = "default", "idle"; + pinctrl-0 = <&uart1_pmx_func &uart1_cfg_func>; + pinctrl-1 = <&uart1_pmx_idle &uart1_cfg_idle>; + status = "ok"; + }; + + uart2: uart@b02000 { /* audience */ + pinctrl-names = "default", "idle"; + pinctrl-0 = <&uart2_pmx_func &uart2_cfg_func>; + pinctrl-1 = <&uart2_pmx_idle &uart2_cfg_idle>; + status = "ok"; + }; + + uart3: uart@b03000 { + pinctrl-names = "default", "idle"; + pinctrl-0 = <&uart3_pmx_func &uart3_cfg_func>; + pinctrl-1 = <&uart3_pmx_idle &uart3_cfg_idle>; + status = "ok"; + }; + + uart4: uart@b04000 { + pinctrl-names = "default", "idle"; + pinctrl-0 = <&uart4_pmx_func &uart4_cfg_func>; + pinctrl-1 = <&uart4_pmx_idle &uart4_cfg_func>; + status = "ok"; + }; + + pmx0: pinmux@803000 { + pinctrl-names = "default"; + pinctrl-0 = <&board_pmx_pins>; + + board_pmx_pins: board_pmx_pins { + pinctrl-single,pins = < + 0x008 0x0 /* GPIO -- eFUSE_DOUT */ + 0x100 0x0 /* USIM_CLK & USIM_DATA (IOMG63) */ + >; + }; + uart0_pmx_func: uart0_pmx_func { + pinctrl-single,pins = < + 0x0f0 0x0 + 0x0f4 0x0 /* UART0_RX & UART0_TX */ + >; + }; + uart0_pmx_idle: uart0_pmx_idle { + pinctrl-single,pins = < + /*0x0f0 0x1*/ /* UART0_CTS & UART0_RTS */ + 0x0f4 0x1 /* UART0_RX & UART0_TX */ + >; + }; + uart1_pmx_func: uart1_pmx_func { + pinctrl-single,pins = < + 0x0f8 0x0 /* UART1_CTS & UART1_RTS (IOMG61) */ + 0x0fc 0x0 /* UART1_RX & UART1_TX (IOMG62) */ + >; + }; + uart1_pmx_idle: uart1_pmx_idle { + pinctrl-single,pins = < + 0x0f8 0x1 /* GPIO (IOMG61) */ + 0x0fc 0x1 /* GPIO (IOMG62) */ + >; + }; + uart2_pmx_func: uart2_pmx_func { + pinctrl-single,pins = < + 0x104 0x2 /* UART2_RXD (IOMG96) */ + 0x108 0x2 /* UART2_TXD (IOMG64) */ + >; + }; + uart2_pmx_idle: uart2_pmx_idle { + pinctrl-single,pins = < + 0x104 0x1 /* GPIO (IOMG96) */ + 0x108 0x1 /* GPIO (IOMG64) */ + >; + }; + uart3_pmx_func: uart3_pmx_func { + pinctrl-single,pins = < + 0x160 0x2 /* UART3_CTS & UART3_RTS (IOMG85) */ + 0x164 0x2 /* UART3_RXD & UART3_TXD (IOMG86) */ + >; + }; + uart3_pmx_idle: uart3_pmx_idle { + pinctrl-single,pins = < + 0x160 0x1 /* GPIO (IOMG85) */ + 0x164 0x1 /* GPIO (IOMG86) */ + >; + }; + uart4_pmx_func: uart4_pmx_func { + pinctrl-single,pins = < + 0x168 0x0 /* UART4_CTS & UART4_RTS (IOMG87) */ + 0x16c 0x0 /* UART4_RXD (IOMG88) */ + 0x170 0x0 /* UART4_TXD (IOMG93) */ + >; + }; + uart4_pmx_idle: uart4_pmx_idle { + pinctrl-single,pins = < + 0x168 0x1 /* GPIO (IOMG87) */ + 0x16c 0x1 /* GPIO (IOMG88) */ + 0x170 0x1 /* GPIO (IOMG93) */ + >; + }; + i2c0_pmx_func: i2c0_pmx_func { + pinctrl-single,pins = < + 0x0b4 0x0 /* I2C0_SCL & I2C0_SDA (IOMG45) */ + >; + }; + i2c0_pmx_idle: i2c0_pmx_idle { + pinctrl-single,pins = < + 0x0b4 0x1 /* GPIO (IOMG45) */ + >; + }; + i2c1_pmx_func: i2c1_pmx_func { + pinctrl-single,pins = < + 0x0b8 0x0 /* I2C1_SCL & I2C1_SDA (IOMG46) */ + >; + }; + i2c1_pmx_idle: i2c1_pmx_idle { + pinctrl-single,pins = < + 0x0b8 0x1 /* GPIO (IOMG46) */ + >; + }; + i2c2_pmx_func: i2c2_pmx_func { + pinctrl-single,pins = < + 0x068 0x0 /* I2C2_SCL (IOMG26) */ + 0x06c 0x0 /* I2C2_SDA (IOMG27) */ + >; + }; + i2c2_pmx_idle: i2c2_pmx_idle { + pinctrl-single,pins = < + 0x068 0x1 /* GPIO (IOMG26) */ + 0x06c 0x1 /* GPIO (IOMG27) */ + >; + }; + i2c3_pmx_func: i2c3_pmx_func { + pinctrl-single,pins = < + 0x050 0x2 /* I2C3_SCL (IOMG20) */ + 0x054 0x2 /* I2C3_SDA (IOMG21) */ + >; + }; + i2c3_pmx_idle: i2c3_pmx_idle { + pinctrl-single,pins = < + 0x050 0x1 /* GPIO (IOMG20) */ + 0x054 0x1 /* GPIO (IOMG21) */ + >; + }; + spi0_pmx_func: spi0_pmx_func { + pinctrl-single,pins = < + 0x0d4 0x0 /* SPI0_CLK/SPI0_DI/SPI0_DO (IOMG53) */ + 0x0d8 0x0 /* SPI0_CS0 (IOMG54) */ + 0x0dc 0x0 /* SPI0_CS1 (IOMG55) */ + 0x0e0 0x0 /* SPI0_CS2 (IOMG56) */ + 0x0e4 0x0 /* SPI0_CS3 (IOMG57) */ + >; + }; + spi0_pmx_idle: spi0_pmx_idle { + pinctrl-single,pins = < + 0x0d4 0x1 /* GPIO (IOMG53) */ + 0x0d8 0x1 /* GPIO (IOMG54) */ + 0x0dc 0x1 /* GPIO (IOMG55) */ + 0x0e0 0x1 /* GPIO (IOMG56) */ + 0x0e4 0x1 /* GPIO (IOMG57) */ + >; + }; + spi1_pmx_func: spi1_pmx_func { + pinctrl-single,pins = < + 0x184 0x0 /* SPI1_CLK/SPI1_DI (IOMG98) */ + 0x0e8 0x0 /* SPI1_DO (IOMG58) */ + 0x0ec 0x0 /* SPI1_CS (IOMG95) */ + >; + }; + spi1_pmx_idle: spi1_pmx_idle { + pinctrl-single,pins = < + 0x184 0x1 /* GPIO (IOMG98) */ + 0x0e8 0x1 /* GPIO (IOMG58) */ + 0x0ec 0x1 /* GPIO (IOMG95) */ + >; + }; + kpc_pmx_func: kpc_pmx_func { + pinctrl-single,pins = < + 0x12c 0x0 /* KEY_IN0 (IOMG73) */ + 0x130 0x0 /* KEY_IN1 (IOMG74) */ + 0x134 0x0 /* KEY_IN2 (IOMG75) */ + 0x10c 0x0 /* KEY_OUT0 (IOMG65) */ + 0x110 0x0 /* KEY_OUT1 (IOMG66) */ + 0x114 0x0 /* KEY_OUT2 (IOMG67) */ + >; + }; + kpc_pmx_idle: kpc_pmx_idle { + pinctrl-single,pins = < + 0x12c 0x1 /* GPIO (IOMG73) */ + 0x130 0x1 /* GPIO (IOMG74) */ + 0x134 0x1 /* GPIO (IOMG75) */ + 0x10c 0x1 /* GPIO (IOMG65) */ + 0x110 0x1 /* GPIO (IOMG66) */ + 0x114 0x1 /* GPIO (IOMG67) */ + >; + }; + gpio_key_func: gpio_key_func { + pinctrl-single,pins = < + 0x10c 0x1 /* KEY_OUT0/GPIO (IOMG65) */ + 0x130 0x1 /* KEY_IN1/GPIO (IOMG74) */ + >; + }; + emmc_pmx_func: emmc_pmx_func { + pinctrl-single,pins = < + 0x030 0x2 /* eMMC_CMD/eMMC_CLK (IOMG12) */ + 0x018 0x0 /* NAND_CS3_N (IOMG6) */ + 0x024 0x0 /* NAND_BUSY2_N (IOMG8) */ + 0x028 0x0 /* NAND_BUSY3_N (IOMG9) */ + 0x02c 0x2 /* eMMC_DATA[0:7] (IOMG10) */ + >; + }; + emmc_pmx_idle: emmc_pmx_idle { + pinctrl-single,pins = < + 0x030 0x0 /* GPIO (IOMG12) */ + 0x018 0x1 /* GPIO (IOMG6) */ + 0x024 0x1 /* GPIO (IOMG8) */ + 0x028 0x1 /* GPIO (IOMG9) */ + 0x02c 0x1 /* GPIO (IOMG10) */ + >; + }; + sd_pmx_func: sd_pmx_func { + pinctrl-single,pins = < + 0x0bc 0x0 /* SD_CLK/SD_CMD/SD_DATA0/SD_DATA1/SD_DATA2 (IOMG47) */ + 0x0c0 0x0 /* SD_DATA3 (IOMG48) */ + >; + }; + sd_pmx_idle: sd_pmx_idle { + pinctrl-single,pins = < + 0x0bc 0x1 /* GPIO (IOMG47) */ + 0x0c0 0x1 /* GPIO (IOMG48) */ + >; + }; + nand_pmx_func: nand_pmx_func { + pinctrl-single,pins = < + 0x00c 0x0 /* NAND_ALE/NAND_CLE/.../NAND_DATA[0:7] (IOMG3) */ + 0x010 0x0 /* NAND_CS1_N (IOMG4) */ + 0x014 0x0 /* NAND_CS2_N (IOMG5) */ + 0x018 0x0 /* NAND_CS3_N (IOMG6) */ + 0x01c 0x0 /* NAND_BUSY0_N (IOMG94) */ + 0x020 0x0 /* NAND_BUSY1_N (IOMG7) */ + 0x024 0x0 /* NAND_BUSY2_N (IOMG8) */ + 0x028 0x0 /* NAND_BUSY3_N (IOMG9) */ + 0x02c 0x0 /* NAND_DATA[8:15] (IOMG10) */ + >; + }; + nand_pmx_idle: nand_pmx_idle { + pinctrl-single,pins = < + 0x00c 0x1 /* GPIO (IOMG3) */ + 0x010 0x1 /* GPIO (IOMG4) */ + 0x014 0x1 /* GPIO (IOMG5) */ + 0x018 0x1 /* GPIO (IOMG6) */ + 0x01c 0x1 /* GPIO (IOMG94) */ + 0x020 0x1 /* GPIO (IOMG7) */ + 0x024 0x1 /* GPIO (IOMG8) */ + 0x028 0x1 /* GPIO (IOMG9) */ + 0x02c 0x1 /* GPIO (IOMG10) */ + >; + }; + sdio_pmx_func: sdio_pmx_func { + pinctrl-single,pins = < + 0x0c4 0x0 /* SDIO_CLK/SDIO_CMD/SDIO_DATA[0:3] (IOMG49) */ + >; + }; + sdio_pmx_idle: sdio_pmx_idle { + pinctrl-single,pins = < + 0x0c4 0x1 /* GPIO (IOMG49) */ + >; + }; + audio_out_pmx_func: audio_out_pmx_func { + pinctrl-single,pins = < + 0x0f0 0x1 /* GPIO (IOMG59), audio spk & earphone */ + >; + }; + }; + + pmx1: pinmux@803800 { + pinctrl-names = "default"; + pinctrl-0 = < &board_pu_pins &board_pd_pins &board_pd_ps_pins + &board_np_pins &board_ps_pins &kpc_cfg_func + &audio_out_cfg_func>; + board_pu_pins: board_pu_pins { + pinctrl-single,pins = < + 0x014 0 /* GPIO_158 (IOCFG2) */ + 0x018 0 /* GPIO_159 (IOCFG3) */ + 0x01c 0 /* BOOT_MODE0 (IOCFG4) */ + 0x020 0 /* BOOT_MODE1 (IOCFG5) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <1 1 0 1>; + }; + board_pd_pins: board_pd_pins { + pinctrl-single,pins = < + 0x038 0 /* eFUSE_DOUT (IOCFG11) */ + 0x150 0 /* ISP_GPIO8 (IOCFG93) */ + 0x154 0 /* ISP_GPIO9 (IOCFG94) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + board_pd_ps_pins: board_pd_ps_pins { + pinctrl-single,pins = < + 0x2d8 0 /* CLK_OUT0 (IOCFG190) */ + 0x004 0 /* PMU_SPI_DATA (IOCFG192) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + board_np_pins: board_np_pins { + pinctrl-single,pins = < + 0x24c 0 /* KEYPAD_OUT7 (IOCFG155) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + board_ps_pins: board_ps_pins { + pinctrl-single,pins = < + 0x000 0 /* PMU_SPI_CLK (IOCFG191) */ + 0x008 0 /* PMU_SPI_CS_N (IOCFG193) */ + >; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + uart0_cfg_func: uart0_cfg_func { + pinctrl-single,pins = < + 0x208 0 /* UART0_RXD (IOCFG138) */ + 0x20c 0 /* UART0_TXD (IOCFG139) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart0_cfg_idle: uart0_cfg_idle { + pinctrl-single,pins = < + 0x208 0 /* UART0_RXD (IOCFG138) */ + 0x20c 0 /* UART0_TXD (IOCFG139) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart1_cfg_func: uart1_cfg_func { + pinctrl-single,pins = < + 0x210 0 /* UART1_CTS (IOCFG140) */ + 0x214 0 /* UART1_RTS (IOCFG141) */ + 0x218 0 /* UART1_RXD (IOCFG142) */ + 0x21c 0 /* UART1_TXD (IOCFG143) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart1_cfg_idle: uart1_cfg_idle { + pinctrl-single,pins = < + 0x210 0 /* UART1_CTS (IOCFG140) */ + 0x214 0 /* UART1_RTS (IOCFG141) */ + 0x218 0 /* UART1_RXD (IOCFG142) */ + 0x21c 0 /* UART1_TXD (IOCFG143) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart2_cfg_func: uart2_cfg_func { + pinctrl-single,pins = < + 0x220 0 /* UART2_CTS (IOCFG144) */ + 0x224 0 /* UART2_RTS (IOCFG145) */ + 0x228 0 /* UART2_RXD (IOCFG146) */ + 0x22c 0 /* UART2_TXD (IOCFG147) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart2_cfg_idle: uart2_cfg_idle { + pinctrl-single,pins = < + 0x220 0 /* GPIO (IOCFG144) */ + 0x224 0 /* GPIO (IOCFG145) */ + 0x228 0 /* GPIO (IOCFG146) */ + 0x22c 0 /* GPIO (IOCFG147) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart3_cfg_func: uart3_cfg_func { + pinctrl-single,pins = < + 0x294 0 /* UART3_CTS (IOCFG173) */ + 0x298 0 /* UART3_RTS (IOCFG174) */ + 0x29c 0 /* UART3_RXD (IOCFG175) */ + 0x2a0 0 /* UART3_TXD (IOCFG176) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart3_cfg_idle: uart3_cfg_idle { + pinctrl-single,pins = < + 0x294 0 /* UART3_CTS (IOCFG173) */ + 0x298 0 /* UART3_RTS (IOCFG174) */ + 0x29c 0 /* UART3_RXD (IOCFG175) */ + 0x2a0 0 /* UART3_TXD (IOCFG176) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + uart4_cfg_func: uart4_cfg_func { + pinctrl-single,pins = < + 0x2a4 0 /* UART4_CTS (IOCFG177) */ + 0x2a8 0 /* UART4_RTS (IOCFG178) */ + 0x2ac 0 /* UART4_RXD (IOCFG179) */ + 0x2b0 0 /* UART4_TXD (IOCFG180) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + i2c0_cfg_func: i2c0_cfg_func { + pinctrl-single,pins = < + 0x17c 0 /* I2C0_SCL (IOCFG103) */ + 0x180 0 /* I2C0_SDA (IOCFG104) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + i2c1_cfg_func: i2c1_cfg_func { + pinctrl-single,pins = < + 0x184 0 /* I2C1_SCL (IOCFG105) */ + 0x188 0 /* I2C1_SDA (IOCFG106) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + i2c2_cfg_func: i2c2_cfg_func { + pinctrl-single,pins = < + 0x118 0 /* I2C2_SCL (IOCFG79) */ + 0x11c 0 /* I2C2_SDA (IOCFG80) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + i2c3_cfg_func: i2c3_cfg_func { + pinctrl-single,pins = < + 0x100 0 /* I2C3_SCL (IOCFG73) */ + 0x104 0 /* I2C3_SDA (IOCFG74) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + spi0_cfg_func1: spi0_cfg_func1 { + pinctrl-single,pins = < + 0x1d4 0 /* SPI0_CLK (IOCFG125) */ + 0x1d8 0 /* SPI0_DI (IOCFG126) */ + 0x1dc 0 /* SPI0_DO (IOCFG127) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + spi0_cfg_func2: spi0_cfg_func2 { + pinctrl-single,pins = < + 0x1e0 0 /* SPI0_CS0 (IOCFG128) */ + 0x1e4 0 /* SPI0_CS1 (IOCFG129) */ + 0x1e8 0 /* SPI0_CS2 (IOCFG130 */ + 0x1ec 0 /* SPI0_CS3 (IOCFG131) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <1 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + spi1_cfg_func1: spi1_cfg_func1 { + pinctrl-single,pins = < + 0x1f0 0 /* SPI1_CLK (IOCFG132) */ + 0x1f4 0 /* SPI1_DI (IOCFG133) */ + 0x1f8 0 /* SPI1_DO (IOCFG134) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + spi1_cfg_func2: spi1_cfg_func2 { + pinctrl-single,pins = < + 0x1fc 0 /* SPI1_CS (IOCFG135) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <1 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + kpc_cfg_func: kpc_cfg_func { + pinctrl-single,pins = < + 0x250 0 /* KEY_IN0 (IOCFG156) */ + 0x254 0 /* KEY_IN1 (IOCFG157) */ + 0x258 0 /* KEY_IN2 (IOCFG158) */ + 0x230 0 /* KEY_OUT0 (IOCFG148) */ + 0x234 0 /* KEY_OUT1 (IOCFG149) */ + 0x238 0 /* KEY_OUT2 (IOCFG150) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + emmc_cfg_func: emmc_cfg_func { + pinctrl-single,pins = < + 0x0ac 0 /* eMMC_CMD (IOCFG40) */ + 0x0b0 0 /* eMMC_CLK (IOCFG41) */ + 0x058 0 /* NAND_CS3_N (IOCFG19) */ + 0x064 0 /* NAND_BUSY2_N (IOCFG22) */ + 0x068 0 /* NAND_BUSY3_N (IOCFG23) */ + 0x08c 0 /* NAND_DATA8 (IOCFG32) */ + 0x090 0 /* NAND_DATA9 (IOCFG33) */ + 0x094 0 /* NAND_DATA10 (IOCFG34) */ + 0x098 0 /* NAND_DATA11 (IOCFG35) */ + 0x09c 0 /* NAND_DATA12 (IOCFG36) */ + 0x0a0 0 /* NAND_DATA13 (IOCFG37) */ + 0x0a4 0 /* NAND_DATA14 (IOCFG38) */ + 0x0a8 0 /* NAND_DATA15 (IOCFG39) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <1 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + sd_cfg_func1: sd_cfg_func1 { + pinctrl-single,pins = < + 0x18c 0 /* SD_CLK (IOCFG107) */ + 0x190 0 /* SD_CMD (IOCFG108) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + sd_cfg_func2: sd_cfg_func2 { + pinctrl-single,pins = < + 0x194 0 /* SD_DATA0 (IOCFG109) */ + 0x198 0 /* SD_DATA1 (IOCFG110) */ + 0x19c 0 /* SD_DATA2 (IOCFG111) */ + 0x1a0 0 /* SD_DATA3 (IOCFG112) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x70 0xf0>; + }; + nand_cfg_func1: nand_cfg_func1 { + pinctrl-single,pins = < + 0x03c 0 /* NAND_ALE (IOCFG12) */ + 0x040 0 /* NAND_CLE (IOCFG13) */ + 0x06c 0 /* NAND_DATA0 (IOCFG24) */ + 0x070 0 /* NAND_DATA1 (IOCFG25) */ + 0x074 0 /* NAND_DATA2 (IOCFG26) */ + 0x078 0 /* NAND_DATA3 (IOCFG27) */ + 0x07c 0 /* NAND_DATA4 (IOCFG28) */ + 0x080 0 /* NAND_DATA5 (IOCFG29) */ + 0x084 0 /* NAND_DATA6 (IOCFG30) */ + 0x088 0 /* NAND_DATA7 (IOCFG31) */ + 0x08c 0 /* NAND_DATA8 (IOCFG32) */ + 0x090 0 /* NAND_DATA9 (IOCFG33) */ + 0x094 0 /* NAND_DATA10 (IOCFG34) */ + 0x098 0 /* NAND_DATA11 (IOCFG35) */ + 0x09c 0 /* NAND_DATA12 (IOCFG36) */ + 0x0a0 0 /* NAND_DATA13 (IOCFG37) */ + 0x0a4 0 /* NAND_DATA14 (IOCFG38) */ + 0x0a8 0 /* NAND_DATA15 (IOCFG39) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + nand_cfg_func2: nand_cfg_func2 { + pinctrl-single,pins = < + 0x044 0 /* NAND_RE_N (IOCFG14) */ + 0x048 0 /* NAND_WE_N (IOCFG15) */ + 0x04c 0 /* NAND_CS0_N (IOCFG16) */ + 0x050 0 /* NAND_CS1_N (IOCFG17) */ + 0x054 0 /* NAND_CS2_N (IOCFG18) */ + 0x058 0 /* NAND_CS3_N (IOCFG19) */ + 0x05c 0 /* NAND_BUSY0_N (IOCFG20) */ + 0x060 0 /* NAND_BUSY1_N (IOCFG21) */ + 0x064 0 /* NAND_BUSY2_N (IOCFG22) */ + 0x068 0 /* NAND_BUSY3_N (IOCFG23) */ + >; + pinctrl-single,bias-pulldown = <0 2 0 2>; + pinctrl-single,bias-pullup = <1 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + sdio_cfg_func: sdio_cfg_func { + pinctrl-single,pins = < + 0x1a4 0 /* SDIO0_CLK (IOCG113) */ + 0x1a8 0 /* SDIO0_CMD (IOCG114) */ + 0x1ac 0 /* SDIO0_DATA0 (IOCG115) */ + 0x1b0 0 /* SDIO0_DATA1 (IOCG116) */ + 0x1b4 0 /* SDIO0_DATA2 (IOCG117) */ + 0x1b8 0 /* SDIO0_DATA3 (IOCG118) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + pinctrl-single,drive-strength = <0x30 0xf0>; + }; + audio_out_cfg_func: audio_out_cfg_func { + pinctrl-single,pins = < + 0x200 0 /* GPIO (IOCFG136) */ + 0x204 0 /* GPIO (IOCFG137) */ + >; + pinctrl-single,bias-pulldown = <2 2 0 2>; + pinctrl-single,bias-pullup = <0 1 0 1>; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + call { + label = "call"; + gpios = <&gpio17 2 0>; + linux,code = <169>; /* KEY_PHONE */ + }; + }; +}; diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi new file mode 100644 index 000000000000..ab1116d086be --- /dev/null +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -0,0 +1,565 @@ +/* + * Hisilicon Ltd. Hi3620 SoC + * + * Copyright (C) 2012-2013 Hisilicon Ltd. + * Copyright (C) 2012-2013 Linaro Ltd. + * + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include "skeleton.dtsi" +#include + +/ { + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + }; + + pclk: clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <26000000>; + clock-output-names = "apb_pclk"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0x0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <1>; + next-level-cache = <&L2>; + }; + + cpu@2 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <2>; + next-level-cache = <&L2>; + }; + + cpu@3 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <3>; + next-level-cache = <&L2>; + }; + }; + + amba { + + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus"; + interrupt-parent = <&gic>; + ranges = <0 0xfc000000 0x2000000>; + + L2: l2-cache { + compatible = "arm,pl310-cache"; + reg = <0xfc10000 0x100000>; + interrupts = <0 15 4>; + cache-unified; + cache-level = <2>; + }; + + gic: interrupt-controller@1000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + /* gic dist base, gic cpu base */ + reg = <0x1000 0x1000>, <0x100 0x100>; + }; + + sysctrl: system-controller@802000 { + compatible = "hisilicon,sysctrl"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x802000 0x1000>; + reg = <0x802000 0x1000>; + + smp-offset = <0x31c>; + resume-offset = <0x308>; + reboot-offset = <0x4>; + + clock: clock@0 { + compatible = "hisilicon,hi3620-clock"; + reg = <0 0x10000>; + #clock-cells = <1>; + }; + }; + + dual_timer0: dual_timer@800000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x800000 0x1000>; + /* timer00 & timer01 */ + interrupts = <0 0 4>, <0 1 4>; + clocks = <&clock HI3620_TIMER0_MUX>, <&clock HI3620_TIMER1_MUX>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + dual_timer1: dual_timer@801000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x801000 0x1000>; + /* timer10 & timer11 */ + interrupts = <0 2 4>, <0 3 4>; + clocks = <&clock HI3620_TIMER2_MUX>, <&clock HI3620_TIMER3_MUX>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + dual_timer2: dual_timer@a01000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0xa01000 0x1000>; + /* timer20 & timer21 */ + interrupts = <0 4 4>, <0 5 4>; + clocks = <&clock HI3620_TIMER4_MUX>, <&clock HI3620_TIMER5_MUX>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + dual_timer3: dual_timer@a02000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0xa02000 0x1000>; + /* timer30 & timer31 */ + interrupts = <0 6 4>, <0 7 4>; + clocks = <&clock HI3620_TIMER6_MUX>, <&clock HI3620_TIMER7_MUX>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + dual_timer4: dual_timer@a03000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0xa03000 0x1000>; + /* timer40 & timer41 */ + interrupts = <0 96 4>, <0 97 4>; + clocks = <&clock HI3620_TIMER8_MUX>, <&clock HI3620_TIMER9_MUX>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + timer5: timer@600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x600 0x20>; + interrupts = <1 13 0xf01>; + }; + + uart0: uart@b00000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xb00000 0x1000>; + interrupts = <0 20 4>; + clocks = <&clock HI3620_UARTCLK0>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + uart1: uart@b01000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xb01000 0x1000>; + interrupts = <0 21 4>; + clocks = <&clock HI3620_UARTCLK1>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + uart2: uart@b02000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xb02000 0x1000>; + interrupts = <0 22 4>; + clocks = <&clock HI3620_UARTCLK2>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + uart3: uart@b03000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xb03000 0x1000>; + interrupts = <0 23 4>; + clocks = <&clock HI3620_UARTCLK3>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + uart4: uart@b04000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xb04000 0x1000>; + interrupts = <0 24 4>; + clocks = <&clock HI3620_UARTCLK4>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + gpio0: gpio@806000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x806000 0x1000>; + interrupts = <0 64 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 2 0 1 &pmx0 3 0 1 &pmx0 4 0 1 + &pmx0 5 0 1 &pmx0 6 1 1 &pmx0 7 2 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK0>; + clock-names = "apb_pclk"; + }; + + gpio1: gpio@807000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x807000 0x1000>; + interrupts = <0 65 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1 + &pmx0 3 3 1 &pmx0 4 3 1 &pmx0 5 4 1 + &pmx0 6 5 1 &pmx0 7 6 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK1>; + clock-names = "apb_pclk"; + }; + + gpio2: gpio@808000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x808000 0x1000>; + interrupts = <0 66 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 7 1 &pmx0 1 8 1 &pmx0 2 9 1 + &pmx0 3 10 1 &pmx0 4 3 1 &pmx0 5 3 1 + &pmx0 6 3 1 &pmx0 7 3 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK2>; + clock-names = "apb_pclk"; + }; + + gpio3: gpio@809000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x809000 0x1000>; + interrupts = <0 67 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 3 1 &pmx0 1 3 1 &pmx0 2 3 1 + &pmx0 3 3 1 &pmx0 4 11 1 &pmx0 5 11 1 + &pmx0 6 11 1 &pmx0 7 11 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK3>; + clock-names = "apb_pclk"; + }; + + gpio4: gpio@80a000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x80a000 0x1000>; + interrupts = <0 68 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 11 1 &pmx0 1 11 1 &pmx0 2 11 1 + &pmx0 3 11 1 &pmx0 4 12 1 &pmx0 5 12 1 + &pmx0 6 13 1 &pmx0 7 13 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK4>; + clock-names = "apb_pclk"; + }; + + gpio5: gpio@80b000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x80b000 0x1000>; + interrupts = <0 69 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 14 1 &pmx0 1 15 1 &pmx0 2 16 1 + &pmx0 3 16 1 &pmx0 4 16 1 &pmx0 5 16 1 + &pmx0 6 16 1 &pmx0 7 16 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK5>; + clock-names = "apb_pclk"; + }; + + gpio6: gpio@80c000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x80c000 0x1000>; + interrupts = <0 70 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 16 1 &pmx0 1 16 1 &pmx0 2 17 1 + &pmx0 3 17 1 &pmx0 4 18 1 &pmx0 5 18 1 + &pmx0 6 18 1 &pmx0 7 19 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK6>; + clock-names = "apb_pclk"; + }; + + gpio7: gpio@80d000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x80d000 0x1000>; + interrupts = <0 71 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 19 1 &pmx0 1 20 1 &pmx0 2 21 1 + &pmx0 3 22 1 &pmx0 4 23 1 &pmx0 5 24 1 + &pmx0 6 25 1 &pmx0 7 26 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK7>; + clock-names = "apb_pclk"; + }; + + gpio8: gpio@80e000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x80e000 0x1000>; + interrupts = <0 72 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 27 1 &pmx0 1 28 1 &pmx0 2 29 1 + &pmx0 3 30 1 &pmx0 4 31 1 &pmx0 5 32 1 + &pmx0 6 33 1 &pmx0 7 34 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK8>; + clock-names = "apb_pclk"; + }; + + gpio9: gpio@80f000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x80f000 0x1000>; + interrupts = <0 73 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 35 1 &pmx0 1 36 1 &pmx0 2 37 1 + &pmx0 3 38 1 &pmx0 4 39 1 &pmx0 5 40 1 + &pmx0 6 41 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK9>; + clock-names = "apb_pclk"; + }; + + gpio10: gpio@810000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x810000 0x1000>; + interrupts = <0 74 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 2 43 1 &pmx0 3 44 1 &pmx0 4 45 1 + &pmx0 5 45 1 &pmx0 6 46 1 &pmx0 7 46 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK10>; + clock-names = "apb_pclk"; + }; + + gpio11: gpio@811000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x811000 0x1000>; + interrupts = <0 75 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 47 1 &pmx0 1 47 1 &pmx0 2 47 1 + &pmx0 3 47 1 &pmx0 4 47 1 &pmx0 5 48 1 + &pmx0 6 49 1 &pmx0 7 49 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK11>; + clock-names = "apb_pclk"; + }; + + gpio12: gpio@812000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x812000 0x1000>; + interrupts = <0 76 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 49 1 &pmx0 1 50 1 &pmx0 2 49 1 + &pmx0 3 49 1 &pmx0 4 51 1 &pmx0 5 51 1 + &pmx0 6 51 1 &pmx0 7 52 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK12>; + clock-names = "apb_pclk"; + }; + + gpio13: gpio@813000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x813000 0x1000>; + interrupts = <0 77 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 51 1 &pmx0 1 51 1 &pmx0 2 53 1 + &pmx0 3 53 1 &pmx0 4 53 1 &pmx0 5 54 1 + &pmx0 6 55 1 &pmx0 7 56 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK13>; + clock-names = "apb_pclk"; + }; + + gpio14: gpio@814000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x814000 0x1000>; + interrupts = <0 78 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 57 1 &pmx0 1 97 1 &pmx0 2 97 1 + &pmx0 3 58 1 &pmx0 4 59 1 &pmx0 5 60 1 + &pmx0 6 60 1 &pmx0 7 61 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK14>; + clock-names = "apb_pclk"; + }; + + gpio15: gpio@815000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x815000 0x1000>; + interrupts = <0 79 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 61 1 &pmx0 1 62 1 &pmx0 2 62 1 + &pmx0 3 63 1 &pmx0 4 63 1 &pmx0 5 64 1 + &pmx0 6 64 1 &pmx0 7 65 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK15>; + clock-names = "apb_pclk"; + }; + + gpio16: gpio@816000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x816000 0x1000>; + interrupts = <0 80 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 66 1 &pmx0 1 67 1 &pmx0 2 68 1 + &pmx0 3 69 1 &pmx0 4 70 1 &pmx0 5 71 1 + &pmx0 6 72 1 &pmx0 7 73 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK16>; + clock-names = "apb_pclk"; + }; + + gpio17: gpio@817000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x817000 0x1000>; + interrupts = <0 81 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 74 1 &pmx0 1 75 1 &pmx0 2 76 1 + &pmx0 3 77 1 &pmx0 4 78 1 &pmx0 5 79 1 + &pmx0 6 80 1 &pmx0 7 81 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK17>; + clock-names = "apb_pclk"; + }; + + gpio18: gpio@818000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x818000 0x1000>; + interrupts = <0 82 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 82 1 &pmx0 1 83 1 &pmx0 2 83 1 + &pmx0 3 84 1 &pmx0 4 84 1 &pmx0 5 85 1 + &pmx0 6 86 1 &pmx0 7 87 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK18>; + clock-names = "apb_pclk"; + }; + + gpio19: gpio@819000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x819000 0x1000>; + interrupts = <0 83 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 87 1 &pmx0 1 87 1 &pmx0 2 88 1 + &pmx0 3 88 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK19>; + clock-names = "apb_pclk"; + }; + + gpio20: gpio@81a000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x81a000 0x1000>; + interrupts = <0 84 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 0 89 1 &pmx0 1 89 1 &pmx0 2 90 1 + &pmx0 3 90 1 &pmx0 4 91 1 &pmx0 5 92 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK20>; + clock-names = "apb_pclk"; + }; + + gpio21: gpio@81b000 { + compatible = "arm,pl061", "arm,primecell"; + reg = <0x81b000 0x1000>; + interrupts = <0 85 0x4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = < &pmx0 3 94 1 &pmx0 7 96 1>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&clock HI3620_GPIOCLK21>; + clock-names = "apb_pclk"; + }; + + pmx0: pinmux@803000 { + compatible = "pinctrl-single"; + reg = <0x803000 0x188>; + #address-cells = <1>; + #size-cells = <1>; + #gpio-range-cells = <3>; + ranges; + + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <7>; + /* pin base, nr pins & gpio function */ + pinctrl-single,gpio-range = <&range 0 3 0 &range 3 9 1 + &range 12 1 0 &range 13 29 1 + &range 43 1 0 &range 44 49 1 + &range 94 1 1 &range 96 2 1>; + + range: gpio-range { + #pinctrl-single,gpio-range-cells = <3>; + }; + }; + + pmx1: pinmux@803800 { + compatible = "pinconf-single"; + reg = <0x803800 0x2dc>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pinctrl-single,register-width = <32>; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi index c96ceaef7ddf..581b75433be6 100644 --- a/arch/arm/boot/dts/imx23.dtsi +++ b/arch/arm/boot/dts/imx23.dtsi @@ -337,8 +337,10 @@ }; dcp@80028000 { + compatible = "fsl,imx23-dcp"; reg = <0x80028000 0x2000>; - status = "disabled"; + interrupts = <53 54>; + status = "okay"; }; pxp@8002a000 { diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index cda19c8b0a47..f8e9b20f6982 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -813,9 +813,10 @@ }; dcp: dcp@80028000 { + compatible = "fsl,imx28-dcp", "fsl,imx23-dcp"; reg = <0x80028000 0x2000>; interrupts = <52 53 54>; - compatible = "fsl-dcp"; + status = "okay"; }; pxp: pxp@8002a000 { diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi index 0f06f8687b0b..88e3d477bf16 100644 --- a/arch/arm/boot/dts/integrator.dtsi +++ b/arch/arm/boot/dts/integrator.dtsi @@ -10,6 +10,11 @@ reg = <0x10000000 0x200>; }; + ebi@12000000 { + compatible = "arm,external-bus-interface"; + reg = <0x12000000 0x100>; + }; + timer@13000000 { reg = <0x13000000 0x100>; interrupt-parent = <&pic>; diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index 7deb3a3182b4..a21c17de9a5e 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts @@ -47,8 +47,11 @@ valid-mask = <0x00000007>; }; + /* The SIC is cascaded off IRQ 26 on the PIC */ sic: sic@ca000000 { compatible = "arm,versatile-fpga-irq"; + interrupt-parent = <&pic>; + interrupts = <26>; #interrupt-cells = <1>; interrupt-controller; reg = <0xca000000 0x100>; diff --git a/arch/arm/boot/dts/k2hk-evm.dts b/arch/arm/boot/dts/k2hk-evm.dts new file mode 100644 index 000000000000..eaefdfef65c3 --- /dev/null +++ b/arch/arm/boot/dts/k2hk-evm.dts @@ -0,0 +1,63 @@ +/* + * Copyright 2013 Texas Instruments, Inc. + * + * Keystone 2 Kepler/Hawking EVM device tree + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "keystone.dtsi" + +/ { + compatible = "ti,keystone-evm"; + + soc { + clock { + refclksys: refclksys { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <122880000>; + clock-output-names = "refclk-sys"; + }; + + refclkpass: refclkpass { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <122880000>; + clock-output-names = "refclk-pass"; + }; + + refclkarm: refclkarm { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "refclk-arm"; + }; + + refclkddr3a: refclkddr3a { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + clock-output-names = "refclk-ddr3a"; + }; + + refclkddr3b: refclkddr3b { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <100000000>; + clock-output-names = "refclk-ddr3b"; + }; + }; + }; +}; + +&usb_phy { + status = "okay"; +}; + +&usb { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi index d6713b113258..2363593e1050 100644 --- a/arch/arm/boot/dts/keystone-clocks.dtsi +++ b/arch/arm/boot/dts/keystone-clocks.dtsi @@ -13,17 +13,10 @@ clocks { #size-cells = <1>; ranges; - refclkmain: refclkmain { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <122880000>; - clock-output-names = "refclk-main"; - }; - mainpllclk: mainpllclk@2310110 { #clock-cells = <0>; compatible = "ti,keystone,main-pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclksys>; reg = <0x02620350 4>, <0x02310110 4>; reg-names = "control", "multiplier"; fixed-postdiv = <2>; @@ -32,47 +25,43 @@ clocks { papllclk: papllclk@2620358 { #clock-cells = <0>; compatible = "ti,keystone,pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclkpass>; clock-output-names = "pa-pll-clk"; reg = <0x02620358 4>; reg-names = "control"; - fixed-postdiv = <6>; }; - ddr3allclk: ddr3apllclk@2620360 { + ddr3apllclk: ddr3apllclk@2620360 { #clock-cells = <0>; compatible = "ti,keystone,pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclkddr3a>; clock-output-names = "ddr-3a-pll-clk"; reg = <0x02620360 4>; reg-names = "control"; - fixed-postdiv = <6>; }; - ddr3bllclk: ddr3bpllclk@2620368 { + ddr3bpllclk: ddr3bpllclk@2620368 { #clock-cells = <0>; compatible = "ti,keystone,pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclkddr3b>; clock-output-names = "ddr-3b-pll-clk"; reg = <0x02620368 4>; reg-names = "control"; - fixed-postdiv = <6>; }; armpllclk: armpllclk@2620370 { #clock-cells = <0>; compatible = "ti,keystone,pll-clock"; - clocks = <&refclkmain>; + clocks = <&refclkarm>; clock-output-names = "arm-pll-clk"; reg = <0x02620370 4>; reg-names = "control"; - fixed-postdiv = <6>; }; mainmuxclk: mainmuxclk@2310108 { #clock-cells = <0>; compatible = "ti,keystone,pll-mux-clock"; - clocks = <&mainpllclk>, <&refclkmain>; + clocks = <&mainpllclk>, <&refclksys>; reg = <0x02310108 4>; bit-shift = <23>; bit-mask = <1>; @@ -135,6 +124,15 @@ clocks { clock-output-names = "chipclk13"; }; + paclk13: paclk13 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&papllclk>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "paclk13"; + }; + chipclk14: chipclk14 { #clock-cells = <0>; compatible = "fixed-factor-clock"; diff --git a/arch/arm/boot/dts/keystone.dts b/arch/arm/boot/dts/keystone.dtsi similarity index 82% rename from arch/arm/boot/dts/keystone.dts rename to arch/arm/boot/dts/keystone.dtsi index 100bdf52b847..b4202907a27b 100644 --- a/arch/arm/boot/dts/keystone.dts +++ b/arch/arm/boot/dts/keystone.dtsi @@ -6,14 +6,12 @@ * published by the Free Software Foundation. */ -/dts-v1/; #include #include "skeleton.dtsi" / { model = "Texas Instruments Keystone 2 SoC"; - compatible = "ti,keystone-evm"; #address-cells = <2>; #size-cells = <2>; interrupt-parent = <&gic>; @@ -64,7 +62,11 @@ #address-cells = <1>; interrupt-controller; reg = <0x0 0x02561000 0x0 0x1000>, - <0x0 0x02562000 0x0 0x2000>; + <0x0 0x02562000 0x0 0x2000>, + <0x0 0x02564000 0x0 0x1000>, + <0x0 0x02566000 0x0 0x2000>; + interrupts = ; }; timer { @@ -179,5 +181,32 @@ interrupts = ; clocks = <&clkspi>; }; + + usb_phy: usb_phy@2620738 { + compatible = "ti,keystone-usbphy"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2620738 32>; + status = "disabled"; + }; + + usb: usb@2680000 { + compatible = "ti,keystone-dwc3"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2680000 0x10000>; + clocks = <&clkusb>; + clock-names = "usb"; + interrupts = ; + ranges; + status = "disabled"; + + dwc3@2690000 { + compatible = "synopsys,dwc3"; + reg = <0x2690000 0x70000>; + interrupts = ; + usb-phy = <&usb_phy>, <&usb_phy>; + }; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-6192.dtsi b/arch/arm/boot/dts/kirkwood-6192.dtsi new file mode 100644 index 000000000000..3916937d6818 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-6192.dtsi @@ -0,0 +1,107 @@ +/ { + mbus { + pcie-controller { + compatible = "marvell,kirkwood-pcie"; + status = "disabled"; + device_type = "pci"; + + #address-cells = <3>; + #size-cells = <2>; + + bus-range = <0x00 0xff>; + + ranges = + <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 + 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */ + 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>; + + pcie@1,0 { + device_type = "pci"; + assigned-addresses = <0x82000800 0 0x00040000 0 0x2000>; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 + 0x81000000 0 0 0x81000000 0x1 0 1 0>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &intc 9>; + marvell,pcie-port = <0>; + marvell,pcie-lane = <0>; + clocks = <&gate_clk 2>; + status = "disabled"; + }; + }; + }; + + ocp@f1000000 { + pinctrl: pinctrl@10000 { + compatible = "marvell,88f6192-pinctrl"; + reg = <0x10000 0x20>; + + pmx_nand: pmx-nand { + marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3", + "mpp4", "mpp5", "mpp18", + "mpp19"; + marvell,function = "nand"; + }; + pmx_sata0: pmx-sata0 { + marvell,pins = "mpp5", "mpp21", "mpp23"; + marvell,function = "sata0"; + }; + pmx_sata1: pmx-sata1 { + marvell,pins = "mpp4", "mpp20", "mpp22"; + marvell,function = "sata1"; + }; + pmx_spi: pmx-spi { + marvell,pins = "mpp0", "mpp1", "mpp2", "mpp3"; + marvell,function = "spi"; + }; + pmx_twsi0: pmx-twsi0 { + marvell,pins = "mpp8", "mpp9"; + marvell,function = "twsi0"; + }; + pmx_uart0: pmx-uart0 { + marvell,pins = "mpp10", "mpp11"; + marvell,function = "uart0"; + }; + pmx_uart1: pmx-uart1 { + marvell,pins = "mpp13", "mpp14"; + marvell,function = "uart1"; + }; + pmx_sdio: pmx-sdio { + marvell,pins = "mpp12", "mpp13", "mpp14", + "mpp15", "mpp16", "mpp17"; + marvell,function = "sdio"; + }; + }; + + rtc@10300 { + compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc"; + reg = <0x10300 0x20>; + interrupts = <53>; + clocks = <&gate_clk 7>; + }; + + sata@80000 { + compatible = "marvell,orion-sata"; + reg = <0x80000 0x5000>; + interrupts = <21>; + clocks = <&gate_clk 14>, <&gate_clk 15>; + clock-names = "0", "1"; + status = "disabled"; + }; + + mvsdio@90000 { + compatible = "marvell,orion-sdio"; + reg = <0x90000 0x200>; + interrupts = <28>; + clocks = <&gate_clk 4>; + bus-width = <4>; + cap-sdio-irq; + cap-sd-highspeed; + cap-mmc-highspeed; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-6281.dtsi b/arch/arm/boot/dts/kirkwood-6281.dtsi index 650ef30e1856..416d96e1302f 100644 --- a/arch/arm/boot/dts/kirkwood-6281.dtsi +++ b/arch/arm/boot/dts/kirkwood-6281.dtsi @@ -89,6 +89,8 @@ interrupts = <21>; clocks = <&gate_clk 14>, <&gate_clk 15>; clock-names = "0", "1"; + phys = <&sata_phy0>, <&sata_phy1>; + phy-names = "port0", "port1"; status = "disabled"; }; @@ -97,6 +99,8 @@ reg = <0x90000 0x200>; interrupts = <28>; clocks = <&gate_clk 4>; + pinctrl-0 = <&pmx_sdio>; + pinctrl-names = "default"; bus-width = <4>; cap-sdio-irq; cap-sd-highspeed; diff --git a/arch/arm/boot/dts/kirkwood-6282.dtsi b/arch/arm/boot/dts/kirkwood-6282.dtsi index 3933a331ddc2..2902e0d7971d 100644 --- a/arch/arm/boot/dts/kirkwood-6282.dtsi +++ b/arch/arm/boot/dts/kirkwood-6282.dtsi @@ -104,6 +104,12 @@ }; }; + thermal@10078 { + compatible = "marvell,kirkwood-thermal"; + reg = <0x10078 0x4>; + status = "okay"; + }; + rtc@10300 { compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc"; reg = <0x10300 0x20>; @@ -111,33 +117,6 @@ clocks = <&gate_clk 7>; }; - sata@80000 { - compatible = "marvell,orion-sata"; - reg = <0x80000 0x5000>; - interrupts = <21>; - clocks = <&gate_clk 14>, <&gate_clk 15>; - clock-names = "0", "1"; - status = "disabled"; - }; - - mvsdio@90000 { - compatible = "marvell,orion-sdio"; - reg = <0x90000 0x200>; - interrupts = <28>; - clocks = <&gate_clk 4>; - bus-width = <4>; - cap-sdio-irq; - cap-sd-highspeed; - cap-mmc-highspeed; - status = "disabled"; - }; - - thermal@10078 { - compatible = "marvell,kirkwood-thermal"; - reg = <0x10078 0x4>; - status = "okay"; - }; - i2c@11100 { compatible = "marvell,mv64xxx-i2c"; reg = <0x11100 0x20>; @@ -149,5 +128,29 @@ status = "disabled"; }; + sata@80000 { + compatible = "marvell,orion-sata"; + reg = <0x80000 0x5000>; + interrupts = <21>; + clocks = <&gate_clk 14>, <&gate_clk 15>; + clock-names = "0", "1"; + phys = <&sata_phy0>, <&sata_phy1>; + phy-names = "port0", "port1"; + status = "disabled"; + }; + + mvsdio@90000 { + compatible = "marvell,orion-sdio"; + reg = <0x90000 0x200>; + interrupts = <28>; + clocks = <&gate_clk 4>; + pinctrl-0 = <&pmx_sdio>; + pinctrl-names = "default"; + bus-width = <4>; + cap-sdio-irq; + cap-sd-highspeed; + cap-mmc-highspeed; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-cloudbox.dts b/arch/arm/boot/dts/kirkwood-cloudbox.dts index 142b9cd3b454..0e06fd3cee4d 100644 --- a/arch/arm/boot/dts/kirkwood-cloudbox.dts +++ b/arch/arm/boot/dts/kirkwood-cloudbox.dts @@ -66,8 +66,8 @@ button@1 { label = "Power push button"; - linux,code = <116>; - gpios = <&gpio0 16 1>; + linux,code = ; + gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; }; }; @@ -76,17 +76,17 @@ red-fail { label = "cloudbox:red:fail"; - gpios = <&gpio0 14 0>; + gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; }; blue-sata { label = "cloudbox:blue:sata"; - gpios = <&gpio0 15 0>; + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; }; }; gpio_poweroff { compatible = "gpio-poweroff"; - gpios = <&gpio0 17 0>; + gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; }; }; @@ -94,7 +94,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-db.dtsi b/arch/arm/boot/dts/kirkwood-db.dtsi index 053aa20fb30f..02d1225ef99f 100644 --- a/arch/arm/boot/dts/kirkwood-db.dtsi +++ b/arch/arm/boot/dts/kirkwood-db.dtsi @@ -51,8 +51,8 @@ mvsdio@90000 { pinctrl-0 = <&pmx_sdio_gpios>; pinctrl-names = "default"; - wp-gpios = <&gpio1 5 0>; - cd-gpios = <&gpio1 6 0>; + wp-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + cd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; status = "okay"; }; }; @@ -84,7 +84,6 @@ status = "okay"; ethphy0: ethernet-phy@8 { - device_type = "ethernet-phy"; reg = <8>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts index e112ca62d978..bf7fe8ab88f4 100644 --- a/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/arch/arm/boot/dts/kirkwood-dns320.dts @@ -24,24 +24,24 @@ blue-power { label = "dns320:blue:power"; - gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ - linux,default-trigger = "default-on"; + gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; blue-usb { label = "dns320:blue:usb"; - gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; orange-l_hdd { label = "dns320:orange:l_hdd"; - gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; }; orange-r_hdd { label = "dns320:orange:r_hdd"; - gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ + gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; }; orange-usb { label = "dns320:orange:usb"; - gpios = <&gpio1 3 1>; /* GPIO 35 Active Low */ + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; /* GPIO 35 */ }; }; diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts index 5119fb8a8eb6..cb9978c652f2 100644 --- a/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/arch/arm/boot/dts/kirkwood-dns325.dts @@ -24,24 +24,24 @@ white-power { label = "dns325:white:power"; - gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ - linux,default-trigger = "default-on"; + gpios = <&gpio0 26 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; white-usb { label = "dns325:white:usb"; - gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO 43 */ }; red-l_hdd { label = "dns325:red:l_hdd"; - gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; }; red-r_hdd { label = "dns325:red:r_hdd"; - gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ + gpios = <&gpio0 27 GPIO_ACTIVE_LOW>; }; red-usb { label = "dns325:red:usb"; - gpios = <&gpio0 29 1>; /* GPIO 29 Active Low */ + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi index aefa375a550d..d5aa9564a287 100644 --- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi +++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi @@ -15,18 +15,18 @@ button@1 { label = "Power button"; - linux,code = <116>; - gpios = <&gpio1 2 1>; + linux,code = ; + gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; }; button@2 { label = "USB unmount button"; - linux,code = <161>; - gpios = <&gpio1 15 1>; + linux,code = ; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; button@3 { label = "Reset button"; - linux,code = <0x198>; - gpios = <&gpio1 16 1>; + linux,code = ; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; }; }; @@ -35,8 +35,8 @@ compatible = "gpio-fan"; pinctrl-0 = <&pmx_fan_high_speed &pmx_fan_low_speed>; pinctrl-names = "default"; - gpios = <&gpio1 14 1 - &gpio1 13 1>; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW + &gpio1 13 GPIO_ACTIVE_LOW>; gpio-fan,speed-map = <0 0 3000 1 6000 2>; @@ -46,7 +46,7 @@ compatible = "gpio-poweroff"; pinctrl-0 = <&pmx_power_off>; pinctrl-names = "default"; - gpios = <&gpio1 4 0>; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; }; ocp@f1000000 { @@ -224,7 +224,6 @@ status = "okay"; ethphy0: ethernet-phy@8 { - device_type = "ethernet-phy"; reg = <8>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts index 33ff368fbfa5..f31312ebd0d6 100644 --- a/arch/arm/boot/dts/kirkwood-dockstar.dts +++ b/arch/arm/boot/dts/kirkwood-dockstar.dts @@ -42,12 +42,12 @@ health { label = "status:green:health"; - gpios = <&gpio1 14 1>; - linux,default-trigger = "default-on"; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; fault { label = "status:orange:fault"; - gpios = <&gpio1 15 1>; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; }; regulators { @@ -95,7 +95,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; compatible = "marvell,88e1116"; reg = <0>; }; diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index 6f62af99c9cb..ef3463e0ae19 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -87,15 +87,15 @@ bluetooth { label = "dreamplug:blue:bluetooth"; - gpios = <&gpio1 15 1>; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; wifi { label = "dreamplug:green:wifi"; - gpios = <&gpio1 16 1>; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; }; wifi-ap { label = "dreamplug:green:wifi_ap"; - gpios = <&gpio1 17 1>; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; }; }; @@ -104,12 +104,10 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; ethphy1: ethernet-phy@1 { - device_type = "ethernet-phy"; reg = <1>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts index a43bebb25110..eb9329420107 100644 --- a/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -85,44 +85,44 @@ health { label = "status:green:health"; - gpios = <&gpio1 14 1>; - linux,default-trigger = "default-on"; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; fault { label = "status:orange:fault"; - gpios = <&gpio1 15 1>; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; left0 { label = "status:white:left0"; - gpios = <&gpio1 10 0>; + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; }; left1 { label = "status:white:left1"; - gpios = <&gpio1 11 0>; + gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; }; left2 { label = "status:white:left2"; - gpios = <&gpio1 12 0>; + gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; }; left3 { label = "status:white:left3"; - gpios = <&gpio1 13 0>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; right0 { label = "status:white:right0"; - gpios = <&gpio1 6 0>; + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; }; right1 { label = "status:white:right1"; - gpios = <&gpio1 7 0>; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; }; right2 { label = "status:white:right2"; - gpios = <&gpio1 8 0>; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; right3 { label = "status:white:right3"; - gpios = <&gpio1 9 0>; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; }; }; regulators { @@ -141,7 +141,7 @@ enable-active-high; regulator-always-on; regulator-boot-on; - gpio = <&gpio0 29 0>; + gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; }; }; }; @@ -176,7 +176,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts index d30a91a5047d..2d51fce74a5a 100644 --- a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts +++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts @@ -45,10 +45,10 @@ nr-ports = <1>; }; + /* AzureWave AW-GH381 WiFi/BT */ mvsdio@90000 { status = "okay"; - /* No CD or WP GPIOs */ - broken-cd; + non-removable; }; }; @@ -60,19 +60,19 @@ health-r { label = "guruplug:red:health"; - gpios = <&gpio1 14 1>; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; }; health-g { label = "guruplug:green:health"; - gpios = <&gpio1 15 1>; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; wmode-r { label = "guruplug:red:wmode"; - gpios = <&gpio1 16 1>; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; }; wmode-g { label = "guruplug:green:wmode"; - gpios = <&gpio1 17 1>; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; }; }; @@ -101,13 +101,11 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; compatible = "marvell,88e1121"; reg = <0>; }; ethphy1: ethernet-phy@1 { - device_type = "ethernet-phy"; compatible = "marvell,88e1121"; reg = <1>; }; diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index c5fb02f7ebc3..a1add3f215e3 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts @@ -63,13 +63,13 @@ button@1 { label = "USB Copy"; - linux,code = <133>; - gpios = <&gpio0 29 1>; + linux,code = ; + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; }; button@2 { label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio0 28 1>; + linux,code = ; + gpios = <&gpio0 28 GPIO_ACTIVE_LOW>; }; }; @@ -81,16 +81,16 @@ green-os { label = "ib62x0:green:os"; - gpios = <&gpio0 25 0>; - linux,default-trigger = "default-on"; + gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; + default-state = "keep"; }; red-os { label = "ib62x0:red:os"; - gpios = <&gpio0 22 0>; + gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>; }; usb-copy { label = "ib62x0:red:usb_copy"; - gpios = <&gpio0 27 0>; + gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; }; }; @@ -98,7 +98,7 @@ compatible = "gpio-poweroff"; pinctrl-0 = <&pmx_power_off>; pinctrl-names = "default"; - gpios = <&gpio0 24 0>; + gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; }; }; @@ -133,7 +133,6 @@ status = "okay"; ethphy0: ethernet-phy@8 { - device_type = "ethernet-phy"; reg = <8>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 4a62b206f680..8d8c80e3656d 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -94,37 +94,37 @@ led-level { label = "led_level"; - gpios = <&gpio1 9 0>; - linux,default-trigger = "default-on"; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + default-state = "on"; }; power-blue { label = "power:blue"; - gpios = <&gpio1 10 0>; - linux,default-trigger = "timer"; + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + default-state = "keep"; }; power-red { label = "power:red"; - gpios = <&gpio1 11 0>; + gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; }; usb1 { label = "usb1:blue"; - gpios = <&gpio1 12 0>; + gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; }; usb2 { label = "usb2:blue"; - gpios = <&gpio1 13 0>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; usb3 { label = "usb3:blue"; - gpios = <&gpio1 14 0>; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; }; usb4 { label = "usb4:blue"; - gpios = <&gpio1 15 0>; + gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; }; otb { label = "otb:blue"; - gpios = <&gpio1 16 0>; + gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; }; }; @@ -137,14 +137,14 @@ button@1 { label = "OTB Button"; - linux,code = <133>; - gpios = <&gpio1 3 1>; + linux,code = ; + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; debounce-interval = <100>; }; button@2 { label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio0 12 1>; + linux,code = ; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; debounce-interval = <100>; }; }; @@ -183,7 +183,6 @@ status = "okay"; ethphy0: ethernet-phy@11 { - device_type = "ethernet-phy"; reg = <11>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index d15395d671ed..59e7a5adeedb 100644 --- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts @@ -127,20 +127,20 @@ power_led { label = "status:white:power_led"; - gpios = <&gpio0 16 0>; - linux,default-trigger = "default-on"; + gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; + default-state = "keep"; }; rebuild_led { label = "status:white:rebuild_led"; - gpios = <&gpio1 4 0>; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; }; health_led { label = "status:red:health_led"; - gpios = <&gpio1 5 0>; + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; }; backup_led { label = "status:blue:backup_led"; - gpios = <&gpio0 15 0>; + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; }; }; gpio-keys { @@ -154,18 +154,18 @@ Power { label = "Power Button"; - linux,code = <116>; - gpios = <&gpio0 14 1>; + linux,code = ; + gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; }; Reset { label = "Reset Button"; - linux,code = <0x198>; - gpios = <&gpio0 12 1>; + linux,code = ; + gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; }; OTB { label = "OTB Button"; - linux,code = <133>; - gpios = <&gpio1 3 1>; + linux,code = ; + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; }; }; }; @@ -200,7 +200,6 @@ status = "okay"; ethphy1: ethernet-phy@11 { - device_type = "ethernet-phy"; reg = <11>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts index cd44f37e54b5..04a1e44541b3 100644 --- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts +++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts @@ -38,8 +38,8 @@ i2c@0 { compatible = "i2c-gpio"; - gpios = < &gpio0 8 0 /* sda */ - &gpio0 9 0 >; /* scl */ + gpios = < &gpio0 8 GPIO_ACTIVE_HIGH /* sda */ + &gpio0 9 GPIO_ACTIVE_HIGH>; /* scl */ i2c-gpio,delay-us = <2>; /* ~100 kHz */ }; }; @@ -55,7 +55,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-laplug.dts b/arch/arm/boot/dts/kirkwood-laplug.dts new file mode 100644 index 000000000000..c9e82eff9bf2 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-laplug.dts @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2013 Maxime Hadjinlian + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/dts-v1/; + +#include +#include +#include "kirkwood.dtsi" +#include "kirkwood-6192.dtsi" + +/ { + model = "LaCie LaPlug"; + compatible = "lacie,laplug", "marvell,kirkwood-88f6192", "marvell,kirkwood"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x8000000>; /* 128 MB */ + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + }; + + mbus { + pcie-controller { + status = "okay"; + pcie@1,0 { + status = "okay"; + }; + }; + }; + + ocp@f1000000 { + serial@12000 { + pinctrl-0 = <&pmx_uart0>; + pinctrl-names = "default"; + status = "okay"; + }; + + i2c@11000 { + pinctrl-0 = <&pmx_twsi0>; + pinctrl-names = "default"; + status = "okay"; + + eeprom@50 { + compatible = "at,24c04"; + pagesize = <16>; + reg = <0x50>; + }; + }; + + pinctrl: pinctrl@10000 { + pmx_usb_power_enable: pmx-usb-power-enable { + marvell,pins = "mpp14"; + marvell,function = "gpio"; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + button@1{ + label = "Power push button"; + linux,code = ; + gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + red-fail { + label = "laplug_v2:red:power"; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + }; + blue-power { + label = "laplug_v2:blue:power"; + gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + }; + }; + + gpio_poweroff { + compatible = "gpio-poweroff"; + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_usb_power_enable>; + pinctrl-names = "default"; + + usb_power_back1: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power Back 1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 15 GPIO_ACTIVE_HIGH>; + }; + + usb_power_back2: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "USB Power Back 2"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; + + usb_power_front: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "USB Power Front"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&nand { + /* Total size : 512MB */ + status = "okay"; + pinctrl-0 = <&pmx_nand>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x100000>; /* 1MB */ + read-only; + }; + + partition@100000 { + label = "uImage"; + reg = <0x100000 0x1000000>; /* 16MB */ + }; + + partition@1100000 { + label = "rootfs"; + reg = <0x1100000 0x1EF00000>; /* 495MB */ + }; +}; + +&mdio { + status = "okay"; + + ethphy0: ethernet-phy@0 { + device_type = "ethernet-phy"; + reg = <0>; + }; +}; + +ð0 { + status = "okay"; + ethernet0-port@0 { + phy-handle = <ðphy0>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi index 4e8f9e42c592..1656653d339b 100644 --- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi +++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi @@ -108,20 +108,20 @@ button@1 { label = "Function Button"; - linux,code = <357>; - gpios = <&gpio1 9 1>; + linux,code = ; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; button@2 { label = "Power-on Switch"; - linux,code = <0>; + linux,code = ; linux,input-type = <5>; - gpios = <&gpio1 10 1>; + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; }; button@3 { label = "Power-auto Switch"; - linux,code = <1>; + linux,code = ; linux,input-type = <5>; - gpios = <&gpio1 11 1>; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; }; @@ -134,28 +134,28 @@ led@1 { label = "lsxl:blue:func"; - gpios = <&gpio1 4 1>; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; }; led@2 { label = "lsxl:red:alarm"; - gpios = <&gpio1 5 1>; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; }; led@3 { label = "lsxl:amber:info"; - gpios = <&gpio1 6 1>; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; }; led@4 { label = "lsxl:blue:power"; - gpios = <&gpio1 7 1>; - linux,default-trigger = "default-on"; + gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; led@5 { label = "lsxl:red:func"; - gpios = <&gpio1 16 1>; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; }; }; @@ -163,13 +163,13 @@ compatible = "gpio-fan"; pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; pinctrl-names = "default"; - gpios = <&gpio0 19 1 - &gpio0 18 1>; + gpios = <&gpio0 19 GPIO_ACTIVE_LOW + &gpio0 18 GPIO_ACTIVE_LOW>; gpio-fan,speed-map = <0 3 1500 2 3250 1 5000 0>; - alarm-gpios = <&gpio1 8 0>; + alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; restart_poweroff { @@ -212,12 +212,10 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; ethphy1: ethernet-phy@8 { - device_type = "ethernet-phy"; reg = <8>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts index 6c1ec2786e6e..73722c067501 100644 --- a/arch/arm/boot/dts/kirkwood-mplcec4.dts +++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts @@ -110,7 +110,7 @@ pinctrl-0 = <&pmx_sdio &pmx_sdio_cd>; pinctrl-names = "default"; status = "okay"; - cd-gpios = <&gpio1 15 1>; + cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; /* No WP GPIO */ }; }; @@ -126,36 +126,36 @@ health { label = "status:green:health"; - gpios = <&gpio0 7 1>; + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; }; user1o { label = "user1:orange"; - gpios = <&gpio1 8 1>; + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; default-state = "on"; }; user1g { label = "user1:green"; - gpios = <&gpio1 9 1>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; default-state = "on"; }; user0o { label = "user0:orange"; - gpios = <&gpio1 12 1>; + gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; default-state = "on"; }; user0g { label = "user0:green"; - gpios = <&gpio1 13 1>; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; default-state = "on"; }; misc { label = "status:orange:misc"; - gpios = <&gpio1 14 1>; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; default-state = "on"; }; @@ -197,12 +197,10 @@ status = "okay"; ethphy0: ethernet-phy@1 { - device_type = "ethernet-phy"; reg = <1>; }; ethphy1: ethernet-phy@2 { - device_type = "ethernet-phy"; reg = <2>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts index 6317e1d088b3..dc86429756d7 100644 --- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts +++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts @@ -90,17 +90,17 @@ green-status { label = "gtw:green:Status"; - gpios = <&gpio0 20 0>; + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; }; red-status { label = "gtw:red:Status"; - gpios = <&gpio0 21 0>; + gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>; }; green-usb { label = "gtw:green:USB"; - gpios = <&gpio0 12 0>; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; }; }; @@ -113,13 +113,13 @@ button@1 { label = "SWR Button"; - linux,code = <0x198>; /* KEY_RESTART */ - gpios = <&gpio1 15 1>; + linux,code = ; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; button@2 { label = "WPS Button"; - linux,code = <0x211>; /* KEY_WPS_BUTTON */ - gpios = <&gpio1 14 1>; + linux,code = ; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts index e6a102cf424c..4838478019cc 100644 --- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts +++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts @@ -1,3 +1,14 @@ +/* + * Device Tree file for NETGEAR ReadyNAS Duo v2 + * + * Copyright (C) 2013, Arnaud EBALARD + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + /dts-v1/; #include "kirkwood.dtsi" @@ -32,41 +43,50 @@ marvell,pins = "mpp47"; marvell,function = "gpio"; }; + pmx_button_backup: pmx-button-backup { marvell,pins = "mpp45"; marvell,function = "gpio"; }; + pmx_button_reset: pmx-button-reset { marvell,pins = "mpp13"; marvell,function = "gpio"; }; + pmx_led_blue_power: pmx-led-blue-power { marvell,pins = "mpp31"; marvell,function = "gpio"; }; + pmx_led_blue_activity: pmx-led-blue-activity { marvell,pins = "mpp38"; marvell,function = "gpio"; }; + pmx_led_blue_disk1: pmx-led-blue-disk1 { marvell,pins = "mpp23"; marvell,function = "gpio"; }; + pmx_led_blue_disk2: pmx-led-blue-disk2 { marvell,pins = "mpp22"; marvell,function = "gpio"; }; + pmx_led_blue_backup: pmx-led-blue-backup { marvell,pins = "mpp29"; marvell,function = "gpio"; }; + + pmx_poweroff: pmx-poweroff { + marvell,pins = "mpp30"; + marvell,function = "gpio"; + }; }; clocks { - #address-cells = <1>; - #size-cells = <0>; - - g762_clk: fixedclk { + g762_clk: g762-oscillator { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <8192>; @@ -112,69 +132,80 @@ power_led { label = "status:blue:power_led"; - gpios = <&gpio0 31 1>; /* GPIO 31 Active Low */ - linux,default-trigger = "default-on"; + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; + activity_led { label = "status:blue:activity_led"; - gpios = <&gpio1 6 1>; /* GPIO 38 Active Low */ + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; }; + disk1_led { label = "status:blue:disk1_led"; - gpios = <&gpio0 23 1>; /* GPIO 23 Active Low */ + gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; }; + disk2_led { label = "status:blue:disk2_led"; - gpios = <&gpio0 22 1>; /* GPIO 22 Active Low */ + gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; }; + backup_led { label = "status:blue:backup_led"; - gpios = <&gpio0 29 1>; /* GPIO 29 Active Low*/ + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; pinctrl-0 = <&pmx_button_power &pmx_button_backup &pmx_button_reset>; pinctrl-names = "default"; - button@1 { + power-button { label = "Power Button"; - linux,code = <116>; /* KEY_POWER */ - gpios = <&gpio1 15 1>; + linux,code = ; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; }; - button@2 { + + reset-button { label = "Reset Button"; - linux,code = <0x198>; /* KEY_RESTART */ - gpios = <&gpio0 13 1>; + linux,code = ; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; }; - button@3 { + + backup-button { label = "Backup Button"; - linux,code = <133>; /* KEY_COPY */ - gpios = <&gpio1 13 1>; + linux,code = ; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; }; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; + gpio-poweroff { + compatible = "gpio-poweroff"; + pinctrl-0 = <&pmx_poweroff>; + pinctrl-names = "default"; + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + }; - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB 3.0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio1 14 0>; - }; - }; + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + usb3_regulator: usb3-regulator { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB 3.0 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + }; }; &nand { @@ -210,8 +241,7 @@ &mdio { status = "okay"; - ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; + ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */ reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts new file mode 100644 index 000000000000..7c8a0d9d8d1f --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_nv+_v2.dts @@ -0,0 +1,268 @@ +/* + * Device Tree file for NETGEAR ReadyNAS NV+ v2 + * + * Copyright (C) 2013, Arnaud EBALARD + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/dts-v1/; + +#include "kirkwood.dtsi" +#include "kirkwood-6282.dtsi" + +/ { + model = "NETGEAR ReadyNAS NV+ v2"; + compatible = "netgear,readynas-nv+-v2", "netgear,readynas", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + }; + + mbus { + pcie-controller { + status = "okay"; + + /* Connected to NEC uPD720200 USB 3.0 controller */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + }; + }; + + ocp@f1000000 { + pinctrl: pinctrl@10000 { + pmx_button_power: pmx-button-power { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + + pmx_button_backup: pmx-button-backup { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + + pmx_button_reset: pmx-button-reset { + marvell,pins = "mpp13"; + marvell,function = "gpio"; + }; + + pmx_led_blue_power: pmx-led-blue-power { + marvell,pins = "mpp31"; + marvell,function = "gpio"; + }; + + pmx_led_blue_backup: pmx-led-blue-backup { + marvell,pins = "mpp22"; + marvell,function = "gpio"; + }; + + pmx_led_blue_disk1: pmx-led-blue-disk1 { + marvell,pins = "mpp20"; + marvell,function = "gpio"; + }; + + pmx_led_blue_disk2: pmx-led-blue-disk2 { + marvell,pins = "mpp23"; + marvell,function = "gpio"; + }; + + pmx_led_blue_disk3: pmx-led-blue-disk3 { + marvell,pins = "mpp24"; + marvell,function = "gpio"; + }; + + pmx_led_blue_disk4: pmx-led-blue-disk4 { + marvell,pins = "mpp29"; + marvell,function = "gpio"; + }; + + pmx_poweroff: pmx-poweroff { + marvell,pins = "mpp30"; + marvell,function = "gpio"; + }; + }; + + clocks { + g762_clk: g762-oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <8192>; + }; + }; + + i2c@11000 { + status = "okay"; + + rs5c372a: rs5c372a@32 { + compatible = "ricoh,rs5c372a"; + reg = <0x32>; + }; + + g762: g762@3e { + compatible = "gmt,g762"; + reg = <0x3e>; + clocks = <&g762_clk>; /* input clock */ + fan_gear_mode = <0>; + fan_startv = <1>; + pwm_polarity = <0>; + }; + }; + + serial@12000 { + pinctrl-0 = <&pmx_uart0>; + pinctrl-names = "default"; + status = "okay"; + }; + + sata@80000 { /* Connected to Marvell 88SM4140 SATA port multiplier */ + status = "okay"; + nr-ports = <1>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-0 = < &pmx_led_blue_power &pmx_led_blue_backup + &pmx_led_blue_disk1 &pmx_led_blue_disk2 + &pmx_led_blue_disk3 &pmx_led_blue_disk3 >; + pinctrl-names = "default"; + + power_led { + label = "status:blue:power_led"; + gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + backup_led { + label = "status:blue:backup_led"; + gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; + }; + + disk1_led { + label = "status:blue:disk1_led"; + gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + }; + + disk2_led { + label = "status:blue:disk2_led"; + gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; + }; + + disk3_led { + label = "status:blue:disk3_led"; + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; + }; + + disk4_led { + label = "status:blue:disk4_led"; + gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&pmx_button_power &pmx_button_backup + &pmx_button_reset>; + pinctrl-names = "default"; + + power-button { + label = "Power Button"; + linux,code = ; + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + }; + + reset-button { + label = "Reset Button"; + linux,code = ; + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + backup-button { + label = "Backup Button"; + linux,code = ; + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-poweroff { + compatible = "gpio-poweroff"; + pinctrl-0 = <&pmx_poweroff>; + pinctrl-names = "default"; + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + usb3_regulator: usb3-regulator { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB 3.0 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&nand { + status = "okay"; + + partition@0 { + label = "u-boot"; + reg = <0x0000000 0x180000>; + read-only; + }; + + partition@180000 { + label = "u-boot-env"; + reg = <0x180000 0x20000>; + }; + + partition@200000 { + label = "uImage"; + reg = <0x0200000 0x600000>; + }; + + partition@800000 { + label = "minirootfs"; + reg = <0x0800000 0x1000000>; + }; + + partition@1800000 { + label = "jffs2"; + reg = <0x1800000 0x6800000>; + }; +}; + +&mdio { + status = "okay"; + + ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */ + device_type = "ethernet-phy"; + reg = <0>; + }; +}; + +ð0 { + status = "okay"; + + ethernet0-port@0 { + phy-handle = <ðphy0>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 2fcb82e20828..743152f31a81 100644 --- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -64,8 +64,8 @@ button@1 { label = "Power push button"; - linux,code = <116>; - gpios = <&gpio1 0 0>; + linux,code = ; + gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; }; }; @@ -74,13 +74,13 @@ red-fail { label = "ns2:red:fail"; - gpios = <&gpio0 12 0>; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; }; }; gpio_poweroff { compatible = "gpio-poweroff"; - gpios = <&gpio0 31 0>; + gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; }; }; @@ -89,7 +89,6 @@ status = "okay"; ethphy0: ethernet-phy { - device_type = "ethernet-phy"; /* overwrite reg property in board file */ }; }; diff --git a/arch/arm/boot/dts/kirkwood-ns2lite.dts b/arch/arm/boot/dts/kirkwood-ns2lite.dts index 279607093cdb..1f2ca60d8b3d 100644 --- a/arch/arm/boot/dts/kirkwood-ns2lite.dts +++ b/arch/arm/boot/dts/kirkwood-ns2lite.dts @@ -25,8 +25,8 @@ blue-sata { label = "ns2:blue:sata"; - gpios = <&gpio0 30 1>; - linux,default-trigger = "default-on"; + gpios = <&gpio0 30 GPIO_ACTIVE_LOW>; + linux,default-trigger = "ide-disk"; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-ns2max.dts b/arch/arm/boot/dts/kirkwood-ns2max.dts index defdc77fb550..72c78d0b1116 100644 --- a/arch/arm/boot/dts/kirkwood-ns2max.dts +++ b/arch/arm/boot/dts/kirkwood-ns2max.dts @@ -22,10 +22,10 @@ gpio_fan { compatible = "gpio-fan"; - gpios = <&gpio0 22 1 - &gpio0 7 1 - &gpio1 1 1 - &gpio0 23 1>; + gpios = <&gpio0 22 GPIO_ACTIVE_LOW + &gpio0 7 GPIO_ACTIVE_LOW + &gpio1 1 GPIO_ACTIVE_LOW + &gpio0 23 GPIO_ACTIVE_LOW>; gpio-fan,speed-map = < 0 0 1500 15 @@ -36,7 +36,7 @@ 3300 10 4300 9 5500 8>; - alarm-gpios = <&gpio0 25 1>; + alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; }; ns2-leds { diff --git a/arch/arm/boot/dts/kirkwood-ns2mini.dts b/arch/arm/boot/dts/kirkwood-ns2mini.dts index adbafdd90991..c441bf62c09f 100644 --- a/arch/arm/boot/dts/kirkwood-ns2mini.dts +++ b/arch/arm/boot/dts/kirkwood-ns2mini.dts @@ -23,10 +23,10 @@ gpio_fan { compatible = "gpio-fan"; - gpios = <&gpio0 22 1 - &gpio0 7 1 - &gpio1 1 1 - &gpio0 23 1>; + gpios = <&gpio0 22 GPIO_ACTIVE_LOW + &gpio0 7 GPIO_ACTIVE_LOW + &gpio1 1 GPIO_ACTIVE_LOW + &gpio0 23 GPIO_ACTIVE_LOW>; gpio-fan,speed-map = < 0 0 3000 15 @@ -37,7 +37,7 @@ 7140 10 7980 9 9200 8>; - alarm-gpios = <&gpio0 25 1>; + alarm-gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; }; ns2-leds { diff --git a/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi b/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi index e3f915defd3d..aa78c2d11fe7 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-nsa310-common.dtsi @@ -40,7 +40,7 @@ compatible = "gpio-poweroff"; pinctrl-0 = <&pmx_pwr_off>; pinctrl-names = "default"; - gpios = <&gpio1 16 0>; + gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; }; regulators { @@ -58,7 +58,7 @@ regulator-max-microvolt = <5000000>; regulator-always-on; regulator-boot-on; - gpio = <&gpio0 21 0>; + gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts index b5418bcaecce..03fa24cf3344 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -119,18 +119,18 @@ button@1 { label = "Power Button"; - linux,code = <116>; - gpios = <&gpio1 14 0>; + linux,code = ; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; }; button@2 { label = "Copy Button"; - linux,code = <133>; - gpios = <&gpio1 5 1>; + linux,code = ; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; }; button@3 { label = "Reset Button"; - linux,code = <0x198>; - gpios = <&gpio1 4 1>; + linux,code = ; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; }; }; @@ -145,43 +145,43 @@ green-sys { label = "nsa310:green:sys"; - gpios = <&gpio0 28 0>; + gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; }; red-sys { label = "nsa310:red:sys"; - gpios = <&gpio0 29 0>; + gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; }; green-hdd { label = "nsa310:green:hdd"; - gpios = <&gpio1 9 0>; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; }; red-hdd { label = "nsa310:red:hdd"; - gpios = <&gpio1 10 0>; + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; }; green-esata { label = "nsa310:green:esata"; - gpios = <&gpio0 12 0>; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; }; red-esata { label = "nsa310:red:esata"; - gpios = <&gpio0 13 0>; + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; }; green-usb { label = "nsa310:green:usb"; - gpios = <&gpio0 15 0>; + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; }; red-usb { label = "nsa310:red:usb"; - gpios = <&gpio0 16 0>; + gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; }; green-copy { label = "nsa310:green:copy"; - gpios = <&gpio1 7 0>; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; }; red-copy { label = "nsa310:red:copy"; - gpios = <&gpio1 8 0>; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-nsa310a.dts b/arch/arm/boot/dts/kirkwood-nsa310a.dts index ab0212b0e6f5..a5e779452867 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310a.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310a.dts @@ -107,18 +107,18 @@ button@1 { label = "Power Button"; - linux,code = <116>; - gpios = <&gpio1 14 0>; + linux,code = ; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; }; button@2 { label = "Copy Button"; - linux,code = <133>; - gpios = <&gpio1 5 1>; + linux,code = ; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; }; button@3 { label = "Reset Button"; - linux,code = <0x198>; - gpios = <&gpio1 4 1>; + linux,code = ; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; }; }; @@ -127,39 +127,39 @@ green-sys { label = "nsa310:green:sys"; - gpios = <&gpio0 28 0>; + gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; }; red-sys { label = "nsa310:red:sys"; - gpios = <&gpio0 29 0>; + gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; }; green-hdd { label = "nsa310:green:hdd"; - gpios = <&gpio1 9 0>; + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; }; red-hdd { label = "nsa310:red:hdd"; - gpios = <&gpio1 10 0>; + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; }; green-esata { label = "nsa310:green:esata"; - gpios = <&gpio0 12 0>; + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; }; red-esata { label = "nsa310:red:esata"; - gpios = <&gpio0 13 0>; + gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; }; green-usb { label = "nsa310:green:usb"; - gpios = <&gpio0 15 0>; + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; }; green-copy { label = "nsa310:green:copy"; - gpios = <&gpio1 7 0>; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; }; red-copy { label = "nsa310:red:copy"; - gpios = <&gpio1 8 0>; + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts index f0e3d213604c..b88da9392c32 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts @@ -101,17 +101,17 @@ led-red { label = "obsa6:red:stat"; - gpios = <&gpio1 9 1>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; led-green { label = "obsa6:green:stat"; - gpios = <&gpio1 10 1>; + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; }; led-yellow { label = "obsa6:yellow:stat"; - gpios = <&gpio1 11 1>; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; }; @@ -124,8 +124,8 @@ button@1 { label = "Init Button"; - linux,code = <116>; - gpios = <&gpio1 6 0>; + linux,code = ; + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; }; }; }; @@ -171,7 +171,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts index 851fb2a60f20..b2f7cae06839 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts @@ -126,17 +126,17 @@ led-red { label = "obsa7:red:stat"; - gpios = <&gpio1 9 1>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; }; led-green { label = "obsa7:green:stat"; - gpios = <&gpio1 10 1>; + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; }; led-yellow { label = "obsa7:yellow:stat"; - gpios = <&gpio1 11 1>; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; }; @@ -149,8 +149,8 @@ button@1 { label = "Init Button"; - linux,code = <116>; - gpios = <&gpio1 6 0>; + linux,code = ; + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; }; }; }; @@ -196,12 +196,10 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; ethphy1: ethernet-phy@1 { - device_type = "ethernet-phy"; reg = <1>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi index 1173d7fb31b2..1ff848d570a9 100644 --- a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi @@ -1,5 +1,5 @@ /* - * kirkwood-sheevaplug-common.dts - Common parts for Sheevaplugs + * kirkwood-sheevaplug-common.dtsi - Common parts for Sheevaplugs * * Copyright (C) 2013 Simon Baatz * @@ -96,7 +96,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts b/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts index eac6a21f3b1f..e2b4ea4f9e10 100644 --- a/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts +++ b/arch/arm/boot/dts/kirkwood-sheevaplug-esata.dts @@ -24,8 +24,8 @@ pinctrl-0 = <&pmx_sdio &pmx_sdio_cd &pmx_sdio_wp>; pinctrl-names = "default"; status = "okay"; - cd-gpios = <&gpio1 12 1>; - wp-gpios = <&gpio1 15 0>; + cd-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; }; }; @@ -36,8 +36,8 @@ health { label = "sheevaplug:blue:health"; - gpios = <&gpio1 17 1>; - linux,default-trigger = "default-on"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-sheevaplug.dts b/arch/arm/boot/dts/kirkwood-sheevaplug.dts index bb61918313db..82f6abf120fd 100644 --- a/arch/arm/boot/dts/kirkwood-sheevaplug.dts +++ b/arch/arm/boot/dts/kirkwood-sheevaplug.dts @@ -1,5 +1,5 @@ /* - * kirkwood-sheevaplug-esata.dts - Device tree file for Sheevaplug + * kirkwood-sheevaplug.dts - Device tree file for Sheevaplug * * Copyright (C) 2013 Simon Baatz * @@ -31,13 +31,13 @@ health { label = "sheevaplug:blue:health"; - gpios = <&gpio1 17 1>; - linux,default-trigger = "default-on"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + default-state = "keep"; }; misc { label = "sheevaplug:red:misc"; - gpios = <&gpio1 14 1>; + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts index 320da677b984..5fc817c2cb87 100644 --- a/arch/arm/boot/dts/kirkwood-topkick.dts +++ b/arch/arm/boot/dts/kirkwood-topkick.dts @@ -131,25 +131,25 @@ disk { label = "topkick:yellow:disk"; - gpios = <&gpio0 21 1>; + gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; linux,default-trigger = "ide-disk"; }; system2 { label = "topkick:red:system"; - gpios = <&gpio1 5 1>; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; }; system { label = "topkick:blue:system"; - gpios = <&gpio1 6 1>; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; default-state = "on"; }; wifi { label = "topkick:green:wifi"; - gpios = <&gpio1 7 1>; + gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; }; wifi2 { label = "topkick:yellow:wifi"; - gpios = <&gpio1 16 1>; + gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; }; }; regulators { @@ -208,7 +208,6 @@ status = "okay"; ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; reg = <0>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts index f755bc1dc604..c17ae45e19be 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6281.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts @@ -41,13 +41,13 @@ button@1 { label = "USB Copy"; - linux,code = <133>; - gpios = <&gpio0 15 1>; + linux,code = ; + gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; }; button@2 { label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio0 16 1>; + linux,code = ; + gpios = <&gpio0 16 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts index 345562f75891..0713d072758a 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts @@ -51,13 +51,13 @@ button@1 { label = "USB Copy"; - linux,code = <133>; - gpios = <&gpio1 11 1>; + linux,code = ; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; }; button@2 { label = "Reset"; - linux,code = <0x198>; - gpios = <&gpio1 5 1>; + linux,code = ; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi index 39158cf16258..911f3a8cee23 100644 --- a/arch/arm/boot/dts/kirkwood-ts219.dtsi +++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi @@ -104,7 +104,6 @@ status = "okay"; ethphy0: ethernet-phy { - device_type = "ethernet-phy"; /* overwrite reg property in board file */ }; }; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 8b73c80f1dad..6abf44d257df 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -1,4 +1,6 @@ /include/ "skeleton.dtsi" +#include +#include #define MBUS_ID(target,attributes) (((target) << 24) | ((attributes) << 16)) @@ -68,39 +70,21 @@ #address-cells = <1>; #size-cells = <1>; - mbusc: mbus-controller@20000 { - compatible = "marvell,mbus-controller"; - reg = <0x20000 0x80>, <0x1500 0x20>; - }; - - timer: timer@20300 { - compatible = "marvell,orion-timer"; - reg = <0x20300 0x20>; - interrupt-parent = <&bridge_intc>; - interrupts = <1>, <2>; - clocks = <&core_clk 0>; - }; - - intc: main-interrupt-ctrl@20200 { - compatible = "marvell,orion-intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x20200 0x10>, <0x20210 0x10>; - }; - - bridge_intc: bridge-interrupt-ctrl@20110 { - compatible = "marvell,orion-bridge-intc"; - interrupt-controller; - #interrupt-cells = <1>; - reg = <0x20110 0x8>; - interrupts = <1>; - marvell,#interrupts = <6>; - }; - core_clk: core-clocks@10030 { compatible = "marvell,kirkwood-core-clock"; reg = <0x10030 0x4>; - #clock-cells = <1>; + #clock-cells = <1>; + }; + + spi@10600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = <23>; + reg = <0x10600 0x28>; + clocks = <&gate_clk 7>; + status = "disabled"; }; gpio0: gpio@10100 { @@ -127,6 +111,17 @@ clocks = <&gate_clk 7>; }; + i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <29>; + clock-frequency = <100000>; + clocks = <&gate_clk 7>; + status = "disabled"; + }; + serial@12000 { compatible = "ns16550a"; reg = <0x12000 0x100>; @@ -145,15 +140,18 @@ status = "disabled"; }; - spi@10600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - interrupts = <23>; - reg = <0x10600 0x28>; - clocks = <&gate_clk 7>; - status = "disabled"; + mbusc: mbus-controller@20000 { + compatible = "marvell,mbus-controller"; + reg = <0x20000 0x80>, <0x1500 0x20>; + }; + + bridge_intc: bridge-interrupt-ctrl@20110 { + compatible = "marvell,orion-bridge-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x20110 0x8>; + interrupts = <1>; + marvell,#interrupts = <6>; }; gate_clk: clock-gating-control@2011c { @@ -163,6 +161,21 @@ #clock-cells = <1>; }; + intc: main-interrupt-ctrl@20200 { + compatible = "marvell,orion-intc"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x20200 0x10>, <0x20210 0x10>; + }; + + timer: timer@20300 { + compatible = "marvell,orion-timer"; + reg = <0x20300 0x20>; + interrupt-parent = <&bridge_intc>; + interrupts = <1>, <2>; + clocks = <&core_clk 0>; + }; + wdt: watchdog-timer@20300 { compatible = "marvell,orion-wdt"; reg = <0x20300 0x28>; @@ -172,6 +185,14 @@ status = "okay"; }; + ehci@50000 { + compatible = "marvell,orion-ehci"; + reg = <0x50000 0x1000>; + interrupts = <19>; + clocks = <&gate_clk 3>; + status = "okay"; + }; + xor@60800 { compatible = "marvell,orion-xor"; reg = <0x60800 0x100 @@ -212,23 +233,23 @@ }; }; - ehci@50000 { - compatible = "marvell,orion-ehci"; - reg = <0x50000 0x1000>; - interrupts = <19>; - clocks = <&gate_clk 3>; - status = "okay"; - }; - - i2c@11000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; + eth0: ethernet-controller@72000 { + compatible = "marvell,kirkwood-eth"; #address-cells = <1>; #size-cells = <0>; - interrupts = <29>; - clock-frequency = <100000>; - clocks = <&gate_clk 7>; + reg = <0x72000 0x4000>; + clocks = <&gate_clk 0>; + marvell,tx-checksum-limit = <1600>; status = "disabled"; + + ethernet0-port@0 { + compatible = "marvell,kirkwood-eth-port"; + reg = <0>; + interrupts = <11>; + /* overwrite MAC address in bootloader */ + local-mac-address = [00 00 00 00 00 00]; + /* set phy-handle property in board file */ + }; }; mdio: mdio-bus@72004 { @@ -243,26 +264,6 @@ /* add phy nodes in board file */ }; - eth0: ethernet-controller@72000 { - compatible = "marvell,kirkwood-eth"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x72000 0x4000>; - clocks = <&gate_clk 0>; - marvell,tx-checksum-limit = <1600>; - status = "disabled"; - - ethernet0-port@0 { - device_type = "network"; - compatible = "marvell,kirkwood-eth-port"; - reg = <0>; - interrupts = <11>; - /* overwrite MAC address in bootloader */ - local-mac-address = [00 00 00 00 00 00]; - /* set phy-handle property in board file */ - }; - }; - eth1: ethernet-controller@76000 { compatible = "marvell,kirkwood-eth"; #address-cells = <1>; @@ -273,7 +274,6 @@ status = "disabled"; ethernet1-port@0 { - device_type = "network"; compatible = "marvell,kirkwood-eth-port"; reg = <0>; interrupts = <15>; @@ -282,5 +282,23 @@ /* set phy-handle property in board file */ }; }; + + sata_phy0: sata-phy@82000 { + compatible = "marvell,mvebu-sata-phy"; + reg = <0x82000 0x0334>; + clocks = <&gate_clk 14>; + clock-names = "sata"; + #phy-cells = <0>; + status = "ok"; + }; + + sata_phy1: sata-phy@84000 { + compatible = "marvell,mvebu-sata-phy"; + reg = <0x84000 0x0334>; + clocks = <&gate_clk 15>; + clock-names = "sata"; + #phy-cells = <0>; + status = "ok"; + }; }; }; diff --git a/arch/arm/boot/dts/moxart-uc7112lx.dts b/arch/arm/boot/dts/moxart-uc7112lx.dts new file mode 100644 index 000000000000..90749d55de0d --- /dev/null +++ b/arch/arm/boot/dts/moxart-uc7112lx.dts @@ -0,0 +1,109 @@ +/* moxart-uc7112lx.dts - Device Tree file for MOXA UC-7112-LX + * + * Copyright (C) 2013 Jonas Jensen + * + * Licensed under GPLv2 or later. + */ + +/dts-v1/; +/include/ "moxart.dtsi" + +/ { + model = "MOXA UC-7112-LX"; + compatible = "moxa,moxart-uc-7112-lx", "moxa,moxart"; + + memory { + device_type = "memory"; + reg = <0x0 0x2000000>; + }; + + flash@80000000,0 { + compatible = "numonyx,js28f128", "cfi-flash"; + reg = <0x80000000 0x1000000>; + bank-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "bootloader"; + reg = <0x0 0x40000>; + }; + partition@40000 { + label = "linux kernel"; + reg = <0x40000 0x1C0000>; + }; + partition@200000 { + label = "root filesystem"; + reg = <0x200000 0x800000>; + }; + partition@a00000 { + label = "user filesystem"; + reg = <0xa00000 0x600000>; + }; + }; + + leds { + compatible = "gpio-leds"; + user-led { + label = "ready-led"; + gpios = <&gpio 27 0x1>; + default-state = "on"; + linux,default-trigger = "default-on"; + }; + }; + + gpio_keys_polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <500>; + button@25 { + label = "GPIO Reset"; + linux,code = <116>; + gpios = <&gpio 25 1>; + }; + }; + + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/mmcblk0p1 rw rootwait"; + }; +}; + +&clk_pll { + clocks = <&ref12>; +}; + +&sdhci { + status = "okay"; +}; + +&mdio0 { + status = "okay"; + + ethphy0: ethernet-phy@1 { + device_type = "ethernet-phy"; + compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; +}; + +&mdio1 { + status = "okay"; + + ethphy1: ethernet-phy@1 { + device_type = "ethernet-phy"; + compatible = "moxa,moxart-rtl8201cp", "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; +}; + +&mac0 { + status = "okay"; +}; + +&mac1 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/moxart.dtsi b/arch/arm/boot/dts/moxart.dtsi new file mode 100644 index 000000000000..da1d8effef97 --- /dev/null +++ b/arch/arm/boot/dts/moxart.dtsi @@ -0,0 +1,154 @@ +/* moxart.dtsi - Device Tree Include file for MOXA ART family SoC + * + * Copyright (C) 2013 Jonas Jensen + * + * Licensed under GPLv2 or later. + */ + +/include/ "skeleton.dtsi" + +/ { + compatible = "moxa,moxart"; + model = "MOXART"; + interrupt-parent = <&intc>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "faraday,fa526"; + reg = <0>; + }; + }; + + clocks { + #address-cells = <1>; + #size-cells = <0>; + + ref12: ref12M { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12000000>; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x90000000 0x10000000>; + ranges; + + intc: interrupt-controller@98800000 { + compatible = "moxa,moxart-ic"; + reg = <0x98800000 0x38>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-mask = <0x00080000>; + }; + + clk_pll: clk_pll@98100000 { + compatible = "moxa,moxart-pll-clock"; + #clock-cells = <0>; + reg = <0x98100000 0x34>; + }; + + clk_apb: clk_apb@98100000 { + compatible = "moxa,moxart-apb-clock"; + #clock-cells = <0>; + reg = <0x98100000 0x34>; + clocks = <&clk_pll>; + }; + + timer: timer@98400000 { + compatible = "moxa,moxart-timer"; + reg = <0x98400000 0x42>; + interrupts = <19 1>; + clocks = <&clk_apb>; + }; + + gpio: gpio@98700000 { + gpio-controller; + #gpio-cells = <2>; + compatible = "moxa,moxart-gpio"; + reg = <0x98700000 0xC>; + }; + + rtc: rtc { + compatible = "moxa,moxart-rtc"; + gpio-rtc-sclk = <&gpio 5 0>; + gpio-rtc-data = <&gpio 6 0>; + gpio-rtc-reset = <&gpio 7 0>; + }; + + dma: dma@90500000 { + compatible = "moxa,moxart-dma"; + reg = <0x90500080 0x40>; + interrupts = <24 0>; + #dma-cells = <1>; + }; + + watchdog: watchdog@98500000 { + compatible = "moxa,moxart-watchdog"; + reg = <0x98500000 0x10>; + clocks = <&clk_apb>; + }; + + sdhci: sdhci@98e00000 { + compatible = "moxa,moxart-sdhci"; + reg = <0x98e00000 0x5C>; + interrupts = <5 0>; + clocks = <&clk_apb>; + dmas = <&dma 5>, + <&dma 5>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + mdio0: mdio@90900090 { + compatible = "moxa,moxart-mdio"; + reg = <0x90900090 0x8>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mdio1: mdio@92000090 { + compatible = "moxa,moxart-mdio"; + reg = <0x92000090 0x8>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mac0: mac@90900000 { + compatible = "moxa,moxart-mac"; + reg = <0x90900000 0x90>; + interrupts = <25 0>; + phy-handle = <ðphy0>; + phy-mode = "mii"; + status = "disabled"; + }; + + mac1: mac@92000000 { + compatible = "moxa,moxart-mac"; + reg = <0x92000000 0x90>; + interrupts = <27 0>; + phy-handle = <ðphy1>; + phy-mode = "mii"; + status = "disabled"; + }; + + uart0: uart@98200000 { + compatible = "ns16550a"; + reg = <0x98200000 0x20>; + interrupts = <31 8>; + reg-shift = <2>; + reg-io-width = <4>; + clock-frequency = <14745600>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index d0c5b37e248c..5377ddf83bf8 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -145,7 +145,7 @@ compatible = "ti,omap2-rng"; ti,hwmods = "rng"; reg = <0x480a0000 0x50>; - interrupts = <36>; + interrupts = <52>; }; sham: sham@480a4000 { diff --git a/arch/arm/boot/dts/omap2420-n800.dts b/arch/arm/boot/dts/omap2420-n800.dts new file mode 100644 index 000000000000..d8c1b423606a --- /dev/null +++ b/arch/arm/boot/dts/omap2420-n800.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +#include "omap2420-n8x0-common.dtsi" + +/ { + model = "Nokia N800"; + compatible = "nokia,n800", "nokia,n8x0", "ti,omap2420", "ti,omap2"; +}; diff --git a/arch/arm/boot/dts/omap2420-n810-wimax.dts b/arch/arm/boot/dts/omap2420-n810-wimax.dts new file mode 100644 index 000000000000..6b25b0359ac9 --- /dev/null +++ b/arch/arm/boot/dts/omap2420-n810-wimax.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +#include "omap2420-n8x0-common.dtsi" + +/ { + model = "Nokia N810 WiMax"; + compatible = "nokia,n810-wimax", "nokia,n8x0", "ti,omap2420", "ti,omap2"; +}; diff --git a/arch/arm/boot/dts/omap2420-n810.dts b/arch/arm/boot/dts/omap2420-n810.dts new file mode 100644 index 000000000000..21baec154b78 --- /dev/null +++ b/arch/arm/boot/dts/omap2420-n810.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +#include "omap2420-n8x0-common.dtsi" + +/ { + model = "Nokia N810"; + compatible = "nokia,n810", "nokia,n8x0", "ti,omap2420", "ti,omap2"; +}; diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi new file mode 100644 index 000000000000..89608b206519 --- /dev/null +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi @@ -0,0 +1,99 @@ +#include "omap2420.dtsi" + +/ { + memory { + device_type = "memory"; + reg = <0x80000000 0x8000000>; /* 128 MB */ + }; + + ocp { + i2c@0 { + compatible = "i2c-cbus-gpio"; + gpios = <&gpio3 2 0 /* gpio66 clk */ + &gpio3 1 0 /* gpio65 dat */ + &gpio3 0 0 /* gpio64 sel */ + >; + #address-cells = <1>; + #size-cells = <0>; + retu_mfd: retu@1 { + compatible = "retu-mfd"; + interrupt-parent = <&gpio4>; + interrupts = <12 IRQ_TYPE_EDGE_RISING>; + reg = <0x1>; + }; + }; + }; +}; + +&i2c1 { + clock-frequency = <400000>; +}; + +&i2c2 { + clock-frequency = <400000>; +}; + +&gpmc { + ranges = <0 0 0x04000000 0x10000000>; + + /* gpio-irq for dma: 26 */ + + onenand@0,0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0 0x10000000>; + + gpmc,sync-read; + gpmc,burst-length = <16>; + gpmc,burst-read; + gpmc,burst-wrap; + gpmc,device-width = <2>; + gpmc,mux-add-data = <2>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <127>; + gpmc,cs-wr-off-ns = <109>; + gpmc,adv-on-ns = <0>; + gpmc,adv-rd-off-ns = <18>; + gpmc,adv-wr-off-ns = <18>; + gpmc,oe-on-ns = <27>; + gpmc,oe-off-ns = <127>; + gpmc,we-on-ns = <27>; + gpmc,we-off-ns = <72>; + gpmc,rd-cycle-ns = <145>; + gpmc,wr-cycle-ns = <136>; + gpmc,access-ns = <118>; + gpmc,page-burst-access-ns = <27>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,wait-monitoring-ns = <0>; + gpmc,clk-activation-ns = <9>; + gpmc,sync-clk-ps = <27000>; + + /* MTD partition table corresponding to old board-n8x0 file. */ + partition@0 { + label = "bootloader"; + reg = <0x00000000 0x00020000>; + read-only; + }; + partition@1 { + label = "config"; + reg = <0x00020000 0x00060000>; + }; + partition@2 { + label = "kernel"; + reg = <0x00080000 0x00200000>; + }; + partition@3 { + label = "initfs"; + reg = <0x00280000 0x00400000>; + }; + partition@4 { + label = "rootfs"; + reg = <0x00680000 0x0f980000>; + }; + partition@5 { + label = "omap2-onenand"; + reg = <0x00000000 0x10000000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap2430-sdp.dts b/arch/arm/boot/dts/omap2430-sdp.dts new file mode 100644 index 000000000000..2c90d29b4cad --- /dev/null +++ b/arch/arm/boot/dts/omap2430-sdp.dts @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap2430.dtsi" + +/ { + model = "TI OMAP2430 SDP"; + compatible = "ti,omap2430-sdp", "ti,omap2430", "ti,omap2"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x8000000>; /* 128 MB */ + }; +}; + +&i2c2 { + clock-frequency = <100000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + }; +}; + +#include "twl4030.dtsi" + +&mmc1 { + vmmc-supply = <&vmmc1>; + bus-width = <4>; +}; + +&gpmc { + ranges = <5 0 0x08000000 0x01000000>; + ethernet@gpmc { + compatible = "smsc,lan91c94"; + interrupt-parent = <&gpio5>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; /* gpio149 */ + reg = <5 0x300 0xf>; + bank-width = <2>; + gpmc,mux-add-data; + }; +}; + diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index df33a50bc070..447e714d435b 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -99,7 +99,7 @@ &omap3_pmx_core { pinctrl-names = "default"; pinctrl-0 = < - &hsusbb2_pins + &hsusb2_pins >; uart3_pins: pinmux_uart3_pins { @@ -109,20 +109,32 @@ >; }; - hsusbb2_pins: pinmux_hsusbb2_pins { + hsusb2_pins: pinmux_hsusb2_pins { pinctrl-single,pins = < - 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ - 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ - 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ - 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ - 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ - 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ - 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ - 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ - 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ - 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ - 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ - 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + >; + }; +}; + +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusb2_2_pins + >; + + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ >; }; }; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 3ba4a625ea5b..5053766d369b 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -93,23 +93,17 @@ &omap3_pmx_core { pinctrl-names = "default"; pinctrl-0 = < - &hsusbb2_pins + &hsusb2_pins >; - hsusbb2_pins: pinmux_hsusbb2_pins { + hsusb2_pins: pinmux_hsusb2_pins { pinctrl-single,pins = < - 0x5c0 (PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ - 0x5c2 (PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ - 0x5c4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ - 0x5c6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ - 0x5c8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ - 0x5cA (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ - 0x1a4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ - 0x1a6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ - 0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ - 0x1aa (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ - 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ - 0x1ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ >; }; @@ -121,6 +115,24 @@ }; }; +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusb2_2_pins + >; + + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + >; + }; +}; + &i2c1 { clock-frequency = <2600000>; diff --git a/arch/arm/boot/dts/omap3-cm-t3730.dts b/arch/arm/boot/dts/omap3-cm-t3730.dts new file mode 100644 index 000000000000..486f4d6c4219 --- /dev/null +++ b/arch/arm/boot/dts/omap3-cm-t3730.dts @@ -0,0 +1,104 @@ +/* + * Support for CompuLab CM-T3730 + */ +/dts-v1/; + +#include "omap36xx.dtsi" +#include "omap3-cm-t3x30.dtsi" + +/ { + model = "CompuLab CM-T3730"; + compatible = "compulab,omap3-cm-t3730", "ti,omap36xx", "ti,omap3"; + + wl12xx_vmmc2: wl12xx_vmmc2 { + compatible = "regulator-fixed"; + regulator-name = "vw1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wl12xx_gpio>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio3 9 GPIO_ACTIVE_HIGH>; /* gpio73 */ + startup-delay-us = <20000>; + enable-active-high; + }; + + wl12xx_vaux2: wl12xx_vaux2 { + compatible = "regulator-fixed"; + regulator-name = "vwl1271_vaux2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vaux2>; + }; +}; + +&omap3_pmx_core { + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + 0x114 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ + 0x116 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ + 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */ + 0x11a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */ + 0x11c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */ + 0x11e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */ + >; + }; + + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + 0x128 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */ + 0x12a (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */ + 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */ + 0x12e (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */ + 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */ + 0x132 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */ + >; + }; + + smsc1_pins: pinmux_smsc1_pins { + pinctrl-single,pins = < + 0x88 (PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs5.gpmc_ncs5 */ + 0x16a (PIN_INPUT_PULLUP | MUX_MODE4) /* uart3_cts_rctx.gpio_163 */ + >; + }; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + 0x16e (PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx.uart3_rx_irrx */ + 0x170 (PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx.uart3_tx_irtx */ + >; + }; + + wl12xx_gpio: pinmux_wl12xx_gpio { + pinctrl-single,pins = < + 0xb2 (PIN_OUTPUT | MUX_MODE4) /* dss_data3.gpio_73 */ + 0x134 (PIN_INPUT | MUX_MODE4) /* sdmmc2_dat4.gpio_136 */ + >; + }; +}; + +&mmc1 { + vmmc-supply = <&vmmc1>; + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <&wl12xx_vmmc2>; + vmmc_aux-supply = <&wl12xx_vaux2>; + non-removable; + bus-width = <4>; + cap-power-off-card; +}; + +&smsc1 { + pinctrl-names = "default"; + pinctrl-0 = <&smsc1_pins>; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; +}; diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi new file mode 100644 index 000000000000..3a9f004d8924 --- /dev/null +++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi @@ -0,0 +1,95 @@ +/* + * Common support for CompuLab CM-T3530 and CM-T3730 + */ + +/ { + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; /* 256 MB */ + }; + + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + leds { + compatible = "gpio-leds"; + ledb { + label = "cm-t35:green"; + gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>; /* gpio186 */ + linux,default-trigger = "heartbeat"; + }; + }; + + vddvario: regulator-vddvario { + compatible = "regulator-fixed"; + regulator-name = "vddvario"; + regulator-always-on; + }; + + vdd33a: regulator-vdd33a { + compatible = "regulator-fixed"; + regulator-name = "vdd33a"; + regulator-always-on; + }; +}; + +&gpmc { + ranges = <5 0 0x2c000000 0x01000000>; + + smsc1: ethernet@5,0 { + compatible = "smsc,lan9221", "smsc,lan9115"; + interrupt-parent = <&gpio6>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + reg = <5 0 0xff>; + bank-width = <2>; + gpmc,mux-add-data; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <186>; + gpmc,cs-wr-off-ns = <186>; + gpmc,adv-on-ns = <12>; + gpmc,adv-rd-off-ns = <48>; + gpmc,adv-wr-off-ns = <48>; + gpmc,oe-on-ns = <54>; + gpmc,oe-off-ns = <168>; + gpmc,we-on-ns = <54>; + gpmc,we-off-ns = <168>; + gpmc,rd-cycle-ns = <186>; + gpmc,wr-cycle-ns = <186>; + gpmc,access-ns = <114>; + gpmc,page-burst-access-ns = <6>; + gpmc,bus-turnaround-ns = <12>; + gpmc,cycle2cycle-delay-ns = <18>; + gpmc,wr-data-mux-bus-ns = <90>; + gpmc,wr-access-ns = <186>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + vddvario-supply = <&vddvario>; + vdd33a-supply = <&vdd33a>; + reg-io-width = <4>; + smsc,save-mac-address; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&i2c3 { + clock-frequency = <400000>; +}; + +&twl_gpio { + ti,use-leds; +}; diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index 165aaf7591ba..c17009323520 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -133,8 +133,6 @@ 0x194 (PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */ >; }; - - leds_pins: pinmux_leds_pins { }; }; &i2c1 { diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts index 1c7e74d2d2bc..25a2b5f652fd 100644 --- a/arch/arm/boot/dts/omap3-igep0020.dts +++ b/arch/arm/boot/dts/omap3-igep0020.dts @@ -66,28 +66,10 @@ &omap3_pmx_core { pinctrl-names = "default"; pinctrl-0 = < - &hsusbb1_pins &tfp410_pins &dss_pins >; - hsusbb1_pins: pinmux_hsusbb1_pins { - pinctrl-single,pins = < - 0x5aa (PIN_OUTPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */ - 0x5a8 (PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */ - 0x5bc (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d8.hsusb1_dir */ - 0x5be (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d9.hsusb1_nxt */ - 0x5ac (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d0.hsusb1_data0 */ - 0x5ae (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d1.hsusb1_data1 */ - 0x5b0 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d2.hsusb1_data2 */ - 0x5b2 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d3.hsusb1_data7 */ - 0x5b4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d4.hsusb1_data4 */ - 0x5b6 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d5.hsusb1_data5 */ - 0x5b8 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d6.hsusb1_data6 */ - 0x5ba (PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */ - >; - }; - tfp410_pins: tfp410_dvi_pins { pinctrl-single,pins = < 0x196 (PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */ @@ -128,12 +110,36 @@ }; }; -&leds_pins { - pinctrl-single,pins = < - 0x5c4 (PIN_OUTPUT | MUX_MODE4) /* etk_d12.gpio_26 */ - 0x5c6 (PIN_OUTPUT | MUX_MODE4) /* etk_d13.gpio_27 */ - 0x5c8 (PIN_OUTPUT | MUX_MODE4) /* etk_d14.gpio_28 */ +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusbb1_pins >; + + hsusbb1_pins: pinmux_hsusbb1_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25da, PIN_OUTPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */ + OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */ + OMAP3630_CORE2_IOPAD(0x25ec, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d8.hsusb1_dir */ + OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d9.hsusb1_nxt */ + OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d0.hsusb1_data0 */ + OMAP3630_CORE2_IOPAD(0x25de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d1.hsusb1_data1 */ + OMAP3630_CORE2_IOPAD(0x25e0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d2.hsusb1_data2 */ + OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d3.hsusb1_data7 */ + OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d4.hsusb1_data4 */ + OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d5.hsusb1_data5 */ + OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d6.hsusb1_data6 */ + OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */ + >; + }; + + leds_pins: pinmux_leds_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25f4, PIN_OUTPUT | MUX_MODE4) /* etk_d12.gpio_26 */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_OUTPUT | MUX_MODE4) /* etk_d13.gpio_27 */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_OUTPUT | MUX_MODE4) /* etk_d14.gpio_28 */ + >; + }; }; &i2c3 { diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts index 02a23f8a3384..145c58cfc8ac 100644 --- a/arch/arm/boot/dts/omap3-igep0030.dts +++ b/arch/arm/boot/dts/omap3-igep0030.dts @@ -46,10 +46,12 @@ }; }; -&leds_pins { - pinctrl-single,pins = < - 0x5b0 (PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */ - >; +&omap3_pmx_core2 { + leds_pins: pinmux_leds_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */ + >; + }; }; &gpmc { diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts new file mode 100644 index 000000000000..ddce0d807f70 --- /dev/null +++ b/arch/arm/boot/dts/omap3-ldp.dts @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap34xx.dtsi" +#include "omap-gpmc-smsc911x.dtsi" + +/ { + model = "TI OMAP3430 LDP (Zoom1 Labrador)"; + compatible = "ti,omap3-ldp", "ti,omap3"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x8000000>; /* 128 MB */ + }; + + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_key_pins>; + + key_enter { + label = "enter"; + gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* gpio101 */ + linux,code = <0x0107001c>; /* KEY_ENTER */ + gpio-key,wakeup; + }; + + key_f1 { + label = "f1"; + gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* gpio102 */ + linux,code = <0x0303003b>; /* KEY_F1 */ + gpio-key,wakeup; + }; + + key_f2 { + label = "f2"; + gpios = <&gpio4 7 GPIO_ACTIVE_LOW>; /* gpio103 */ + linux,code = <0x0403003c>; /* KEY_F2 */ + gpio-key,wakeup; + }; + + key_f3 { + label = "f3"; + gpios = <&gpio4 8 GPIO_ACTIVE_LOW>; /* gpio104 */ + linux,code = <0x0503003d>; /* KEY_F3 */ + gpio-key,wakeup; + }; + + key_f4 { + label = "f4"; + gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; /* gpio105 */ + linux,code = <0x0704003e>; /* KEY_F4 */ + gpio-key,wakeup; + }; + + key_left { + label = "left"; + gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; /* gpio106 */ + linux,code = <0x04070069>; /* KEY_LEFT */ + gpio-key,wakeup; + }; + + key_right { + label = "right"; + gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; /* gpio107 */ + linux,code = <0x0507006a>; /* KEY_RIGHT */ + gpio-key,wakeup; + }; + + key_up { + label = "up"; + gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; /* gpio108 */ + linux,code = <0x06070067>; /* KEY_UP */ + gpio-key,wakeup; + }; + + key_down { + label = "down"; + gpios = <&gpio4 13 GPIO_ACTIVE_LOW>; /* gpio109 */ + linux,code = <0x0707006c>; /* KEY_DOWN */ + gpio-key,wakeup; + }; + }; +}; + +&gpmc { + ranges = <0 0 0x00000000 0x01000000>, + <1 0 0x08000000 0x01000000>; + + nand@0,0 { + linux,mtd-name= "micron,nand"; + reg = <0 0 0>; + nand-bus-width = <16>; + ti,nand-ecc-opt = "bch8"; + + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-off-ns = <40>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "X-Loader"; + reg = <0 0x80000>; + }; + partition@80000 { + label = "U-Boot"; + reg = <0x80000 0x140000>; + }; + partition@1c0000 { + label = "Environment"; + reg = <0x1c0000 0x40000>; + }; + partition@200000 { + label = "Kernel"; + reg = <0x200000 0x1e00000>; + }; + partition@2000000 { + label = "Filesystem"; + reg = <0x2000000 0xe000000>; + }; + }; + + ethernet@gpmc { + interrupt-parent = <&gpio5>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + reg = <1 0 0xff>; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + }; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&i2c2 { + clock-frequency = <400000>; +}; + +&i2c3 { + clock-frequency = <400000>; +}; + +&mmc1 { + vmmc-supply = <&vmmc1>; + bus-width = <4>; +}; + +&omap3_pmx_core { + gpio_key_pins: pinmux_gpio_key_pins { + pinctrl-single,pins = < + 0xea (PIN_INPUT | MUX_MODE4) /* cam_d2.gpio_101 */ + 0xec (PIN_INPUT | MUX_MODE4) /* cam_d3.gpio_102 */ + 0xee (PIN_INPUT | MUX_MODE4) /* cam_d4.gpio_103 */ + 0xf0 (PIN_INPUT | MUX_MODE4) /* cam_d5.gpio_104 */ + 0xf2 (PIN_INPUT | MUX_MODE4) /* cam_d6.gpio_105 */ + 0xf4 (PIN_INPUT | MUX_MODE4) /* cam_d7.gpio_106 */ + 0xf6 (PIN_INPUT | MUX_MODE4) /* cam_d8.gpio_107 */ + 0xf8 (PIN_INPUT | MUX_MODE4) /* cam_d9.gpio_108 */ + 0xfa (PIN_INPUT | MUX_MODE4) /* cam_d10.gpio_109 */ + >; + }; + + musb_pins: pinmux_musb_pins { + pinctrl-single,pins = < + 0x172 (PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */ + 0x17a (PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */ + 0x17c (PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */ + 0x17e (PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */ + 0x180 (PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */ + 0x182 (PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */ + 0x184 (PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */ + 0x186 (PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */ + 0x188 (PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */ + 0x176 (PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */ + 0x178 (PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */ + 0x174 (PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ + >; + }; +}; + +&usb_otg_hs { + pinctrl-names = "default"; + pinctrl-0 = <&musb_pins>; + interface-type = <0>; + usb-phy = <&usb2_phy>; + mode = <3>; + power = <50>; +}; + +&vaux1 { + /* Needed for ads7846 */ + regulator-name = "vcc"; +}; + +&vpll2 { + /* Needed for DSS */ + regulator-name = "vdds_dsi"; +}; diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi new file mode 100644 index 000000000000..b9a2fedce7ee --- /dev/null +++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi @@ -0,0 +1,40 @@ +/* + * Common support for CompuLab SB-T35 used on SBC-T3530, SBC-T3517 and SBC-T3730 + */ + +&gpmc { + ranges = <4 0 0x2d000000 0x01000000>; + + smsc2: ethernet@4,0 { + compatible = "smsc,lan9221", "smsc,lan9115"; + interrupt-parent = <&gpio3>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + reg = <4 0 0xff>; + bank-width = <2>; + gpmc,mux-add-data; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <186>; + gpmc,cs-wr-off-ns = <186>; + gpmc,adv-on-ns = <12>; + gpmc,adv-rd-off-ns = <48>; + gpmc,adv-wr-off-ns = <48>; + gpmc,oe-on-ns = <54>; + gpmc,oe-off-ns = <168>; + gpmc,we-on-ns = <54>; + gpmc,we-off-ns = <168>; + gpmc,rd-cycle-ns = <186>; + gpmc,wr-cycle-ns = <186>; + gpmc,access-ns = <114>; + gpmc,page-burst-access-ns = <6>; + gpmc,bus-turnaround-ns = <12>; + gpmc,cycle2cycle-delay-ns = <18>; + gpmc,wr-data-mux-bus-ns = <90>; + gpmc,wr-access-ns = <186>; + gpmc,cycle2cycle-samecsen; + gpmc,cycle2cycle-diffcsen; + vddvario-supply = <&vddvario>; + vdd33a-supply = <&vdd33a>; + reg-io-width = <4>; + smsc,save-mac-address; + }; +}; diff --git a/arch/arm/boot/dts/omap3-sbc-t3730.dts b/arch/arm/boot/dts/omap3-sbc-t3730.dts new file mode 100644 index 000000000000..c119bd545053 --- /dev/null +++ b/arch/arm/boot/dts/omap3-sbc-t3730.dts @@ -0,0 +1,30 @@ +/* + * Suppport for CompuLab SBC-T3730 with CM-T3730 + */ + +#include "omap3-cm-t3730.dts" +#include "omap3-sb-t35.dtsi" + +/ { + model = "CompuLab SBC-T3730 with CM-T3730"; + compatible = "compulab,omap3-sbc-t3730", "compulab,omap3-cm-t3730", "ti,omap36xx", "ti,omap3"; +}; + +&gpmc { + ranges = <5 0 0x2c000000 0x01000000>, + <4 0 0x2d000000 0x01000000>; +}; + +&smsc2 { + pinctrl-names = "default"; + pinctrl-0 = <&smsc2_pins>; +}; + +&omap3_pmx_core { + smsc2_pins: pinmux_smsc2_pins { + pinctrl-single,pins = < + 0x86 (PIN_OUTPUT | MUX_MODE0) /* gpmc_ncs4.gpmc_ncs4 */ + 0xa2 (PIN_INPUT_PULLUP | MUX_MODE4) /* gpmc_wait3.gpio_65 */ + >; + }; +}; \ No newline at end of file diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts index 15eb9fe5169c..6644f516a42b 100644 --- a/arch/arm/boot/dts/omap3-zoom3.dts +++ b/arch/arm/boot/dts/omap3-zoom3.dts @@ -80,13 +80,8 @@ mmc3_pins: pinmux_mmc3_pins { pinctrl-single,pins = < - 0x168 (PIN_INPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 WLAN IRQ */ - 0x1a0 (PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */ - 0x5a8 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */ - 0x5b4 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d4.sdmmc3_dat0 */ - 0x5b6 (WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */ - 0x5b8 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d6.sdmmc3_dat2 */ - 0x5b2 (PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d3.sdmmc3_dat3 */ + OMAP3_CORE1_IOPAD(0x2198, PIN_INPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 WLAN IRQ */ + OMAP3_CORE1_IOPAD(0x21d0, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */ >; }; @@ -125,6 +120,18 @@ }; }; +&omap3_pmx_core2 { + mmc3_2_pins: pinmux_mmc3_2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_clk */ + OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d4.sdmmc3_dat0 */ + OMAP3630_CORE2_IOPAD(0x25e6, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d5.sdmmc3_dat1 */ + OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d6.sdmmc3_dat2 */ + OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_d3.sdmmc3_dat3 */ + >; + }; +}; + &omap3_pmx_wkup { wlan_host_wkup: pinmux_wlan_host_wkup_pins { pinctrl-single,pins = < @@ -187,7 +194,7 @@ bus-width = <4>; cap-power-off-card; pinctrl-names = "default"; - pinctrl-0 = <&mmc3_pins>; + pinctrl-0 = <&mmc3_pins &mmc3_2_pins>; }; &uart1 { diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index daabf99d402a..427395c083f5 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -117,7 +117,7 @@ omap3_pmx_core: pinmux@48002030 { compatible = "ti,omap3-padconf", "pinctrl-single"; - reg = <0x48002030 0x05cc>; + reg = <0x48002030 0x0238>; #address-cells = <1>; #size-cells = <0>; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi index 5355d6173748..77d124678c95 100644 --- a/arch/arm/boot/dts/omap34xx.dtsi +++ b/arch/arm/boot/dts/omap34xx.dtsi @@ -25,4 +25,17 @@ clock-latency = <300000>; /* From legacy driver */ }; }; + + ocp { + omap3_pmx_core2: pinmux@480025d8 { + compatible = "ti,omap3-padconf", "pinctrl-single"; + reg = <0x480025d8 0x24>; + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + pinctrl-single,register-width = <16>; + pinctrl-single,function-mask = <0xff1f>; + }; + }; }; diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi index 380c22eb468e..b7c7bd96c404 100644 --- a/arch/arm/boot/dts/omap36xx.dtsi +++ b/arch/arm/boot/dts/omap36xx.dtsi @@ -38,5 +38,16 @@ ti,hwmods = "uart4"; clock-frequency = <48000000>; }; + + omap3_pmx_core2: pinmux@480025a0 { + compatible = "ti,omap3-padconf", "pinctrl-single"; + reg = <0x480025a0 0x5c>; + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + pinctrl-single,register-width = <16>; + pinctrl-single,function-mask = <0xff1f>; + }; }; }; diff --git a/arch/arm/boot/dts/omap4-cpu-thermal.dtsi b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi new file mode 100644 index 000000000000..cb9458feb2e3 --- /dev/null +++ b/arch/arm/boot/dts/omap4-cpu-thermal.dtsi @@ -0,0 +1,41 @@ +/* + * Device Tree Source for OMAP4/5 SoC CPU thermal + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Contact: Eduardo Valentin + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include + +cpu_thermal: cpu_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap 0>; + + trips { + cpu_alert0: cpu_alert { + temperature = <100000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <125000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi index bcf455efe18d..ab607a19a613 100644 --- a/arch/arm/boot/dts/omap443x.dtsi +++ b/arch/arm/boot/dts/omap443x.dtsi @@ -12,7 +12,7 @@ / { cpus { - cpu@0 { + cpu0: cpu@0 { /* OMAP443x variants OPP50-OPPNT */ operating-points = < /* kHz uV */ @@ -22,12 +22,25 @@ 1008000 1375000 >; clock-latency = <300000>; /* From legacy driver */ + + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <3>; + #cooling-cells = <2>; /* min followed by max */ }; }; - bandgap { - reg = <0x4a002260 0x4 - 0x4a00232C 0x4>; - compatible = "ti,omap4430-bandgap"; + thermal-zones { + #include "omap4-cpu-thermal.dtsi" + }; + + ocp { + bandgap: bandgap { + reg = <0x4a002260 0x4 + 0x4a00232C 0x4>; + compatible = "ti,omap4430-bandgap"; + + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi index c2f0f39b5a24..11566bed0035 100644 --- a/arch/arm/boot/dts/omap4460.dtsi +++ b/arch/arm/boot/dts/omap4460.dtsi @@ -12,7 +12,7 @@ / { cpus { /* OMAP446x 'standard device' variants OPP50 to OPPTurbo */ - cpu@0 { + cpu0: cpu@0 { operating-points = < /* kHz uV */ 350000 1025000 @@ -20,6 +20,11 @@ 920000 1313000 >; clock-latency = <300000>; /* From legacy driver */ + + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <2>; + #cooling-cells = <2>; /* min followed by max */ }; }; @@ -30,12 +35,20 @@ ti,hwmods = "debugss"; }; - bandgap { - reg = <0x4a002260 0x4 - 0x4a00232C 0x4 - 0x4a002378 0x18>; - compatible = "ti,omap4460-bandgap"; - interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */ - gpios = <&gpio3 22 0>; /* tshut */ + thermal-zones { + #include "omap4-cpu-thermal.dtsi" + }; + + ocp { + bandgap: bandgap { + reg = <0x4a002260 0x4 + 0x4a00232C 0x4 + 0x4a002378 0x18>; + compatible = "ti,omap4460-bandgap"; + interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>; /* talert */ + gpios = <&gpio3 22 0>; /* tshut */ + + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap5-core-thermal.dtsi b/arch/arm/boot/dts/omap5-core-thermal.dtsi new file mode 100644 index 000000000000..19212ac6eef0 --- /dev/null +++ b/arch/arm/boot/dts/omap5-core-thermal.dtsi @@ -0,0 +1,28 @@ +/* + * Device Tree Source for OMAP543x SoC CORE thermal + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Contact: Eduardo Valentin + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include + +core_thermal: core_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap 2>; + + trips { + core_crit: core_crit { + temperature = <125000>; /* milliCelsius */ + hysteresis = <2000>; /* milliCelsius */ + type = "critical"; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap5-gpu-thermal.dtsi b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi new file mode 100644 index 000000000000..1b87aca88b77 --- /dev/null +++ b/arch/arm/boot/dts/omap5-gpu-thermal.dtsi @@ -0,0 +1,28 @@ +/* + * Device Tree Source for OMAP543x SoC GPU thermal + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * Contact: Eduardo Valentin + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include + +gpu_thermal: gpu_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <1000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap 1>; + + trips { + gpu_crit: gpu_crit { + temperature = <125000>; /* milliCelsius */ + hysteresis = <2000>; /* milliCelsius */ + type = "critical"; + }; + }; +}; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index fc3fad563861..ab9a21ae82f3 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -49,6 +49,10 @@ 1000000 1060000 1500000 1250000 >; + /* cooling options */ + cooling-min-level = <0>; + cooling-max-level = <2>; + #cooling-cells = <2>; /* min followed by max */ }; cpu@1 { device_type = "cpu"; @@ -57,6 +61,12 @@ }; }; + thermal-zones { + #include "omap4-cpu-thermal.dtsi" + #include "omap5-gpu-thermal.dtsi" + #include "omap5-core-thermal.dtsi" + }; + timer { compatible = "arm,armv7-timer"; /* PPI secure/nonsecure IRQ */ @@ -729,13 +739,15 @@ }; }; - bandgap@4a0021e0 { + bandgap: bandgap@4a0021e0 { reg = <0x4a0021e0 0xc 0x4a00232c 0xc 0x4a002380 0x2c 0x4a0023C0 0x3c>; interrupts = ; compatible = "ti,omap5430-bandgap"; + + #thermal-sensor-cells = <1>; }; }; }; diff --git a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts index aed83deaa991..5ed6c1376901 100644 --- a/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts +++ b/arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts @@ -58,7 +58,6 @@ status = "okay"; ethphy: ethernet-phy { - device-type = "ethernet-phy"; reg = <8>; }; }; diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi index e06c37e91ac6..174d89241f70 100644 --- a/arch/arm/boot/dts/orion5x.dtsi +++ b/arch/arm/boot/dts/orion5x.dtsi @@ -42,6 +42,25 @@ interrupts = <6>, <7>, <8>, <9>; }; + spi@10600 { + compatible = "marvell,orion-spi"; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + reg = <0x10600 0x28>; + status = "disabled"; + }; + + i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <5>; + clock-frequency = <100000>; + status = "disabled"; + }; + serial@12000 { compatible = "ns16550a"; reg = <0x12000 0x100>; @@ -60,15 +79,6 @@ status = "disabled"; }; - spi@10600 { - compatible = "marvell,orion-spi"; - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - reg = <0x10600 0x28>; - status = "disabled"; - }; - wdt@20300 { compatible = "marvell,orion-wdt"; reg = <0x20300 0x28>; @@ -82,30 +92,6 @@ status = "disabled"; }; - ehci@a0000 { - compatible = "marvell,orion-ehci"; - reg = <0xa0000 0x1000>; - interrupts = <12>; - status = "disabled"; - }; - - sata@80000 { - compatible = "marvell,orion-sata"; - reg = <0x80000 0x5000>; - interrupts = <29>; - status = "disabled"; - }; - - i2c@11000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <5>; - clock-frequency = <100000>; - status = "disabled"; - }; - xor@60900 { compatible = "marvell,orion-xor"; reg = <0x60900 0x100 @@ -125,13 +111,21 @@ }; }; - crypto@90000 { - compatible = "marvell,orion-crypto"; - reg = <0x90000 0x10000>, - <0xf2200000 0x800>; - reg-names = "regs", "sram"; - interrupts = <28>; - status = "okay"; + eth: ethernet-controller@72000 { + compatible = "marvell,orion-eth"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x72000 0x4000>; + marvell,tx-checksum-limit = <1600>; + status = "disabled"; + + ethernet-port@0 { + compatible = "marvell,orion-eth-port"; + reg = <0>; + /* overwrite MAC address in bootloader */ + local-mac-address = [00 00 00 00 00 00]; + /* set phy-handle property in board file */ + }; }; mdio: mdio-bus@72004 { @@ -145,22 +139,27 @@ /* add phy nodes in board file */ }; - eth: ethernet-controller@72000 { - compatible = "marvell,orion-eth"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x72000 0x4000>; - marvell,tx-checksum-limit = <1600>; + sata@80000 { + compatible = "marvell,orion-sata"; + reg = <0x80000 0x5000>; + interrupts = <29>; status = "disabled"; + }; - ethernet-port@0 { - device_type = "network"; - compatible = "marvell,orion-eth-port"; - reg = <0>; - /* overwrite MAC address in bootloader */ - local-mac-address = [00 00 00 00 00 00]; - /* set phy-handle property in board file */ - }; + crypto@90000 { + compatible = "marvell,orion-crypto"; + reg = <0x90000 0x10000>, + <0xf2200000 0x800>; + reg-names = "regs", "sram"; + interrupts = <28>; + status = "okay"; + }; + + ehci@a0000 { + compatible = "marvell,orion-ehci"; + reg = <0xa0000 0x1000>; + interrupts = <12>; + status = "disabled"; }; }; }; diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index daee58944e15..0e219932d7cc 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi @@ -29,6 +29,15 @@ timebase-frequency = <0>; bus-frequency = <0>; clock-frequency = <0>; + clocks = <&clks 12>; + operating-points = < + /* kHz uV */ + 200000 1025000 + 400000 1025000 + 664000 1050000 + 800000 1100000 + >; + clock-latency = <150000>; }; }; @@ -80,6 +89,7 @@ cphifbg@88030000 { compatible = "sirf,prima2-cphifbg"; reg = <0x88030000 0x1000>; + clocks = <&clks 42>; }; }; @@ -540,6 +550,18 @@ "usp0_uart_nostreamctrl"; }; }; + usp0_only_utfs_pins_a: usp0@2 { + usp0 { + sirf,pins = "usp0_only_utfs_grp"; + sirf,function = "usp0_only_utfs"; + }; + }; + usp0_only_urfs_pins_a: usp0@3 { + usp0 { + sirf,pins = "usp0_only_urfs_grp"; + sirf,function = "usp0_only_urfs"; + }; + }; usp1_pins_a: usp1@0 { usp1 { sirf,pins = "usp1grp"; @@ -648,6 +670,9 @@ compatible = "sirf,prima2-sdhc"; reg = <0x56000000 0x100000>; interrupts = <38>; + status = "disabled"; + bus-width = <8>; + clocks = <&clks 36>; }; sd1: sdhci@56100000 { @@ -655,6 +680,9 @@ compatible = "sirf,prima2-sdhc"; reg = <0x56100000 0x100000>; interrupts = <38>; + status = "disabled"; + bus-width = <4>; + clocks = <&clks 36>; }; sd2: sdhci@56200000 { @@ -662,6 +690,8 @@ compatible = "sirf,prima2-sdhc"; reg = <0x56200000 0x100000>; interrupts = <23>; + status = "disabled"; + clocks = <&clks 37>; }; sd3: sdhci@56300000 { @@ -669,6 +699,8 @@ compatible = "sirf,prima2-sdhc"; reg = <0x56300000 0x100000>; interrupts = <23>; + status = "disabled"; + clocks = <&clks 37>; }; sd4: sdhci@56400000 { @@ -676,6 +708,8 @@ compatible = "sirf,prima2-sdhc"; reg = <0x56400000 0x100000>; interrupts = <39>; + status = "disabled"; + clocks = <&clks 38>; }; sd5: sdhci@56500000 { @@ -683,6 +717,7 @@ compatible = "sirf,prima2-sdhc"; reg = <0x56500000 0x100000>; interrupts = <39>; + clocks = <&clks 38>; }; pci-copy@57900000 { @@ -716,6 +751,12 @@ interrupts = <52 53 54>; }; + minigpsrtc@2000 { + compatible = "sirf,prima2-minigpsrtc"; + reg = <0x2000 0x1000>; + interrupts = <54>; + }; + pwrc@3000 { compatible = "sirf,prima2-pwrc"; reg = <0x3000 0x1000>; diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi index d7c5d721a5c7..a70546945985 100644 --- a/arch/arm/boot/dts/pxa27x.dtsi +++ b/arch/arm/boot/dts/pxa27x.dtsi @@ -10,5 +10,29 @@ marvell,intc-priority; marvell,intc-nr-irqs = <34>; }; + + pwm0: pwm@40b00000 { + compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm"; + reg = <0x40b00000 0x10>; + #pwm-cells = <1>; + }; + + pwm1: pwm@40b00010 { + compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm"; + reg = <0x40b00010 0x10>; + #pwm-cells = <1>; + }; + + pwm2: pwm@40c00000 { + compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm"; + reg = <0x40c00000 0x10>; + #pwm-cells = <1>; + }; + + pwm3: pwm@40c00010 { + compatible = "marvell,pxa270-pwm", "marvell,pxa250-pwm"; + reg = <0x40c00010 0x10>; + #pwm-cells = <1>; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts new file mode 100644 index 000000000000..13ac3e222495 --- /dev/null +++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts @@ -0,0 +1,6 @@ +#include "qcom-msm8974.dtsi" + +/ { + model = "Qualcomm APQ8074 Dragonboard"; + compatible = "qcom,apq8074-dragonboard", "qcom,apq8074"; +}; diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts index 386d42870215..1187185cf25b 100644 --- a/arch/arm/boot/dts/qcom-msm8660-surf.dts +++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts @@ -28,11 +28,11 @@ msmgpio: gpio@800000 { compatible = "qcom,msm-gpio"; - reg = <0x00800000 0x1000>; + reg = <0x00800000 0x4000>; gpio-controller; #gpio-cells = <2>; ngpio = <173>; - interrupts = <0 32 0x4>; + interrupts = <0 16 0x4>; interrupt-controller; #interrupt-cells = <2>; }; diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts index 93e9f7e0b7ad..6ccbac77931e 100644 --- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts +++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts @@ -31,7 +31,7 @@ gpio-controller; #gpio-cells = <2>; ngpio = <150>; - interrupts = <0 32 0x4>; + interrupts = <0 16 0x4>; interrupt-controller; #interrupt-cells = <2>; reg = <0x800000 0x4000>; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi new file mode 100644 index 000000000000..6ac94967d2d3 --- /dev/null +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -0,0 +1,97 @@ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + model = "Qualcomm MSM8974"; + compatible = "qcom,msm8974"; + interrupt-parent = <&intc>; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "simple-bus"; + + intc: interrupt-controller@f9000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0xf9000000 0x1000>, + <0xf9002000 0x1000>; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 2 0xf08>, + <1 3 0xf08>, + <1 4 0xf08>, + <1 1 0xf08>; + clock-frequency = <19200000>; + }; + + timer@f9020000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xf9020000 0x1000>; + clock-frequency = <19200000>; + + frame@f9021000 { + frame-number = <0>; + interrupts = <0 8 0x4>, + <0 7 0x4>; + reg = <0xf9021000 0x1000>, + <0xf9022000 0x1000>; + }; + + frame@f9023000 { + frame-number = <1>; + interrupts = <0 9 0x4>; + reg = <0xf9023000 0x1000>; + status = "disabled"; + }; + + frame@f9024000 { + frame-number = <2>; + interrupts = <0 10 0x4>; + reg = <0xf9024000 0x1000>; + status = "disabled"; + }; + + frame@f9025000 { + frame-number = <3>; + interrupts = <0 11 0x4>; + reg = <0xf9025000 0x1000>; + status = "disabled"; + }; + + frame@f9026000 { + frame-number = <4>; + interrupts = <0 12 0x4>; + reg = <0xf9026000 0x1000>; + status = "disabled"; + }; + + frame@f9027000 { + frame-number = <5>; + interrupts = <0 13 0x4>; + reg = <0xf9027000 0x1000>; + status = "disabled"; + }; + + frame@f9028000 { + frame-number = <6>; + interrupts = <0 14 0x4>; + reg = <0xf9028000 0x1000>; + status = "disabled"; + }; + }; + + restart@fc4ab000 { + compatible = "qcom,pshold"; + reg = <0xfc4ab000 0x4>; + }; + }; +}; diff --git a/arch/arm/boot/dts/r7s72100-genmai-reference.dts b/arch/arm/boot/dts/r7s72100-genmai-reference.dts new file mode 100644 index 000000000000..da19c70ed82b --- /dev/null +++ b/arch/arm/boot/dts/r7s72100-genmai-reference.dts @@ -0,0 +1,31 @@ +/* + * Device Tree Source for the Genmai board + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +/include/ "r7s72100.dtsi" + +/ { + model = "Genmai"; + compatible = "renesas,genmai-reference", "renesas,r7s72100"; + + chosen { + bootargs = "console=ttySC2,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp"; + }; + + memory { + device_type = "memory"; + reg = <0x08000000 0x08000000>; + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; +}; diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts index 1fb20f2333cc..b1deaf7e2e06 100644 --- a/arch/arm/boot/dts/r7s72100-genmai.dts +++ b/arch/arm/boot/dts/r7s72100-genmai.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "r7s72100.dtsi" +#include "r7s72100.dtsi" / { model = "Genmai"; diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts index 9443e93d3cac..70b1fff8f4a3 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "r8a73a4.dtsi" +#include "r8a73a4.dtsi" #include / { @@ -25,6 +25,11 @@ reg = <0 0x40000000 0 0x40000000>; }; + memory@200000000 { + device_type = "memory"; + reg = <2 0x00000000 0 0x40000000>; + }; + vcc_mmc0: regulator@0 { compatible = "regulator-fixed"; regulator-name = "MMC0 Vcc"; @@ -88,22 +93,22 @@ pinctrl-0 = <&scifa0_pins>; pinctrl-names = "default"; - scifa0_pins: scifa0 { + scifa0_pins: serial0 { renesas,groups = "scifa0_data"; renesas,function = "scifa0"; }; - mmc0_pins: mmcif { + mmc0_pins: mmc { renesas,groups = "mmc0_data8", "mmc0_ctrl"; renesas,function = "mmc0"; }; - sdhi0_pins: sdhi0 { + sdhi0_pins: sd0 { renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd"; renesas,function = "sdhi0"; }; - sdhi1_pins: sdhi1 { + sdhi1_pins: sd1 { renesas,groups = "sdhi1_data4", "sdhi1_ctrl"; renesas,function = "sdhi1"; }; diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts index 91436b58016f..ce085fa444a1 100644 --- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts +++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts @@ -9,7 +9,8 @@ */ /dts-v1/; -/include/ "r8a73a4.dtsi" +#include "r8a73a4.dtsi" +#include / { model = "APE6EVM"; @@ -24,6 +25,11 @@ reg = <0 0x40000000 0 0x40000000>; }; + memory@200000000 { + device_type = "memory"; + reg = <2 0x00000000 0 0x40000000>; + }; + ape6evm_fixed_3v3: fixedregulator@0 { compatible = "regulator-fixed"; regulator-name = "3V3"; @@ -40,7 +46,7 @@ compatible = "smsc,lan9118", "smsc,lan9115"; reg = <0x08000000 0x1000>; interrupt-parent = <&irqc1>; - interrupts = <8 0x4>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; phy-mode = "mii"; reg-io-width = <4>; smsc,irq-active-high; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index 287e047592a0..62d0211bd192 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -9,6 +9,9 @@ * kind, whether express or implied. */ +#include +#include + / { compatible = "renesas,r8a73a4"; interrupt-parent = <&gic>; @@ -36,15 +39,15 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 0xf04>; + interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; + interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; irqc0: interrupt-controller@e61c0000 { @@ -53,14 +56,38 @@ interrupt-controller; reg = <0 0xe61c0000 0 0x200>; interrupt-parent = <&gic>; - interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>, - <0 4 4>, <0 5 4>, <0 6 4>, <0 7 4>, - <0 8 4>, <0 9 4>, <0 10 4>, <0 11 4>, - <0 12 4>, <0 13 4>, <0 14 4>, <0 15 4>, - <0 16 4>, <0 17 4>, <0 18 4>, <0 19 4>, - <0 20 4>, <0 21 4>, <0 22 4>, <0 23 4>, - <0 24 4>, <0 25 4>, <0 26 4>, <0 27 4>, - <0 28 4>, <0 29 4>, <0 30 4>, <0 31 4>; + interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, + <0 1 IRQ_TYPE_LEVEL_HIGH>, + <0 2 IRQ_TYPE_LEVEL_HIGH>, + <0 3 IRQ_TYPE_LEVEL_HIGH>, + <0 4 IRQ_TYPE_LEVEL_HIGH>, + <0 5 IRQ_TYPE_LEVEL_HIGH>, + <0 6 IRQ_TYPE_LEVEL_HIGH>, + <0 7 IRQ_TYPE_LEVEL_HIGH>, + <0 8 IRQ_TYPE_LEVEL_HIGH>, + <0 9 IRQ_TYPE_LEVEL_HIGH>, + <0 10 IRQ_TYPE_LEVEL_HIGH>, + <0 11 IRQ_TYPE_LEVEL_HIGH>, + <0 12 IRQ_TYPE_LEVEL_HIGH>, + <0 13 IRQ_TYPE_LEVEL_HIGH>, + <0 14 IRQ_TYPE_LEVEL_HIGH>, + <0 15 IRQ_TYPE_LEVEL_HIGH>, + <0 16 IRQ_TYPE_LEVEL_HIGH>, + <0 17 IRQ_TYPE_LEVEL_HIGH>, + <0 18 IRQ_TYPE_LEVEL_HIGH>, + <0 19 IRQ_TYPE_LEVEL_HIGH>, + <0 20 IRQ_TYPE_LEVEL_HIGH>, + <0 21 IRQ_TYPE_LEVEL_HIGH>, + <0 22 IRQ_TYPE_LEVEL_HIGH>, + <0 23 IRQ_TYPE_LEVEL_HIGH>, + <0 24 IRQ_TYPE_LEVEL_HIGH>, + <0 25 IRQ_TYPE_LEVEL_HIGH>, + <0 26 IRQ_TYPE_LEVEL_HIGH>, + <0 27 IRQ_TYPE_LEVEL_HIGH>, + <0 28 IRQ_TYPE_LEVEL_HIGH>, + <0 29 IRQ_TYPE_LEVEL_HIGH>, + <0 30 IRQ_TYPE_LEVEL_HIGH>, + <0 31 IRQ_TYPE_LEVEL_HIGH>; }; irqc1: interrupt-controller@e61c0200 { @@ -69,13 +96,32 @@ interrupt-controller; reg = <0 0xe61c0200 0 0x200>; interrupt-parent = <&gic>; - interrupts = <0 32 4>, <0 33 4>, <0 34 4>, <0 35 4>, - <0 36 4>, <0 37 4>, <0 38 4>, <0 39 4>, - <0 40 4>, <0 41 4>, <0 42 4>, <0 43 4>, - <0 44 4>, <0 45 4>, <0 46 4>, <0 47 4>, - <0 48 4>, <0 49 4>, <0 50 4>, <0 51 4>, - <0 52 4>, <0 53 4>, <0 54 4>, <0 55 4>, - <0 56 4>, <0 57 4>; + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, + <0 33 IRQ_TYPE_LEVEL_HIGH>, + <0 34 IRQ_TYPE_LEVEL_HIGH>, + <0 35 IRQ_TYPE_LEVEL_HIGH>, + <0 36 IRQ_TYPE_LEVEL_HIGH>, + <0 37 IRQ_TYPE_LEVEL_HIGH>, + <0 38 IRQ_TYPE_LEVEL_HIGH>, + <0 39 IRQ_TYPE_LEVEL_HIGH>, + <0 40 IRQ_TYPE_LEVEL_HIGH>, + <0 41 IRQ_TYPE_LEVEL_HIGH>, + <0 42 IRQ_TYPE_LEVEL_HIGH>, + <0 43 IRQ_TYPE_LEVEL_HIGH>, + <0 44 IRQ_TYPE_LEVEL_HIGH>, + <0 45 IRQ_TYPE_LEVEL_HIGH>, + <0 46 IRQ_TYPE_LEVEL_HIGH>, + <0 47 IRQ_TYPE_LEVEL_HIGH>, + <0 48 IRQ_TYPE_LEVEL_HIGH>, + <0 49 IRQ_TYPE_LEVEL_HIGH>, + <0 50 IRQ_TYPE_LEVEL_HIGH>, + <0 51 IRQ_TYPE_LEVEL_HIGH>, + <0 52 IRQ_TYPE_LEVEL_HIGH>, + <0 53 IRQ_TYPE_LEVEL_HIGH>, + <0 54 IRQ_TYPE_LEVEL_HIGH>, + <0 55 IRQ_TYPE_LEVEL_HIGH>, + <0 56 IRQ_TYPE_LEVEL_HIGH>, + <0 57 IRQ_TYPE_LEVEL_HIGH>; }; dmac: dma-multiplexer@0 { @@ -91,27 +137,27 @@ compatible = "renesas,shdma-r8a73a4"; reg = <0 0xe6700020 0 0x89e0>; interrupt-parent = <&gic>; - interrupts = <0 220 4 - 0 200 4 - 0 201 4 - 0 202 4 - 0 203 4 - 0 204 4 - 0 205 4 - 0 206 4 - 0 207 4 - 0 208 4 - 0 209 4 - 0 210 4 - 0 211 4 - 0 212 4 - 0 213 4 - 0 214 4 - 0 215 4 - 0 216 4 - 0 217 4 - 0 218 4 - 0 219 4>; + interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH + 0 200 IRQ_TYPE_LEVEL_HIGH + 0 201 IRQ_TYPE_LEVEL_HIGH + 0 202 IRQ_TYPE_LEVEL_HIGH + 0 203 IRQ_TYPE_LEVEL_HIGH + 0 204 IRQ_TYPE_LEVEL_HIGH + 0 205 IRQ_TYPE_LEVEL_HIGH + 0 206 IRQ_TYPE_LEVEL_HIGH + 0 207 IRQ_TYPE_LEVEL_HIGH + 0 208 IRQ_TYPE_LEVEL_HIGH + 0 209 IRQ_TYPE_LEVEL_HIGH + 0 210 IRQ_TYPE_LEVEL_HIGH + 0 211 IRQ_TYPE_LEVEL_HIGH + 0 212 IRQ_TYPE_LEVEL_HIGH + 0 213 IRQ_TYPE_LEVEL_HIGH + 0 214 IRQ_TYPE_LEVEL_HIGH + 0 215 IRQ_TYPE_LEVEL_HIGH + 0 216 IRQ_TYPE_LEVEL_HIGH + 0 217 IRQ_TYPE_LEVEL_HIGH + 0 218 IRQ_TYPE_LEVEL_HIGH + 0 219 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -126,7 +172,7 @@ reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>; interrupt-parent = <&gic>; - interrupts = <0 69 4>; + interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; }; i2c0: i2c@e6500000 { @@ -135,7 +181,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 174 0x4>; + interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -145,7 +191,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 175 0x4>; + interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -155,7 +201,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 176 0x4>; + interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -165,7 +211,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6530000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 177 0x4>; + interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -175,7 +221,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6540000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 178 0x4>; + interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -185,7 +231,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 179 0x4>; + interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -195,7 +241,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6550000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 184 0x4>; + interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -205,7 +251,7 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6560000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 185 0x4>; + interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -215,24 +261,24 @@ compatible = "renesas,rmobile-iic"; reg = <0 0xe6570000 0 0x428>; interrupt-parent = <&gic>; - interrupts = <0 173 0x4>; + interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; - mmcif0: mmcif@ee200000 { + mmcif0: mmc@ee200000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; interrupt-parent = <&gic>; - interrupts = <0 169 0x4>; + interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; status = "disabled"; }; - mmcif1: mmcif@ee220000 { + mmcif1: mmc@ee220000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; interrupt-parent = <&gic>; - interrupts = <0 170 0x4>; + interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; status = "disabled"; }; @@ -242,31 +288,47 @@ reg = <0 0xe6050000 0 0x9000>; gpio-controller; #gpio-cells = <2>; + interrupts-extended = + <&irqc0 0 0>, <&irqc0 1 0>, <&irqc0 2 0>, <&irqc0 3 0>, + <&irqc0 4 0>, <&irqc0 5 0>, <&irqc0 6 0>, <&irqc0 7 0>, + <&irqc0 8 0>, <&irqc0 9 0>, <&irqc0 10 0>, <&irqc0 11 0>, + <&irqc0 12 0>, <&irqc0 13 0>, <&irqc0 14 0>, <&irqc0 15 0>, + <&irqc0 16 0>, <&irqc0 17 0>, <&irqc0 18 0>, <&irqc0 19 0>, + <&irqc0 20 0>, <&irqc0 21 0>, <&irqc0 22 0>, <&irqc0 23 0>, + <&irqc0 24 0>, <&irqc0 25 0>, <&irqc0 26 0>, <&irqc0 27 0>, + <&irqc0 28 0>, <&irqc0 29 0>, <&irqc0 30 0>, <&irqc0 31 0>, + <&irqc1 0 0>, <&irqc1 1 0>, <&irqc1 2 0>, <&irqc1 3 0>, + <&irqc1 4 0>, <&irqc1 5 0>, <&irqc1 6 0>, <&irqc1 7 0>, + <&irqc1 8 0>, <&irqc1 9 0>, <&irqc1 10 0>, <&irqc1 11 0>, + <&irqc1 12 0>, <&irqc1 13 0>, <&irqc1 14 0>, <&irqc1 15 0>, + <&irqc1 16 0>, <&irqc1 17 0>, <&irqc1 18 0>, <&irqc1 19 0>, + <&irqc1 20 0>, <&irqc1 21 0>, <&irqc1 22 0>, <&irqc1 23 0>, + <&irqc1 24 0>, <&irqc1 25 0>; }; - sdhi0: sdhi@ee100000 { + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee100000 0 0x100>; interrupt-parent = <&gic>; - interrupts = <0 165 4>; + interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; cap-sd-highspeed; status = "disabled"; }; - sdhi1: sdhi@ee120000 { + sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee120000 0 0x100>; interrupt-parent = <&gic>; - interrupts = <0 166 4>; + interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; cap-sd-highspeed; status = "disabled"; }; - sdhi2: sdhi@ee140000 { + sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee140000 0 0x100>; interrupt-parent = <&gic>; - interrupts = <0 167 4>; + interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; cap-sd-highspeed; status = "disabled"; }; diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts index 1c56c5e56950..95a849bf921f 100644 --- a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +++ b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts @@ -9,8 +9,9 @@ */ /dts-v1/; -/include/ "r8a7740.dtsi" +#include "r8a7740.dtsi" #include +#include #include / { @@ -62,6 +63,44 @@ enable-active-high; }; + reg_5p0v: regulator@3 { + compatible = "regulator-fixed"; + regulator-name = "fixed-5.0V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + gpio-keys { + compatible = "gpio-keys"; + + power-key { + gpios = <&pfc 99 GPIO_ACTIVE_LOW>; + linux,code = <116>; + label = "SW3"; + gpio-key,wakeup; + }; + + back-key { + gpios = <&pfc 100 GPIO_ACTIVE_LOW>; + linux,code = <158>; + label = "SW4"; + }; + + menu-key { + gpios = <&pfc 97 GPIO_ACTIVE_LOW>; + linux,code = <139>; + label = "SW5"; + }; + + home-key { + gpios = <&pfc 98 GPIO_ACTIVE_LOW>; + linux,code = <102>; + label = "SW6"; + }; + }; + leds { compatible = "gpio-leds"; led1 { @@ -85,32 +124,58 @@ default-brightness-level = <9>; pinctrl-0 = <&backlight_pins>; pinctrl-names = "default"; + power-supply = <®_5p0v>; + enable-gpios = <&pfc 61 GPIO_ACTIVE_HIGH>; + }; + + sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "i2s"; + + simple-audio-card,cpu { + sound-dai = <&sh_fsi2 0>; + bitclock-inversion; + }; + + simple-audio-card,codec { + sound-dai = <&wm8978>; + bitclock-master; + frame-master; + system-clock-frequency = <12288000>; + }; }; }; &i2c0 { status = "okay"; - touchscreen: st1232@55 { + touchscreen@55 { compatible = "sitronix,st1232"; reg = <0x55>; interrupt-parent = <&irqpin1>; - interrupts = <2 0>; /* IRQ10: hwirq 2 on irqpin1 */ + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&st1232_pins>; pinctrl-names = "default"; gpios = <&pfc 166 GPIO_ACTIVE_LOW>; }; + + wm8978: wm8978@1a { + #sound-dai-cells = <0>; + compatible = "wlf,wm8978"; + reg = <0x1a>; + }; }; &pfc { pinctrl-0 = <&scifa1_pins>; pinctrl-names = "default"; - scifa1_pins: scifa1 { + scifa1_pins: serial1 { renesas,groups = "scifa1_data"; renesas,function = "scifa1"; }; - st1232_pins: st1232 { + st1232_pins: touchscreen { renesas,groups = "intc_irq10"; renesas,function = "intc"; }; @@ -125,10 +190,16 @@ renesas,function = "mmc0"; }; - sdhi0_pins: sdhi0 { + sdhi0_pins: sd0 { renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp"; renesas,function = "sdhi0"; }; + + fsia_pins: sounda { + renesas,groups = "fsia_sclk_in", "fsia_mclk_out", + "fsia_data_in_1", "fsia_data_out_0"; + renesas,function = "fsia"; + }; }; &tpu { @@ -155,3 +226,10 @@ cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>; status = "okay"; }; + +&sh_fsi2 { + pinctrl-0 = <&fsia_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts index 426cd9c3e1c4..a06a11e1a840 100644 --- a/arch/arm/boot/dts/r8a7740-armadillo800eva.dts +++ b/arch/arm/boot/dts/r8a7740-armadillo800eva.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "r8a7740.dtsi" +#include "r8a7740.dtsi" / { model = "armadillo 800 eva"; diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index ae1e230f711d..8280884bfa59 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -10,6 +10,8 @@ /include/ "skeleton.dtsi" +#include + / { compatible = "renesas,r8a7740"; @@ -34,12 +36,12 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 83 4>; + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>; }; /* irqpin0: IRQ0 - IRQ7 */ irqpin0: irqpin@e6900000 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe6900000 4>, @@ -48,19 +50,19 @@ <0xe6900040 1>, <0xe6900060 1>; interrupt-parent = <&gic>; - interrupts = <0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4>; + interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH>; }; /* irqpin1: IRQ8 - IRQ15 */ irqpin1: irqpin@e6900004 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe6900004 4>, @@ -69,19 +71,19 @@ <0xe6900044 1>, <0xe6900064 1>; interrupt-parent = <&gic>; - interrupts = <0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4>; + interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH>; }; /* irqpin2: IRQ16 - IRQ23 */ irqpin2: irqpin@e6900008 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe6900008 4>, @@ -90,19 +92,19 @@ <0xe6900048 1>, <0xe6900068 1>; interrupt-parent = <&gic>; - interrupts = <0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4>; + interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH>; }; /* irqpin3: IRQ24 - IRQ31 */ irqpin3: irqpin@e690000c { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-r8a7740", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe690000c 4>, @@ -111,14 +113,14 @@ <0xe690004c 1>, <0xe690006c 1>; interrupt-parent = <&gic>; - interrupts = <0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4 - 0 149 0x4>; + interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH + 0 149 IRQ_TYPE_LEVEL_HIGH>; }; i2c0: i2c@fff20000 { @@ -127,10 +129,10 @@ compatible = "renesas,rmobile-iic"; reg = <0xfff20000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 201 0x4 - 0 202 0x4 - 0 203 0x4 - 0 204 0x4>; + interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH + 0 202 IRQ_TYPE_LEVEL_HIGH + 0 203 IRQ_TYPE_LEVEL_HIGH + 0 204 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -140,10 +142,10 @@ compatible = "renesas,rmobile-iic"; reg = <0xe6c20000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 70 0x4 - 0 71 0x4 - 0 72 0x4 - 0 73 0x4>; + interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH + 0 71 IRQ_TYPE_LEVEL_HIGH + 0 72 IRQ_TYPE_LEVEL_HIGH + 0 73 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -153,6 +155,15 @@ <0xe605800c 0x20>; gpio-controller; #gpio-cells = <2>; + interrupts-extended = + <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>, + <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>, + <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>, + <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>, + <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>, + <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>, + <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>, + <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>; }; tpu: pwm@e6600000 { @@ -162,36 +173,57 @@ #pwm-cells = <3>; }; - mmcif0: mmcif@e6bd0000 { + mmcif0: mmc@e6bd0000 { compatible = "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 56 4 - 0 57 4>; + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH + 0 57 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; - sdhi0: sdhi@e6850000 { + sdhi0: sd@e6850000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6850000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 117 4 - 0 118 4 - 0 119 4>; + interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH + 0 118 IRQ_TYPE_LEVEL_HIGH + 0 119 IRQ_TYPE_LEVEL_HIGH>; cap-sd-highspeed; cap-sdio-irq; status = "disabled"; }; - sdhi1: sdhi@e6860000 { + sdhi1: sd@e6860000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6860000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 121 4 - 0 122 4 - 0 123 4>; + interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH + 0 122 IRQ_TYPE_LEVEL_HIGH + 0 123 IRQ_TYPE_LEVEL_HIGH>; cap-sd-highspeed; cap-sdio-irq; status = "disabled"; }; + + sdhi2: sd@e6870000 { + compatible = "renesas,sdhi-r8a7740"; + reg = <0xe6870000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH + 0 126 IRQ_TYPE_LEVEL_HIGH + 0 127 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sh_fsi2: sound@fe1f0000 { + #sound-dai-cells = <1>; + compatible = "renesas,sh_fsi2"; + reg = <0xfe1f0000 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 9 0x4>; + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts index 969e386e852c..bb62c7a906f4 100644 --- a/arch/arm/boot/dts/r8a7778-bockw-reference.dts +++ b/arch/arm/boot/dts/r8a7778-bockw-reference.dts @@ -15,7 +15,8 @@ */ /dts-v1/; -/include/ "r8a7778.dtsi" +#include "r8a7778.dtsi" +#include / { model = "bockw"; @@ -45,13 +46,65 @@ phy-mode = "mii"; interrupt-parent = <&irqpin>; - interrupts = <0 0>; /* IRQ0: hwirq 0 on irqpin */ + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; reg-io-width = <4>; vddvario-supply = <&fixedregulator3v3>; vdd33a-supply = <&fixedregulator3v3>; }; + +}; + +&mmcif { + pinctrl-0 = <&mmc_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&fixedregulator3v3>; + bus-width = <8>; + broken-cd; + status = "okay"; }; &irqpin { status = "okay"; }; + +&pfc { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + + scif0_pins: serial0 { + renesas,groups = "scif0_data_a", "scif0_ctrl"; + renesas,function = "scif0"; + }; + + mmc_pins: mmc { + renesas,groups = "mmc_data8", "mmc_ctrl"; + renesas,function = "mmc"; + }; + + sdhi0_pins: sd0 { + renesas,groups = "sdhi0_data4", "sdhi0_ctrl", + "sdhi0_cd", "sdhi0_wp"; + renesas,function = "sdhi0"; + }; + + hspi0_pins: hspi0 { + renesas,groups = "hspi0_a"; + renesas,function = "hspi0"; + }; +}; + +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&fixedregulator3v3>; + bus-width = <4>; + status = "okay"; +}; + +&hspi0 { + pinctrl-0 = <&hspi0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7778-bockw.dts b/arch/arm/boot/dts/r8a7778-bockw.dts index 12bbebc9c955..46a884d45175 100644 --- a/arch/arm/boot/dts/r8a7778-bockw.dts +++ b/arch/arm/boot/dts/r8a7778-bockw.dts @@ -15,7 +15,7 @@ */ /dts-v1/; -/include/ "r8a7778.dtsi" +#include "r8a7778.dtsi" / { model = "bockw"; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index a6308a399e2d..ddb3bd7a8838 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -16,6 +16,8 @@ /include/ "skeleton.dtsi" +#include + / { compatible = "renesas,r8a7778"; @@ -25,6 +27,12 @@ }; }; + aliases { + spi0 = &hspi0; + spi1 = &hspi1; + spi2 = &hspi2; + }; + gic: interrupt-controller@fe438000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; @@ -35,7 +43,7 @@ /* irqpin: IRQ0 - IRQ3 */ irqpin: irqpin@fe78001c { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-r8a7778", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; status = "disabled"; /* default off */ @@ -45,10 +53,10 @@ <0xfe780044 4>, <0xfe780064 4>; interrupt-parent = <&gic>; - interrupts = <0 27 0x4 - 0 28 0x4 - 0 29 0x4 - 0 30 0x4>; + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH + 0 28 IRQ_TYPE_LEVEL_HIGH + 0 29 IRQ_TYPE_LEVEL_HIGH + 0 30 IRQ_TYPE_LEVEL_HIGH>; sense-bitfield-width = <2>; }; @@ -56,7 +64,7 @@ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 103 0x4>; + interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -68,7 +76,7 @@ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 103 0x4>; + interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -80,7 +88,7 @@ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 103 0x4>; + interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -92,7 +100,7 @@ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 103 0x4>; + interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -104,7 +112,7 @@ compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 103 0x4>; + interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 27>; @@ -114,6 +122,148 @@ pfc: pfc@fffc0000 { compatible = "renesas,pfc-r8a7778"; - reg = <0xfffc000 0x118>; + reg = <0xfffc0000 0x118>; + }; + + i2c0: i2c@ffc70000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc70000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2c1: i2c@ffc71000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc71000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2c2: i2c@ffc72000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc72000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2c3: i2c@ffc73000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc73000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + mmcif: mmc@ffe4e000 { + compatible = "renesas,sh-mmcif"; + reg = <0xffe4e000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + sdhi0: sd@ffe4c000 { + compatible = "renesas,sdhi-r8a7778"; + reg = <0xffe4c000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sdhi1: sd@ffe4d000 { + compatible = "renesas,sdhi-r8a7778"; + reg = <0xffe4d000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sdhi2: sd@ffe4f000 { + compatible = "renesas,sdhi-r8a7778"; + reg = <0xffe4f000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + i2c0: i2c@ffc70000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc70000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2c1: i2c@ffc71000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc71000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2c2: i2c@ffc72000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc72000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2c3: i2c@ffc73000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7778"; + reg = <0xffc73000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hspi0: spi@fffc7000 { + compatible = "renesas,hspi"; + reg = <0xfffc7000 0x18>; + interrupt-controller = <&gic>; + interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hspi1: spi@fffc8000 { + compatible = "renesas,hspi"; + reg = <0xfffc8000 0x18>; + interrupt-controller = <&gic>; + interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hspi2: spi@fffc6000 { + compatible = "renesas,hspi"; + reg = <0xfffc6000 0x18>; + interrupt-controller = <&gic>; + interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/r8a7779-marzen-reference.dts b/arch/arm/boot/dts/r8a7779-marzen-reference.dts index ab4110aa3c3b..76f5eef7d1cc 100644 --- a/arch/arm/boot/dts/r8a7779-marzen-reference.dts +++ b/arch/arm/boot/dts/r8a7779-marzen-reference.dts @@ -10,8 +10,9 @@ */ /dts-v1/; -/include/ "r8a7779.dtsi" +#include "r8a7779.dtsi" #include +#include / { model = "marzen"; @@ -43,7 +44,7 @@ phy-mode = "mii"; interrupt-parent = <&irqpin0>; - interrupts = <1 0>; /* IRQ1: hwirq 1 on irqpin0 */ + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; reg-io-width = <4>; vddvario-supply = <&fixedregulator3v3>; vdd33a-supply = <&fixedregulator3v3>; @@ -68,7 +69,7 @@ }; &pfc { - pinctrl-0 = <&scif2_pins &scif4_pins &sdhi0_pins>; + pinctrl-0 = <&scif2_pins &scif4_pins>; pinctrl-names = "default"; lan0_pins: lan0 { @@ -82,19 +83,38 @@ }; }; - scif2_pins: scif2 { + scif2_pins: serial2 { renesas,groups = "scif2_data_c"; renesas,function = "scif2"; }; - scif4_pins: scif4 { + scif4_pins: serial4 { renesas,groups = "scif4_data"; renesas,function = "scif4"; }; - sdhi0_pins: sdhi0 { - renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd", - "sdhi0_wp"; + sdhi0_pins: sd0 { + renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd"; renesas,function = "sdhi0"; }; + + hspi0_pins: hspi0 { + renesas,groups = "hspi0"; + renesas,function = "hspi0"; + }; +}; + +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&fixedregulator3v3>; + bus-width = <4>; + status = "okay"; +}; + +&hspi0 { + pinctrl-0 = <&hspi0_pins>; + pinctrl-names = "default"; + status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index f3f7f7999736..a7af2c2371f2 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -10,7 +10,7 @@ */ /dts-v1/; -/include/ "r8a7779.dtsi" +#include "r8a7779.dtsi" / { model = "marzen"; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 19faeac3fd2e..d0561d4c7c46 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -11,6 +11,8 @@ /include/ "skeleton.dtsi" +#include + / { compatible = "renesas,r8a7779"; @@ -40,6 +42,12 @@ }; }; + aliases { + spi0 = &hspi0; + spi1 = &hspi1; + spi2 = &hspi2; + }; + gic: interrupt-controller@f0001000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; @@ -52,7 +60,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 141 0x4>; + interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -64,7 +72,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 142 0x4>; + interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -76,7 +84,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 143 0x4>; + interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -88,7 +96,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 144 0x4>; + interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -100,7 +108,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 145 0x4>; + interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -112,7 +120,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc45000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 146 0x4>; + interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -124,7 +132,7 @@ compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc46000 0x2c>; interrupt-parent = <&gic>; - interrupts = <0 147 0x4>; + interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 9>; @@ -133,7 +141,7 @@ }; irqpin0: irqpin@fe780010 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-r8a7779", "renesas,intc-irqpin"; #interrupt-cells = <2>; status = "disabled"; interrupt-controller; @@ -143,50 +151,50 @@ <0xfe780044 4>, <0xfe780064 4>; interrupt-parent = <&gic>; - interrupts = <0 27 0x4 - 0 28 0x4 - 0 29 0x4 - 0 30 0x4>; + interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH + 0 28 IRQ_TYPE_LEVEL_HIGH + 0 29 IRQ_TYPE_LEVEL_HIGH + 0 30 IRQ_TYPE_LEVEL_HIGH>; sense-bitfield-width = <2>; }; i2c0: i2c@ffc70000 { #address-cells = <1>; #size-cells = <0>; - compatible = "renesas,rmobile-iic"; + compatible = "renesas,i2c-r8a7779"; reg = <0xffc70000 0x1000>; interrupt-parent = <&gic>; - interrupts = <0 79 0x4>; + interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; i2c1: i2c@ffc71000 { #address-cells = <1>; #size-cells = <0>; - compatible = "renesas,rmobile-iic"; + compatible = "renesas,i2c-r8a7779"; reg = <0xffc71000 0x1000>; interrupt-parent = <&gic>; - interrupts = <0 82 0x4>; + interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; i2c2: i2c@ffc72000 { #address-cells = <1>; #size-cells = <0>; - compatible = "renesas,rmobile-iic"; + compatible = "renesas,i2c-r8a7779"; reg = <0xffc72000 0x1000>; interrupt-parent = <&gic>; - interrupts = <0 80 0x4>; + interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; i2c3: i2c@ffc73000 { #address-cells = <1>; #size-cells = <0>; - compatible = "renesas,rmobile-iic"; + compatible = "renesas,i2c-r8a7779"; reg = <0xffc73000 0x1000>; interrupt-parent = <&gic>; - interrupts = <0 81 0x4>; + interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -204,6 +212,70 @@ compatible = "renesas,rcar-sata"; reg = <0xfc600000 0x2000>; interrupt-parent = <&gic>; - interrupts = <0 100 0x4>; + interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + }; + + sdhi0: sd@ffe4c000 { + compatible = "renesas,sdhi-r8a7779"; + reg = <0xffe4c000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sdhi1: sd@ffe4d000 { + compatible = "renesas,sdhi-r8a7779"; + reg = <0xffe4d000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sdhi2: sd@ffe4e000 { + compatible = "renesas,sdhi-r8a7779"; + reg = <0xffe4e000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + sdhi3: sd@ffe4f000 { + compatible = "renesas,sdhi-r8a7779"; + reg = <0xffe4f000 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + cap-sd-highspeed; + cap-sdio-irq; + status = "disabled"; + }; + + hspi0: spi@fffc7000 { + compatible = "renesas,hspi"; + reg = <0xfffc7000 0x18>; + interrupt-controller = <&gic>; + interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hspi1: spi@fffc8000 { + compatible = "renesas,hspi"; + reg = <0xfffc8000 0x18>; + interrupt-controller = <&gic>; + interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + hspi2: spi@fffc6000 { + compatible = "renesas,hspi"; + reg = <0xfffc6000 0x18>; + interrupt-controller = <&gic>; + interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts b/arch/arm/boot/dts/r8a7790-lager-reference.dts deleted file mode 100644 index c462ef138922..000000000000 --- a/arch/arm/boot/dts/r8a7790-lager-reference.dts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Device Tree Source for the Lager board - * - * Copyright (C) 2013 Renesas Solutions Corp. - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -/dts-v1/; -/include/ "r8a7790.dtsi" -#include - -/ { - model = "Lager"; - compatible = "renesas,lager-reference", "renesas,r8a7790"; - - chosen { - bootargs = "console=ttySC6,115200 ignore_loglevel rw"; - }; - - memory@40000000 { - device_type = "memory"; - reg = <0 0x40000000 0 0x80000000>; - }; - - lbsc { - #address-cells = <1>; - #size-cells = <1>; - }; - - leds { - compatible = "gpio-leds"; - led6 { - gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>; - }; - led7 { - gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>; - }; - led8 { - gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>; - }; - }; -}; diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 203bd089af29..57569cba1528 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -9,7 +9,8 @@ */ /dts-v1/; -/include/ "r8a7790.dtsi" +#include "r8a7790.dtsi" +#include / { model = "Lager"; @@ -24,8 +25,69 @@ reg = <0 0x40000000 0 0x80000000>; }; + memory@180000000 { + device_type = "memory"; + reg = <1 0x80000000 0 0x80000000>; + }; + lbsc { #address-cells = <1>; #size-cells = <1>; }; + + leds { + compatible = "gpio-leds"; + led6 { + gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>; + }; + led7 { + gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>; + }; + led8 { + gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>; + }; + }; + + fixedregulator3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&extal_clk { + clock-frequency = <20000000>; +}; + +&pfc { + pinctrl-0 = <&scif0_pins &scif1_pins>; + pinctrl-names = "default"; + + scif0_pins: serial0 { + renesas,groups = "scif0_data"; + renesas,function = "scif0"; + }; + + scif1_pins: serial1 { + renesas,groups = "scif1_data"; + renesas,function = "scif1"; + }; + + mmc1_pins: mmc1 { + renesas,groups = "mmc1_data8", "mmc1_ctrl"; + renesas,function = "mmc1"; + }; +}; + +&mmcif1 { + pinctrl-0 = <&mmc1_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&fixedregulator3v3>; + bus-width = <8>; + non-removable; + status = "okay"; }; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 46e1d7ef163f..f48487c2a970 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -8,6 +8,10 @@ * kind, whether express or implied. */ +#include +#include +#include + / { compatible = "renesas,r8a7790"; interrupt-parent = <&gic>; @@ -84,14 +88,14 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 0xf04>; + interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; interrupt-parent = <&gic>; - interrupts = <0 4 0x4>; + interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -103,7 +107,7 @@ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; interrupt-parent = <&gic>; - interrupts = <0 5 0x4>; + interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -115,7 +119,7 @@ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; interrupt-parent = <&gic>; - interrupts = <0 6 0x4>; + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -127,7 +131,7 @@ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; interrupt-parent = <&gic>; - interrupts = <0 7 0x4>; + interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -139,7 +143,7 @@ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; interrupt-parent = <&gic>; - interrupts = <0 8 0x4>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -151,7 +155,7 @@ compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; interrupt-parent = <&gic>; - interrupts = <0 9 0x4>; + interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -159,21 +163,31 @@ interrupt-controller; }; + thermal@e61f0000 { + compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal"; + reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; + interrupt-parent = <&gic>; + interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + }; + timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; + interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; irqc0: interrupt-controller@e61c0000 { - compatible = "renesas,irqc"; + compatible = "renesas,irqc-r8a7790", "renesas,irqc"; #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; interrupt-parent = <&gic>; - interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>; + interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, + <0 1 IRQ_TYPE_LEVEL_HIGH>, + <0 2 IRQ_TYPE_LEVEL_HIGH>, + <0 3 IRQ_TYPE_LEVEL_HIGH>; }; i2c0: i2c@e6508000 { @@ -182,7 +196,8 @@ compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6508000 0 0x40>; interrupt-parent = <&gic>; - interrupts = <0 287 0x4>; + interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_I2C0>; status = "disabled"; }; @@ -192,7 +207,8 @@ compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6518000 0 0x40>; interrupt-parent = <&gic>; - interrupts = <0 288 0x4>; + interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_I2C1>; status = "disabled"; }; @@ -202,7 +218,8 @@ compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6530000 0 0x40>; interrupt-parent = <&gic>; - interrupts = <0 286 0x4>; + interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_I2C2>; status = "disabled"; }; @@ -212,24 +229,27 @@ compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6540000 0 0x40>; interrupt-parent = <&gic>; - interrupts = <0 290 0x4>; + interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_I2C3>; status = "disabled"; }; mmcif0: mmcif@ee200000 { - compatible = "renesas,sh-mmcif"; + compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; interrupt-parent = <&gic>; - interrupts = <0 169 0x4>; + interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>; reg-io-width = <4>; status = "disabled"; }; - mmcif1: mmcif@ee220000 { - compatible = "renesas,sh-mmcif"; + mmcif1: mmc@ee220000 { + compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; interrupt-parent = <&gic>; - interrupts = <0 170 0x4>; + interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>; reg-io-width = <4>; status = "disabled"; }; @@ -239,39 +259,372 @@ reg = <0 0xe6060000 0 0x250>; }; - sdhi0: sdhi@ee100000 { + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7790"; - reg = <0 0xee100000 0 0x100>; + reg = <0 0xee100000 0 0x200>; interrupt-parent = <&gic>; - interrupts = <0 165 4>; + interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_SDHI0>; cap-sd-highspeed; status = "disabled"; }; - sdhi1: sdhi@ee120000 { + sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a7790"; - reg = <0 0xee120000 0 0x100>; + reg = <0 0xee120000 0 0x200>; interrupt-parent = <&gic>; - interrupts = <0 166 4>; + interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_SDHI1>; cap-sd-highspeed; status = "disabled"; }; - sdhi2: sdhi@ee140000 { + sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee140000 0 0x100>; interrupt-parent = <&gic>; - interrupts = <0 167 4>; + interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_SDHI2>; cap-sd-highspeed; status = "disabled"; }; - sdhi3: sdhi@ee160000 { + sdhi3: sd@ee160000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee160000 0 0x100>; interrupt-parent = <&gic>; - interrupts = <0 168 4>; + interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_SDHI3>; cap-sd-highspeed; status = "disabled"; }; + + clocks { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* External root clock */ + extal_clk: extal_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overriden by the board. */ + clock-frequency = <0>; + clock-output-names = "extal"; + }; + + /* Special CPG clocks */ + cpg_clocks: cpg_clocks@e6150000 { + compatible = "renesas,r8a7790-cpg-clocks", + "renesas,rcar-gen2-cpg-clocks"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>; + #clock-cells = <1>; + clock-output-names = "main", "pll0", "pll1", "pll3", + "lb", "qspi", "sdh", "sd0", "sd1", + "z"; + }; + + /* Variable factor clocks */ + sd2_clk: sd2_clk@e6150078 { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150078 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sd2"; + }; + sd3_clk: sd3_clk@e615007c { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe615007c 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sd3"; + }; + mmc0_clk: mmc0_clk@e6150240 { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150240 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "mmc0"; + }; + mmc1_clk: mmc1_clk@e6150244 { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150244 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "mmc1"; + }; + ssp_clk: ssp_clk@e6150248 { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150248 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "ssp"; + }; + ssprs_clk: ssprs_clk@e615024c { + compatible = "renesas,r8a7790-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe615024c 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "ssprs"; + }; + + /* Fixed factor clocks */ + pll1_div2_clk: pll1_div2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "pll1_div2"; + }; + z2_clk: z2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "z2"; + }; + zg_clk: zg_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "zg"; + }; + zx_clk: zx_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "zx"; + }; + zs_clk: zs_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <6>; + clock-mult = <1>; + clock-output-names = "zs"; + }; + hp_clk: hp_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "hp"; + }; + i_clk: i_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "i"; + }; + b_clk: b_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "b"; + }; + p_clk: p_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <24>; + clock-mult = <1>; + clock-output-names = "p"; + }; + cl_clk: cl_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <48>; + clock-mult = <1>; + clock-output-names = "cl"; + }; + m2_clk: m2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "m2"; + }; + imp_clk: imp_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "imp"; + }; + rclk_clk: rclk_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <(48 * 1024)>; + clock-mult = <1>; + clock-output-names = "rclk"; + }; + oscclk_clk: oscclk_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <(12 * 1024)>; + clock-mult = <1>; + clock-output-names = "oscclk"; + }; + zb3_clk: zb3_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL3>; + #clock-cells = <0>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "zb3"; + }; + zb3d2_clk: zb3d2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL3>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "zb3d2"; + }; + ddr_clk: ddr_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7790_CLK_PLL3>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "ddr"; + }; + mp_clk: mp_clk { + compatible = "fixed-factor-clock"; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-div = <15>; + clock-mult = <1>; + clock-output-names = "mp"; + }; + cp_clk: cp_clk { + compatible = "fixed-factor-clock"; + clocks = <&extal_clk>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "cp"; + }; + + /* Gate clocks */ + mstp0_clks: mstp0_clks@e6150130 { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>; + clocks = <&mp_clk>; + #clock-cells = <1>; + renesas,clock-indices = ; + clock-output-names = "msiof0"; + }; + mstp1_clks: mstp1_clks@e6150134 { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>; + clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, + <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, + <&zs_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 + R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 + R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY + >; + clock-output-names = + "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", + "vsp1-du0", "vsp1-rt", "vsp1-sy"; + }; + mstp2_clks: mstp2_clks@e6150138 { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>; + clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, + <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0 + R8A7790_CLK_MSIOF2 R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1 + R8A7790_CLK_MSIOF1 R8A7790_CLK_MSIOF3 R8A7790_CLK_SCIFB2 + >; + clock-output-names = + "scifa2", "scifa1", "scifa0", "msiof2", "scifb0", + "scifb1", "msiof1", "msiof3", "scifb2"; + }; + mstp3_clks: mstp3_clks@e615013c { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>; + clocks = <&cp_clk>, <&mmc1_clk>, <&sd3_clk>, <&sd2_clk>, + <&cpg_clocks R8A7790_CLK_SD1>, <&cpg_clocks R8A7790_CLK_SD0>, + <&mmc0_clk>, <&rclk_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7790_CLK_TPU0 R8A7790_CLK_MMCIF1 R8A7790_CLK_SDHI3 + R8A7790_CLK_SDHI2 R8A7790_CLK_SDHI1 R8A7790_CLK_SDHI0 + R8A7790_CLK_MMCIF0 R8A7790_CLK_CMT1 + >; + clock-output-names = + "tpu0", "mmcif1", "sdhi3", "sdhi2", + "sdhi1", "sdhi0", "mmcif0", "cmt1"; + }; + mstp5_clks: mstp5_clks@e6150144 { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>; + clocks = <&extal_clk>, <&p_clk>; + #clock-cells = <1>; + renesas,clock-indices = ; + clock-output-names = "thermal", "pwm"; + }; + mstp7_clks: mstp7_clks@e615014c { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>; + clocks = <&mp_clk>, <&mp_clk>, <&zs_clk>, <&zs_clk>, <&p_clk>, + <&p_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>, <&zx_clk>, + <&zx_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7790_CLK_EHCI R8A7790_CLK_HSUSB R8A7790_CLK_HSCIF1 + R8A7790_CLK_HSCIF0 R8A7790_CLK_SCIF1 R8A7790_CLK_SCIF0 + R8A7790_CLK_DU2 R8A7790_CLK_DU1 R8A7790_CLK_DU0 + R8A7790_CLK_LVDS1 R8A7790_CLK_LVDS0 + >; + clock-output-names = + "ehci", "hsusb", "hscif1", "hscif0", "scif1", + "scif0", "du2", "du1", "du0", "lvds1", "lvds0"; + }; + mstp8_clks: mstp8_clks@e6150990 { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>; + clocks = <&p_clk>; + #clock-cells = <1>; + renesas,clock-indices = ; + clock-output-names = "ether"; + }; + mstp9_clks: mstp9_clks@e6150994 { + compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; + clocks = <&p_clk>, <&p_clk>, <&cpg_clocks R8A7790_CLK_QSPI>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7790_CLK_RCAN1 R8A7790_CLK_RCAN0 R8A7790_CLK_QSPI_MOD + R8A7790_CLK_I2C3 R8A7790_CLK_I2C2 R8A7790_CLK_I2C1 + R8A7790_CLK_I2C0 + >; + clock-output-names = + "rcan1", "rcan0", "qspi_mod", "i2c3", "i2c2", "i2c1", "i2c0"; + }; + }; }; diff --git a/arch/arm/boot/dts/r8a7791-koelsch-reference.dts b/arch/arm/boot/dts/r8a7791-koelsch-reference.dts new file mode 100644 index 000000000000..588ca17ea1f0 --- /dev/null +++ b/arch/arm/boot/dts/r8a7791-koelsch-reference.dts @@ -0,0 +1,115 @@ +/* + * Device Tree Source for the Koelsch board + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "r8a7791.dtsi" +#include + +/ { + model = "Koelsch"; + compatible = "renesas,koelsch-reference", "renesas,r8a7791"; + + chosen { + bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; + + lbsc { + #address-cells = <1>; + #size-cells = <1>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + key-a { + gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; + linux,code = <30>; + label = "SW30"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-b { + gpios = <&gpio7 1 GPIO_ACTIVE_LOW>; + linux,code = <48>; + label = "SW31"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-c { + gpios = <&gpio7 2 GPIO_ACTIVE_LOW>; + linux,code = <46>; + label = "SW32"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-d { + gpios = <&gpio7 3 GPIO_ACTIVE_LOW>; + linux,code = <32>; + label = "SW33"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-e { + gpios = <&gpio7 4 GPIO_ACTIVE_LOW>; + linux,code = <18>; + label = "SW34"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-f { + gpios = <&gpio7 5 GPIO_ACTIVE_LOW>; + linux,code = <33>; + label = "SW35"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + key-g { + gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; + linux,code = <34>; + label = "SW36"; + gpio-key,wakeup; + debounce-interval = <20>; + }; + }; + + leds { + compatible = "gpio-leds"; + led6 { + gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>; + }; + led7 { + gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; + }; + led8 { + gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&pfc { + pinctrl-0 = <&scif0_pins &scif1_pins>; + pinctrl-names = "default"; + + scif0_pins: serial0 { + renesas,groups = "scif0_data_d"; + renesas,function = "scif0"; + }; + + scif1_pins: serial1 { + renesas,groups = "scif1_data_d"; + renesas,function = "scif1"; + }; +}; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 1ce5250ec278..fd556c3483e3 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -10,7 +10,8 @@ */ /dts-v1/; -/include/ "r8a7791.dtsi" +#include "r8a7791.dtsi" +#include / { model = "Koelsch"; @@ -29,4 +30,36 @@ #address-cells = <1>; #size-cells = <1>; }; + + leds { + compatible = "gpio-leds"; + led6 { + gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>; + }; + led7 { + gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; + }; + led8 { + gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&extal_clk { + clock-frequency = <20000000>; +}; + +&pfc { + pinctrl-0 = <&scif0_pins &scif1_pins>; + pinctrl-names = "default"; + + scif0_pins: serial0 { + renesas,groups = "scif0_data_d"; + renesas,function = "scif0"; + }; + + scif1_pins: serial1 { + renesas,groups = "scif1_data_d"; + renesas,function = "scif1"; + }; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index fea5cfef4691..19c65509a22d 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -9,6 +9,10 @@ * kind, whether express or implied. */ +#include +#include +#include + / { compatible = "renesas,r8a7791"; interrupt-parent = <&gic>; @@ -43,32 +47,463 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 0xf04>; + interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + + gpio0: gpio@e6050000 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6050000 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 0 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio1: gpio@e6051000 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6051000 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 32 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio2: gpio@e6052000 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6052000 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 64 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio3: gpio@e6053000 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6053000 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 96 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio4: gpio@e6054000 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6054000 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 128 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio5: gpio@e6055000 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6055000 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 160 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio6: gpio@e6055400 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6055400 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 192 32>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + gpio7: gpio@e6055800 { + compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; + reg = <0 0xe6055800 0 0x50>; + interrupt-parent = <&gic>; + interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 224 26>; + #interrupt-cells = <2>; + interrupt-controller; + }; + + thermal@e61f0000 { + compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal"; + reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; + interrupt-parent = <&gic>; + interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; + interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, + <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; irqc0: interrupt-controller@e61c0000 { - compatible = "renesas,irqc"; + compatible = "renesas,irqc-r8a7791", "renesas,irqc"; #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; interrupt-parent = <&gic>; - interrupts = <0 0 4>, - <0 1 4>, - <0 2 4>, - <0 3 4>, - <0 12 4>, - <0 13 4>, - <0 14 4>, - <0 15 4>, - <0 16 4>, - <0 17 4>; + interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, + <0 1 IRQ_TYPE_LEVEL_HIGH>, + <0 2 IRQ_TYPE_LEVEL_HIGH>, + <0 3 IRQ_TYPE_LEVEL_HIGH>, + <0 12 IRQ_TYPE_LEVEL_HIGH>, + <0 13 IRQ_TYPE_LEVEL_HIGH>, + <0 14 IRQ_TYPE_LEVEL_HIGH>, + <0 15 IRQ_TYPE_LEVEL_HIGH>, + <0 16 IRQ_TYPE_LEVEL_HIGH>, + <0 17 IRQ_TYPE_LEVEL_HIGH>; + }; + + pfc: pfc@e6060000 { + compatible = "renesas,pfc-r8a7791"; + reg = <0 0xe6060000 0 0x250>; + #gpio-range-cells = <3>; + }; + + clocks { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* External root clock */ + extal_clk: extal_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overriden by the board. */ + clock-frequency = <0>; + clock-output-names = "extal"; + }; + + /* Special CPG clocks */ + cpg_clocks: cpg_clocks@e6150000 { + compatible = "renesas,r8a7791-cpg-clocks", + "renesas,rcar-gen2-cpg-clocks"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>; + #clock-cells = <1>; + clock-output-names = "main", "pll0", "pll1", "pll3", + "lb", "qspi", "sdh", "sd0", "z"; + }; + + /* Variable factor clocks */ + sd1_clk: sd2_clk@e6150078 { + compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150078 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sd1"; + }; + sd2_clk: sd3_clk@e615007c { + compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe615007c 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "sd2"; + }; + mmc0_clk: mmc0_clk@e6150240 { + compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150240 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "mmc0"; + }; + ssp_clk: ssp_clk@e6150248 { + compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe6150248 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "ssp"; + }; + ssprs_clk: ssprs_clk@e615024c { + compatible = "renesas,r8a7791-div6-clock", "renesas,cpg-div6-clock"; + reg = <0 0xe615024c 0 4>; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-output-names = "ssprs"; + }; + + /* Fixed factor clocks */ + pll1_div2_clk: pll1_div2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "pll1_div2"; + }; + zg_clk: zg_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "zg"; + }; + zx_clk: zx_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "zx"; + }; + zs_clk: zs_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <6>; + clock-mult = <1>; + clock-output-names = "zs"; + }; + hp_clk: hp_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "hp"; + }; + i_clk: i_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "i"; + }; + b_clk: b_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "b"; + }; + p_clk: p_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <24>; + clock-mult = <1>; + clock-output-names = "p"; + }; + cl_clk: cl_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <48>; + clock-mult = <1>; + clock-output-names = "cl"; + }; + m2_clk: m2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "m2"; + }; + imp_clk: imp_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "imp"; + }; + rclk_clk: rclk_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <(48 * 1024)>; + clock-mult = <1>; + clock-output-names = "rclk"; + }; + oscclk_clk: oscclk_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <(12 * 1024)>; + clock-mult = <1>; + clock-output-names = "oscclk"; + }; + zb3_clk: zb3_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL3>; + #clock-cells = <0>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "zb3"; + }; + zb3d2_clk: zb3d2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL3>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "zb3d2"; + }; + ddr_clk: ddr_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7791_CLK_PLL3>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "ddr"; + }; + mp_clk: mp_clk { + compatible = "fixed-factor-clock"; + clocks = <&pll1_div2_clk>; + #clock-cells = <0>; + clock-div = <15>; + clock-mult = <1>; + clock-output-names = "mp"; + }; + cp_clk: cp_clk { + compatible = "fixed-factor-clock"; + clocks = <&extal_clk>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "cp"; + }; + + /* Gate clocks */ + mstp0_clks: mstp0_clks@e6150130 { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150130 0 4>, <0 0xe6150030 0 4>; + clocks = <&mp_clk>; + #clock-cells = <1>; + renesas,clock-indices = ; + clock-output-names = "msiof0"; + }; + mstp1_clks: mstp1_clks@e6150134 { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>; + clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, + <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 + R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 + R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY + >; + clock-output-names = + "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", + "vsp1-du0", "vsp1-sy"; + }; + mstp2_clks: mstp2_clks@e6150138 { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>; + clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, + <&mp_clk>, <&mp_clk>, <&mp_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7791_CLK_SCIFA2 R8A7791_CLK_SCIFA1 R8A7791_CLK_SCIFA0 + R8A7791_CLK_MSIOF2 R8A7791_CLK_SCIFB0 R8A7791_CLK_SCIFB1 + R8A7791_CLK_MSIOF1 R8A7791_CLK_SCIFB2 + >; + clock-output-names = + "scifa2", "scifa1", "scifa0", "misof2", "scifb0", + "scifb1", "msiof1", "scifb2"; + }; + mstp3_clks: mstp3_clks@e615013c { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe615013c 0 4>, <0 0xe6150048 0 4>; + clocks = <&cp_clk>, <&sd2_clk>, <&sd1_clk>, + <&cpg_clocks R8A7791_CLK_SD0>, <&mmc0_clk>, <&rclk_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7791_CLK_TPU0 R8A7791_CLK_SDHI2 R8A7791_CLK_SDHI1 + R8A7791_CLK_SDHI0 R8A7791_CLK_MMCIF0 R8A7791_CLK_CMT1 + >; + clock-output-names = + "tpu0", "sdhi2", "sdhi1", "sdhi0", "mmcif0", "cmt1"; + }; + mstp5_clks: mstp5_clks@e6150144 { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>; + clocks = <&extal_clk>, <&p_clk>; + #clock-cells = <1>; + renesas,clock-indices = ; + clock-output-names = "thermal", "pwm"; + }; + mstp7_clks: mstp7_clks@e615014c { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe615014c 0 4>, <0 0xe61501c4 0 4>; + clocks = <&mp_clk>, <&zs_clk>, <&p_clk>, <&p_clk>, <&zs_clk>, + <&zs_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&zx_clk>, <&zx_clk>, <&zx_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7791_CLK_HSUSB R8A7791_CLK_HSCIF2 R8A7791_CLK_SCIF5 + R8A7791_CLK_SCIF4 R8A7791_CLK_HSCIF1 R8A7791_CLK_HSCIF0 + R8A7791_CLK_SCIF3 R8A7791_CLK_SCIF2 R8A7791_CLK_SCIF1 + R8A7791_CLK_SCIF0 R8A7791_CLK_DU1 R8A7791_CLK_DU0 + R8A7791_CLK_LVDS0 + >; + clock-output-names = + "hsusb", "hscif2", "scif5", "scif4", "hscif1", "hscif0", + "scif3", "scif2", "scif1", "scif0", "du1", "du0", "lvds0"; + }; + mstp8_clks: mstp8_clks@e6150990 { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>; + clocks = <&p_clk>; + #clock-cells = <1>; + renesas,clock-indices = ; + clock-output-names = "ether"; + }; + mstp9_clks: mstp9_clks@e6150994 { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; + clocks = <&p_clk>, <&p_clk>, <&cpg_clocks R8A7791_CLK_QSPI>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7791_CLK_RCAN1 R8A7791_CLK_RCAN0 R8A7791_CLK_QSPI_MOD + R8A7791_CLK_I2C4 R8A7791_CLK_I2C4 R8A7791_CLK_I2C3 + R8A7791_CLK_I2C2 R8A7791_CLK_I2C1 R8A7791_CLK_I2C0 + >; + clock-output-names = + "rcan1", "rcan0", "qspi_mod", "i2c5", "i2c4", "i2c3", + "i2c2", "i2c1", "i2c0"; + }; + mstp11_clks: mstp11_clks@e615099c { + compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe615099c 0 4>, <0 0xe61509ac 0 4>; + clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>; + #clock-cells = <1>; + renesas,clock-indices = < + R8A7791_CLK_SCIFA3 R8A7791_CLK_SCIFA4 R8A7791_CLK_SCIFA5 + >; + clock-output-names = "scifa3", "scifa4", "scifa5"; + }; }; }; diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 5cdaba4cea86..1105558d188b 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -1,6 +1,6 @@ /* * sama5d3.dtsi - Device Tree Include file for SAMA5D3 family SoC - * applies to SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35 SoC + * applies to SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36 SoC * * Copyright (C) 2013 Atmel, * 2013 Ludovic Desroches @@ -13,6 +13,7 @@ #include #include #include +#include / { model = "Atmel SAMA5D3 family SoC"; @@ -36,6 +37,7 @@ i2c2 = &i2c2; ssc0 = &ssc0; ssc1 = &ssc1; + pwm0 = &pwm0; }; cpus { #address-cells = <1>; @@ -56,6 +58,14 @@ reg = <0x20000000 0x8000000>; }; + clocks { + adc_op_clk: adc_op_clk{ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <20000000>; + }; + }; + ahb { compatible = "simple-bus"; #address-cells = <1>; @@ -79,6 +89,8 @@ status = "disabled"; #address-cells = <1>; #size-cells = <0>; + clocks = <&mci0_clk>; + clock-names = "mci_clk"; }; spi0: spi@f0004000 { @@ -92,6 +104,8 @@ dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi0>; + clocks = <&spi0_clk>; + clock-names = "spi_clk"; status = "disabled"; }; @@ -101,6 +115,8 @@ interrupts = <38 IRQ_TYPE_LEVEL_HIGH 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; + clocks = <&ssc0_clk>; + clock-names = "pclk"; status = "disabled"; }; @@ -108,6 +124,8 @@ compatible = "atmel,at91sam9x5-tcb"; reg = <0xf0010000 0x100>; interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&tcb0_clk>; + clock-names = "t0_clk"; }; i2c0: i2c@f0014000 { @@ -121,6 +139,7 @@ pinctrl-0 = <&pinctrl_i2c0>; #address-cells = <1>; #size-cells = <0>; + clocks = <&twi0_clk>; status = "disabled"; }; @@ -135,6 +154,7 @@ pinctrl-0 = <&pinctrl_i2c1>; #address-cells = <1>; #size-cells = <0>; + clocks = <&twi1_clk>; status = "disabled"; }; @@ -144,6 +164,8 @@ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart0>; + clocks = <&usart0_clk>; + clock-names = "usart"; status = "disabled"; }; @@ -153,6 +175,17 @@ interrupts = <13 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart1>; + clocks = <&usart1_clk>; + clock-names = "usart"; + status = "disabled"; + }; + + pwm0: pwm@f002c000 { + compatible = "atmel,sama5d3-pwm"; + reg = <0xf002c000 0x300>; + interrupts = <28 IRQ_TYPE_LEVEL_HIGH 4>; + #pwm-cells = <3>; + clocks = <&pwm_clk>; status = "disabled"; }; @@ -174,6 +207,8 @@ status = "disabled"; #address-cells = <1>; #size-cells = <0>; + clocks = <&mci1_clk>; + clock-names = "mci_clk"; }; spi1: spi@f8008000 { @@ -187,6 +222,8 @@ dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1>; + clocks = <&spi1_clk>; + clock-names = "spi_clk"; status = "disabled"; }; @@ -196,6 +233,8 @@ interrupts = <39 IRQ_TYPE_LEVEL_HIGH 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ssc1_tx &pinctrl_ssc1_rx>; + clocks = <&ssc1_clk>; + clock-names = "pclk"; status = "disabled"; }; @@ -219,6 +258,9 @@ &pinctrl_adc0_ad10 &pinctrl_adc0_ad11 >; + clocks = <&adc_clk>, + <&adc_op_clk>; + clock-names = "adc_clk", "adc_op_clk"; atmel,adc-channel-base = <0x50>; atmel,adc-channels-used = <0xfff>; atmel,adc-drdy-mask = <0x1000000>; @@ -272,8 +314,11 @@ dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(11)>, <&dma1 2 AT91_DMA_CFG_PER_ID(12)>; dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; #address-cells = <1>; #size-cells = <0>; + clocks = <&twi2_clk>; status = "disabled"; }; @@ -283,6 +328,8 @@ interrupts = <14 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart2>; + clocks = <&usart2_clk>; + clock-names = "usart"; status = "disabled"; }; @@ -292,25 +339,41 @@ interrupts = <15 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usart3>; + clocks = <&usart3_clk>; + clock-names = "usart"; status = "disabled"; }; sha@f8034000 { - compatible = "atmel,sam9g46-sha"; + compatible = "atmel,at91sam9g46-sha"; reg = <0xf8034000 0x100>; interrupts = <42 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(17)>; + dma-names = "tx"; + clocks = <&sha_clk>; + clock-names = "sha_clk"; }; aes@f8038000 { - compatible = "atmel,sam9g46-aes"; + compatible = "atmel,at91sam9g46-aes"; reg = <0xf8038000 0x100>; - interrupts = <43 4 0>; + interrupts = <43 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(18)>, + <&dma1 2 AT91_DMA_CFG_PER_ID(19)>; + dma-names = "tx", "rx"; + clocks = <&aes_clk>; + clock-names = "aes_clk"; }; tdes@f803c000 { - compatible = "atmel,sam9g46-tdes"; + compatible = "atmel,at91sam9g46-tdes"; reg = <0xf803c000 0x100>; interrupts = <44 IRQ_TYPE_LEVEL_HIGH 0>; + dmas = <&dma1 2 AT91_DMA_CFG_PER_ID(20)>, + <&dma1 2 AT91_DMA_CFG_PER_ID(21)>; + dma-names = "tx", "rx"; + clocks = <&tdes_clk>; + clock-names = "tdes_clk"; }; dma0: dma-controller@ffffe600 { @@ -318,6 +381,8 @@ reg = <0xffffe600 0x200>; interrupts = <30 IRQ_TYPE_LEVEL_HIGH 0>; #dma-cells = <2>; + clocks = <&dma0_clk>; + clock-names = "dma_clk"; }; dma1: dma-controller@ffffe800 { @@ -325,6 +390,8 @@ reg = <0xffffe800 0x200>; interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>; #dma-cells = <2>; + clocks = <&dma1_clk>; + clock-names = "dma_clk"; }; ramc0: ramc@ffffea00 { @@ -338,6 +405,8 @@ interrupts = <2 IRQ_TYPE_LEVEL_HIGH 7>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dbgu>; + clocks = <&dbgu_clk>; + clock-names = "usart"; status = "disabled"; }; @@ -443,6 +512,14 @@ }; }; + i2c2 { + pinctrl_i2c2: i2c2-0 { + atmel,pins = + ; /* TWCK2 pin, conflicts with LCDDAT19, ISI_D3 */ + }; + }; + isi { pinctrl_isi: isi-0 { atmel,pins = @@ -626,6 +703,7 @@ gpio-controller; interrupt-controller; #interrupt-cells = <2>; + clocks = <&pioA_clk>; }; pioB: gpio@fffff400 { @@ -636,6 +714,7 @@ gpio-controller; interrupt-controller; #interrupt-cells = <2>; + clocks = <&pioB_clk>; }; pioC: gpio@fffff600 { @@ -646,6 +725,7 @@ gpio-controller; interrupt-controller; #interrupt-cells = <2>; + clocks = <&pioC_clk>; }; pioD: gpio@fffff800 { @@ -656,6 +736,7 @@ gpio-controller; interrupt-controller; #interrupt-cells = <2>; + clocks = <&pioD_clk>; }; pioE: gpio@fffffa00 { @@ -666,12 +747,334 @@ gpio-controller; interrupt-controller; #interrupt-cells = <2>; + clocks = <&pioE_clk>; }; }; pmc: pmc@fffffc00 { - compatible = "atmel,at91rm9200-pmc"; + compatible = "atmel,sama5d3-pmc"; reg = <0xfffffc00 0x120>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + + clk32k: slck { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + main: mainck { + compatible = "atmel,at91rm9200-clk-main"; + #clock-cells = <0>; + interrupt-parent = <&pmc>; + interrupts = ; + clocks = <&clk32k>; + }; + + plla: pllack { + compatible = "atmel,sama5d3-clk-pll"; + #clock-cells = <0>; + interrupt-parent = <&pmc>; + interrupts = ; + clocks = <&main>; + reg = <0>; + atmel,clk-input-range = <8000000 50000000>; + #atmel,pll-clk-output-range-cells = <4>; + atmel,pll-clk-output-ranges = <400000000 1000000000 0 0>; + }; + + plladiv: plladivck { + compatible = "atmel,at91sam9x5-clk-plldiv"; + #clock-cells = <0>; + clocks = <&plla>; + }; + + utmi: utmick { + compatible = "atmel,at91sam9x5-clk-utmi"; + #clock-cells = <0>; + interrupt-parent = <&pmc>; + interrupts = ; + clocks = <&main>; + }; + + mck: masterck { + compatible = "atmel,at91sam9x5-clk-master"; + #clock-cells = <0>; + interrupt-parent = <&pmc>; + interrupts = ; + clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>; + atmel,clk-output-range = <0 166000000>; + atmel,clk-divisors = <1 2 4 3>; + }; + + usb: usbck { + compatible = "atmel,at91sam9x5-clk-usb"; + #clock-cells = <0>; + clocks = <&plladiv>, <&utmi>; + }; + + prog: progck { + compatible = "atmel,at91sam9x5-clk-programmable"; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&pmc>; + clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>; + + prog0: prog0 { + #clock-cells = <0>; + reg = <0>; + interrupts = ; + }; + + prog1: prog1 { + #clock-cells = <0>; + reg = <1>; + interrupts = ; + }; + + prog2: prog2 { + #clock-cells = <0>; + reg = <2>; + interrupts = ; + }; + }; + + smd: smdclk { + compatible = "atmel,at91sam9x5-clk-smd"; + #clock-cells = <0>; + clocks = <&plladiv>, <&utmi>; + }; + + systemck { + compatible = "atmel,at91rm9200-clk-system"; + #address-cells = <1>; + #size-cells = <0>; + + ddrck: ddrck { + #clock-cells = <0>; + reg = <2>; + clocks = <&mck>; + }; + + smdck: smdck { + #clock-cells = <0>; + reg = <4>; + clocks = <&smd>; + }; + + uhpck: uhpck { + #clock-cells = <0>; + reg = <6>; + clocks = <&usb>; + }; + + udpck: udpck { + #clock-cells = <0>; + reg = <7>; + clocks = <&usb>; + }; + + pck0: pck0 { + #clock-cells = <0>; + reg = <8>; + clocks = <&prog0>; + }; + + pck1: pck1 { + #clock-cells = <0>; + reg = <9>; + clocks = <&prog1>; + }; + + pck2: pck2 { + #clock-cells = <0>; + reg = <10>; + clocks = <&prog2>; + }; + }; + + periphck { + compatible = "atmel,at91sam9x5-clk-peripheral"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&mck>; + + dbgu_clk: dbgu_clk { + #clock-cells = <0>; + reg = <2>; + }; + + pioA_clk: pioA_clk { + #clock-cells = <0>; + reg = <6>; + }; + + pioB_clk: pioB_clk { + #clock-cells = <0>; + reg = <7>; + }; + + pioC_clk: pioC_clk { + #clock-cells = <0>; + reg = <8>; + }; + + pioD_clk: pioD_clk { + #clock-cells = <0>; + reg = <9>; + }; + + pioE_clk: pioE_clk { + #clock-cells = <0>; + reg = <10>; + }; + + usart0_clk: usart0_clk { + #clock-cells = <0>; + reg = <12>; + atmel,clk-output-range = <0 66000000>; + }; + + usart1_clk: usart1_clk { + #clock-cells = <0>; + reg = <13>; + atmel,clk-output-range = <0 66000000>; + }; + + usart2_clk: usart2_clk { + #clock-cells = <0>; + reg = <14>; + atmel,clk-output-range = <0 66000000>; + }; + + usart3_clk: usart3_clk { + #clock-cells = <0>; + reg = <15>; + atmel,clk-output-range = <0 66000000>; + }; + + twi0_clk: twi0_clk { + reg = <18>; + #clock-cells = <0>; + atmel,clk-output-range = <0 16625000>; + }; + + twi1_clk: twi1_clk { + #clock-cells = <0>; + reg = <19>; + atmel,clk-output-range = <0 16625000>; + }; + + twi2_clk: twi2_clk { + #clock-cells = <0>; + reg = <20>; + atmel,clk-output-range = <0 16625000>; + }; + + mci0_clk: mci0_clk { + #clock-cells = <0>; + reg = <21>; + }; + + mci1_clk: mci1_clk { + #clock-cells = <0>; + reg = <22>; + }; + + spi0_clk: spi0_clk { + #clock-cells = <0>; + reg = <24>; + atmel,clk-output-range = <0 133000000>; + }; + + spi1_clk: spi1_clk { + #clock-cells = <0>; + reg = <25>; + atmel,clk-output-range = <0 133000000>; + }; + + tcb0_clk: tcb0_clk { + #clock-cells = <0>; + reg = <26>; + atmel,clk-output-range = <0 133000000>; + }; + + pwm_clk: pwm_clk { + #clock-cells = <0>; + reg = <28>; + }; + + adc_clk: adc_clk { + #clock-cells = <0>; + reg = <29>; + atmel,clk-output-range = <0 66000000>; + }; + + dma0_clk: dma0_clk { + #clock-cells = <0>; + reg = <30>; + }; + + dma1_clk: dma1_clk { + #clock-cells = <0>; + reg = <31>; + }; + + uhphs_clk: uhphs_clk { + #clock-cells = <0>; + reg = <32>; + }; + + udphs_clk: udphs_clk { + #clock-cells = <0>; + reg = <33>; + }; + + isi_clk: isi_clk { + #clock-cells = <0>; + reg = <37>; + }; + + ssc0_clk: ssc0_clk { + #clock-cells = <0>; + reg = <38>; + atmel,clk-output-range = <0 66000000>; + }; + + ssc1_clk: ssc1_clk { + #clock-cells = <0>; + reg = <39>; + atmel,clk-output-range = <0 66000000>; + }; + + sha_clk: sha_clk { + #clock-cells = <0>; + reg = <42>; + }; + + aes_clk: aes_clk { + #clock-cells = <0>; + reg = <43>; + }; + + tdes_clk: tdes_clk { + #clock-cells = <0>; + reg = <44>; + }; + + trng_clk: trng_clk { + #clock-cells = <0>; + reg = <45>; + }; + + fuse_clk: fuse_clk { + #clock-cells = <0>; + reg = <48>; + }; + }; }; rstc@fffffe00 { @@ -683,6 +1086,7 @@ compatible = "atmel,at91sam9260-pit"; reg = <0xfffffe30 0xf>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&mck>; }; watchdog@fffffe40 { @@ -705,6 +1109,8 @@ reg = <0x00500000 0x100000 0xf8030000 0x4000>; interrupts = <33 IRQ_TYPE_LEVEL_HIGH 2>; + clocks = <&udphs_clk>, <&utmi>; + clock-names = "pclk", "hclk"; status = "disabled"; ep0 { @@ -817,6 +1223,9 @@ compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; + clocks = <&usb>, <&uhphs_clk>, <&udphs_clk>, + <&uhpck>; + clock-names = "usb_clk", "ohci_clk", "hclk", "uhpck"; status = "disabled"; }; @@ -824,6 +1233,8 @@ compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; reg = <0x00700000 0x100000>; interrupts = <32 IRQ_TYPE_LEVEL_HIGH 2>; + clocks = <&usb>, <&uhphs_clk>, <&uhpck>; + clock-names = "usb_clk", "ehci_clk", "uhpck"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sama5d36.dtsi b/arch/arm/boot/dts/sama5d36.dtsi new file mode 100644 index 000000000000..6c31c26e6cc0 --- /dev/null +++ b/arch/arm/boot/dts/sama5d36.dtsi @@ -0,0 +1,20 @@ +/* + * sama5d36.dtsi - Device Tree Include file for SAMA5D36 SoC + * + * Copyright (C) 2013 Atmel, + * 2013 Josh Wu + * + * Licensed under GPLv2 or later. + */ +#include "sama5d3.dtsi" +#include "sama5d3_can.dtsi" +#include "sama5d3_emac.dtsi" +#include "sama5d3_gmac.dtsi" +#include "sama5d3_lcd.dtsi" +#include "sama5d3_mci2.dtsi" +#include "sama5d3_tcb1.dtsi" +#include "sama5d3_uart.dtsi" + +/ { + compatible = "atmel,samad36", "atmel,sama5d3", "atmel,sama5"; +}; diff --git a/arch/arm/boot/dts/sama5d36ek.dts b/arch/arm/boot/dts/sama5d36ek.dts new file mode 100644 index 000000000000..59576c6f9826 --- /dev/null +++ b/arch/arm/boot/dts/sama5d36ek.dts @@ -0,0 +1,53 @@ +/* + * sama5d36ek.dts - Device Tree file for SAMA5D36-EK board + * + * Copyright (C) 2013 Atmel, + * 2013 Josh Wu + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +#include "sama5d36.dtsi" +#include "sama5d3xmb.dtsi" +#include "sama5d3xdm.dtsi" + +/ { + model = "Atmel SAMA5D36-EK"; + compatible = "atmel,sama5d36ek", "atmel,sama5d3xmb", "atmel,sama5d3xcm", "atmel,sama5d36", "atmel,sama5d3", "atmel,sama5"; + + ahb { + apb { + spi0: spi@f0004000 { + status = "okay"; + }; + + ssc0: ssc@f0008000 { + status = "okay"; + }; + + can0: can@f000c000 { + status = "okay"; + }; + + i2c0: i2c@f0014000 { + status = "okay"; + }; + + i2c1: i2c@f0018000 { + status = "okay"; + }; + + macb0: ethernet@f0028000 { + status = "okay"; + }; + + macb1: ethernet@f802c000 { + status = "okay"; + }; + }; + }; + + sound { + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/sama5d3_can.dtsi b/arch/arm/boot/dts/sama5d3_can.dtsi index 8ed3260cef66..a0775851cce5 100644 --- a/arch/arm/boot/dts/sama5d3_can.dtsi +++ b/arch/arm/boot/dts/sama5d3_can.dtsi @@ -32,12 +32,30 @@ }; + pmc: pmc@fffffc00 { + periphck { + can0_clk: can0_clk { + #clock-cells = <0>; + reg = <40>; + atmel,clk-output-range = <0 66000000>; + }; + + can1_clk: can0_clk { + #clock-cells = <0>; + reg = <41>; + atmel,clk-output-range = <0 66000000>; + }; + }; + }; + can0: can@f000c000 { compatible = "atmel,at91sam9x5-can"; reg = <0xf000c000 0x300>; interrupts = <40 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_can0_rx_tx>; + clocks = <&can0_clk>; + clock-names = "can_clk"; status = "disabled"; }; @@ -47,6 +65,8 @@ interrupts = <41 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_can1_rx_tx>; + clocks = <&can1_clk>; + clock-names = "can_clk"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/sama5d3_emac.dtsi b/arch/arm/boot/dts/sama5d3_emac.dtsi index 4d4f351f1f9f..fe2af9276312 100644 --- a/arch/arm/boot/dts/sama5d3_emac.dtsi +++ b/arch/arm/boot/dts/sama5d3_emac.dtsi @@ -31,12 +31,23 @@ }; }; + pmc: pmc@fffffc00 { + periphck { + macb1_clk: macb1_clk { + #clock-cells = <0>; + reg = <35>; + }; + }; + }; + macb1: ethernet@f802c000 { compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xf802c000 0x100>; interrupts = <35 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_macb1_rmii>; + clocks = <&macb1_clk>, <&macb1_clk>; + clock-names = "hclk", "pclk"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/sama5d3_gmac.dtsi b/arch/arm/boot/dts/sama5d3_gmac.dtsi index 0ba8be30ccd8..a6cb0508762f 100644 --- a/arch/arm/boot/dts/sama5d3_gmac.dtsi +++ b/arch/arm/boot/dts/sama5d3_gmac.dtsi @@ -64,12 +64,23 @@ }; }; + pmc: pmc@fffffc00 { + periphck { + macb0_clk: macb0_clk { + #clock-cells = <0>; + reg = <34>; + }; + }; + }; + macb0: ethernet@f0028000 { compatible = "cdns,pc302-gem", "cdns,gem"; reg = <0xf0028000 0x100>; interrupts = <34 IRQ_TYPE_LEVEL_HIGH 3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_macb0_data_rgmii &pinctrl_macb0_signal_rgmii>; + clocks = <&macb0_clk>, <&macb0_clk>; + clock-names = "hclk", "pclk"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/sama5d3_lcd.dtsi b/arch/arm/boot/dts/sama5d3_lcd.dtsi index 01f52a79f8ba..85d302701565 100644 --- a/arch/arm/boot/dts/sama5d3_lcd.dtsi +++ b/arch/arm/boot/dts/sama5d3_lcd.dtsi @@ -50,6 +50,23 @@ }; }; }; + + pmc: pmc@fffffc00 { + periphck { + lcdc_clk: lcdc_clk { + #clock-cells = <0>; + reg = <36>; + }; + }; + + systemck { + lcdck: lcdck { + #clock-cells = <0>; + reg = <3>; + clocks = <&mck>; + }; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/sama5d3_mci2.dtsi b/arch/arm/boot/dts/sama5d3_mci2.dtsi index 38e88e39e551..b029fe7ef17a 100644 --- a/arch/arm/boot/dts/sama5d3_mci2.dtsi +++ b/arch/arm/boot/dts/sama5d3_mci2.dtsi @@ -9,6 +9,7 @@ #include #include +#include / { ahb { @@ -30,6 +31,15 @@ }; }; + pmc: pmc@fffffc00 { + periphck { + mci2_clk: mci2_clk { + #clock-cells = <0>; + reg = <23>; + }; + }; + }; + mmc2: mmc@f8004000 { compatible = "atmel,hsmci"; reg = <0xf8004000 0x600>; @@ -38,6 +48,8 @@ dma-names = "rxtx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc2_clk_cmd_dat0 &pinctrl_mmc2_dat1_3>; + clocks = <&mci2_clk>; + clock-names = "mci_clk"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sama5d3_tcb1.dtsi b/arch/arm/boot/dts/sama5d3_tcb1.dtsi index 5264bb4a6998..382b04431f66 100644 --- a/arch/arm/boot/dts/sama5d3_tcb1.dtsi +++ b/arch/arm/boot/dts/sama5d3_tcb1.dtsi @@ -9,6 +9,7 @@ #include #include +#include / { aliases { @@ -17,10 +18,21 @@ ahb { apb { + pmc: pmc@fffffc00 { + periphck { + tcb1_clk: tcb1_clk { + #clock-cells = <0>; + reg = <27>; + }; + }; + }; + tcb1: timer@f8014000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xf8014000 0x100>; interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&tcb1_clk>; + clock-names = "t0_clk"; }; }; }; diff --git a/arch/arm/boot/dts/sama5d3_uart.dtsi b/arch/arm/boot/dts/sama5d3_uart.dtsi index 98fcb2d57446..a9fa75e41652 100644 --- a/arch/arm/boot/dts/sama5d3_uart.dtsi +++ b/arch/arm/boot/dts/sama5d3_uart.dtsi @@ -9,8 +9,14 @@ #include #include +#include / { + aliases { + serial5 = &uart0; + serial6 = &uart1; + }; + ahb { apb { pinctrl@fffff200 { @@ -31,12 +37,30 @@ }; }; + pmc: pmc@fffffc00 { + periphck { + uart0_clk: uart0_clk { + #clock-cells = <0>; + reg = <16>; + atmel,clk-output-range = <0 66000000>; + }; + + uart1_clk: uart1_clk { + #clock-cells = <0>; + reg = <17>; + atmel,clk-output-range = <0 66000000>; + }; + }; + }; + uart0: serial@f0024000 { compatible = "atmel,at91sam9260-usart"; reg = <0xf0024000 0x200>; interrupts = <16 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart0>; + clocks = <&uart0_clk>; + clock-names = "usart"; status = "disabled"; }; @@ -46,6 +70,8 @@ interrupts = <17 IRQ_TYPE_LEVEL_HIGH 5>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; + clocks = <&uart1_clk>; + clock-names = "usart"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/sama5d3xcm.dtsi b/arch/arm/boot/dts/sama5d3xcm.dtsi index 726a0f35100c..f55ed072c8e6 100644 --- a/arch/arm/boot/dts/sama5d3xcm.dtsi +++ b/arch/arm/boot/dts/sama5d3xcm.dtsi @@ -18,17 +18,6 @@ reg = <0x20000000 0x20000000>; }; - clocks { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - main_clock: clock@0 { - compatible = "atmel,osc", "fixed-clock"; - clock-frequency = <12000000>; - }; - }; - ahb { apb { spi0: spi@f0004000 { @@ -38,6 +27,12 @@ macb0: ethernet@f0028000 { phy-mode = "rgmii"; }; + + pmc: pmc@fffffc00 { + main: mainck { + clock-frequency = <12000000>; + }; + }; }; nand0: nand@60000000 { diff --git a/arch/arm/boot/dts/sama5d3xdm.dtsi b/arch/arm/boot/dts/sama5d3xdm.dtsi index 1c296d6b2f2a..f9bdde542ced 100644 --- a/arch/arm/boot/dts/sama5d3xdm.dtsi +++ b/arch/arm/boot/dts/sama5d3xdm.dtsi @@ -18,6 +18,7 @@ interrupts = <31 0x0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_qt1070_irq>; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/sh7372-mackerel.dts b/arch/arm/boot/dts/sh7372-mackerel.dts index 8acf51e0cdae..a759a276c9a9 100644 --- a/arch/arm/boot/dts/sh7372-mackerel.dts +++ b/arch/arm/boot/dts/sh7372-mackerel.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "sh7372.dtsi" +#include "sh7372.dtsi" / { model = "Mackerel (AP4 EVM 2nd)"; diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts index 8ee06dd81799..eb8886b535e4 100644 --- a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts +++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts @@ -12,8 +12,9 @@ */ /dts-v1/; -/include/ "sh73a0.dtsi" +#include "sh73a0.dtsi" #include +#include / { model = "KZM-A9-GT"; @@ -82,7 +83,7 @@ reg = <0x10000000 0x100>; phy-mode = "mii"; interrupt-parent = <&irqpin0>; - interrupts = <3 0>; /* active low */ + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; reg-io-width = <4>; smsc,irq-push-pull; smsc,save-mac-address; @@ -105,6 +106,66 @@ gpios = <&pfc 23 GPIO_ACTIVE_LOW>; }; }; + + gpio-keys { + compatible = "gpio-keys"; + + back-key { + gpios = <&pcf8575 8 GPIO_ACTIVE_LOW>; + linux,code = <158>; + label = "SW3"; + }; + + right-key { + gpios = <&pcf8575 9 GPIO_ACTIVE_LOW>; + linux,code = <106>; + label = "SW2-R"; + }; + + left-key { + gpios = <&pcf8575 10 GPIO_ACTIVE_LOW>; + linux,code = <105>; + label = "SW2-L"; + }; + + enter-key { + gpios = <&pcf8575 11 GPIO_ACTIVE_LOW>; + linux,code = <28>; + label = "SW2-P"; + }; + + up-key { + gpios = <&pcf8575 12 GPIO_ACTIVE_LOW>; + linux,code = <103>; + label = "SW2-U"; + }; + + down-key { + gpios = <&pcf8575 13 GPIO_ACTIVE_LOW>; + linux,code = <108>; + label = "SW2-D"; + }; + + home-key { + gpios = <&pcf8575 14 GPIO_ACTIVE_LOW>; + linux,code = <102>; + label = "SW1"; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "left_j"; + simple-audio-card,cpu { + sound-dai = <&sh_fsi2 0>; + }; + simple-audio-card,codec { + sound-dai = <&ak4648>; + bitclock-master; + frame-master; + system-clock-frequency = <11289600>; + }; + }; }; &i2c0 { @@ -179,12 +240,29 @@ }; }; }; + + ak4648: ak4648@0x12 { + #sound-dai-cells = <0>; + compatible = "asahi-kasei,ak4648"; + reg = <0x12>; + }; }; &i2c3 { pinctrl-0 = <&i2c3_pins>; pinctrl-names = "default"; status = "okay"; + + pcf8575: gpio@20 { + compatible = "nxp,pcf8575"; + reg = <0x20>; + interrupt-parent = <&irqpin2>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; }; &mmcif { @@ -205,7 +283,7 @@ renesas,function = "i2c3"; }; - mmcif_pins: mmcif { + mmcif_pins: mmc { mux { renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0"; renesas,function = "mmc0"; @@ -217,20 +295,26 @@ }; }; - scifa4_pins: scifa4 { + scifa4_pins: serial4 { renesas,groups = "scifa4_data", "scifa4_ctrl"; renesas,function = "scifa4"; }; - sdhi0_pins: sdhi0 { + sdhi0_pins: sd0 { renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd", "sdhi0_wp"; renesas,function = "sdhi0"; }; - sdhi2_pins: sdhi2 { + sdhi2_pins: sd2 { renesas,groups = "sdhi2_data4", "sdhi2_ctrl"; renesas,function = "sdhi2"; }; + + fsia_pins: sounda { + renesas,groups = "fsia_mclk_in", "fsia_sclk_in", + "fsia_data_in", "fsia_data_out"; + renesas,function = "fsia"; + }; }; &sdhi0 { @@ -251,3 +335,10 @@ broken-cd; status = "okay"; }; + +&sh_fsi2 { + pinctrl-0 = <&fsia_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sh73a0-kzm9g.dts b/arch/arm/boot/dts/sh73a0-kzm9g.dts index 0f1ca7792c46..27c5f426d172 100644 --- a/arch/arm/boot/dts/sh73a0-kzm9g.dts +++ b/arch/arm/boot/dts/sh73a0-kzm9g.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "sh73a0.dtsi" +#include "sh73a0.dtsi" / { model = "KZM-A9-GT"; diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index fcf26889a8a0..b7bd3b9a6753 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -10,6 +10,8 @@ /include/ "skeleton.dtsi" +#include + / { compatible = "renesas,sh73a0"; @@ -40,12 +42,12 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 55 4>, - <0 56 4>; + interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>, + <0 56 IRQ_TYPE_LEVEL_HIGH>; }; irqpin0: irqpin@e6900000 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe6900000 4>, @@ -54,18 +56,18 @@ <0xe6900040 1>, <0xe6900060 1>; interrupt-parent = <&gic>; - interrupts = <0 1 0x4 - 0 2 0x4 - 0 3 0x4 - 0 4 0x4 - 0 5 0x4 - 0 6 0x4 - 0 7 0x4 - 0 8 0x4>; + interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH + 0 2 IRQ_TYPE_LEVEL_HIGH + 0 3 IRQ_TYPE_LEVEL_HIGH + 0 4 IRQ_TYPE_LEVEL_HIGH + 0 5 IRQ_TYPE_LEVEL_HIGH + 0 6 IRQ_TYPE_LEVEL_HIGH + 0 7 IRQ_TYPE_LEVEL_HIGH + 0 8 IRQ_TYPE_LEVEL_HIGH>; }; irqpin1: irqpin@e6900004 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe6900004 4>, @@ -74,19 +76,19 @@ <0xe6900044 1>, <0xe6900064 1>; interrupt-parent = <&gic>; - interrupts = <0 9 0x4 - 0 10 0x4 - 0 11 0x4 - 0 12 0x4 - 0 13 0x4 - 0 14 0x4 - 0 15 0x4 - 0 16 0x4>; + interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH + 0 10 IRQ_TYPE_LEVEL_HIGH + 0 11 IRQ_TYPE_LEVEL_HIGH + 0 12 IRQ_TYPE_LEVEL_HIGH + 0 13 IRQ_TYPE_LEVEL_HIGH + 0 14 IRQ_TYPE_LEVEL_HIGH + 0 15 IRQ_TYPE_LEVEL_HIGH + 0 16 IRQ_TYPE_LEVEL_HIGH>; control-parent; }; irqpin2: irqpin@e6900008 { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe6900008 4>, @@ -95,18 +97,18 @@ <0xe6900048 1>, <0xe6900068 1>; interrupt-parent = <&gic>; - interrupts = <0 17 0x4 - 0 18 0x4 - 0 19 0x4 - 0 20 0x4 - 0 21 0x4 - 0 22 0x4 - 0 23 0x4 - 0 24 0x4>; + interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH + 0 18 IRQ_TYPE_LEVEL_HIGH + 0 19 IRQ_TYPE_LEVEL_HIGH + 0 20 IRQ_TYPE_LEVEL_HIGH + 0 21 IRQ_TYPE_LEVEL_HIGH + 0 22 IRQ_TYPE_LEVEL_HIGH + 0 23 IRQ_TYPE_LEVEL_HIGH + 0 24 IRQ_TYPE_LEVEL_HIGH>; }; irqpin3: irqpin@e690000c { - compatible = "renesas,intc-irqpin"; + compatible = "renesas,intc-irqpin-sh73a0", "renesas,intc-irqpin"; #interrupt-cells = <2>; interrupt-controller; reg = <0xe690000c 4>, @@ -115,14 +117,14 @@ <0xe690004c 1>, <0xe690006c 1>; interrupt-parent = <&gic>; - interrupts = <0 25 0x4 - 0 26 0x4 - 0 27 0x4 - 0 28 0x4 - 0 29 0x4 - 0 30 0x4 - 0 31 0x4 - 0 32 0x4>; + interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH + 0 26 IRQ_TYPE_LEVEL_HIGH + 0 27 IRQ_TYPE_LEVEL_HIGH + 0 28 IRQ_TYPE_LEVEL_HIGH + 0 29 IRQ_TYPE_LEVEL_HIGH + 0 30 IRQ_TYPE_LEVEL_HIGH + 0 31 IRQ_TYPE_LEVEL_HIGH + 0 32 IRQ_TYPE_LEVEL_HIGH>; }; i2c0: i2c@e6820000 { @@ -131,10 +133,10 @@ compatible = "renesas,rmobile-iic"; reg = <0xe6820000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 167 0x4 - 0 168 0x4 - 0 169 0x4 - 0 170 0x4>; + interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH + 0 168 IRQ_TYPE_LEVEL_HIGH + 0 169 IRQ_TYPE_LEVEL_HIGH + 0 170 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -144,10 +146,10 @@ compatible = "renesas,rmobile-iic"; reg = <0xe6822000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 51 0x4 - 0 52 0x4 - 0 53 0x4 - 0 54 0x4>; + interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH + 0 52 IRQ_TYPE_LEVEL_HIGH + 0 53 IRQ_TYPE_LEVEL_HIGH + 0 54 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -157,10 +159,10 @@ compatible = "renesas,rmobile-iic"; reg = <0xe6824000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 171 0x4 - 0 172 0x4 - 0 173 0x4 - 0 174 0x4>; + interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH + 0 172 IRQ_TYPE_LEVEL_HIGH + 0 173 IRQ_TYPE_LEVEL_HIGH + 0 174 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -170,10 +172,10 @@ compatible = "renesas,rmobile-iic"; reg = <0xe6826000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 183 0x4 - 0 184 0x4 - 0 185 0x4 - 0 186 0x4>; + interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH + 0 184 IRQ_TYPE_LEVEL_HIGH + 0 185 IRQ_TYPE_LEVEL_HIGH + 0 186 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; @@ -183,52 +185,52 @@ compatible = "renesas,rmobile-iic"; reg = <0xe6828000 0x425>; interrupt-parent = <&gic>; - interrupts = <0 187 0x4 - 0 188 0x4 - 0 189 0x4 - 0 190 0x4>; + interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH + 0 188 IRQ_TYPE_LEVEL_HIGH + 0 189 IRQ_TYPE_LEVEL_HIGH + 0 190 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; - mmcif: mmcif@e6bd0000 { + mmcif: mmc@e6bd0000 { compatible = "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 140 0x4 - 0 141 0x4>; + interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH + 0 141 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; status = "disabled"; }; - sdhi0: sdhi@ee100000 { - compatible = "renesas,sdhi-r8a7740"; + sdhi0: sd@ee100000 { + compatible = "renesas,sdhi-sh73a0"; reg = <0xee100000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 83 4 - 0 84 4 - 0 85 4>; + interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH + 0 84 IRQ_TYPE_LEVEL_HIGH + 0 85 IRQ_TYPE_LEVEL_HIGH>; cap-sd-highspeed; status = "disabled"; }; /* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */ - sdhi1: sdhi@ee120000 { - compatible = "renesas,sdhi-r8a7740"; + sdhi1: sd@ee120000 { + compatible = "renesas,sdhi-sh73a0"; reg = <0xee120000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 88 4 - 0 89 4>; + interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH + 0 89 IRQ_TYPE_LEVEL_HIGH>; toshiba,mmc-wrprotect-disable; cap-sd-highspeed; status = "disabled"; }; - sdhi2: sdhi@ee140000 { - compatible = "renesas,sdhi-r8a7740"; + sdhi2: sd@ee140000 { + compatible = "renesas,sdhi-sh73a0"; reg = <0xee140000 0x100>; interrupt-parent = <&gic>; - interrupts = <0 104 4 - 0 105 4>; + interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH + 0 105 IRQ_TYPE_LEVEL_HIGH>; toshiba,mmc-wrprotect-disable; cap-sd-highspeed; status = "disabled"; @@ -240,5 +242,23 @@ <0xe605801c 0x1c>; gpio-controller; #gpio-cells = <2>; + interrupts-extended = + <&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>, + <&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>, + <&irqpin1 0 0>, <&irqpin1 1 0>, <&irqpin1 2 0>, <&irqpin1 3 0>, + <&irqpin1 4 0>, <&irqpin1 5 0>, <&irqpin1 6 0>, <&irqpin1 7 0>, + <&irqpin2 0 0>, <&irqpin2 1 0>, <&irqpin2 2 0>, <&irqpin2 3 0>, + <&irqpin2 4 0>, <&irqpin2 5 0>, <&irqpin2 6 0>, <&irqpin2 7 0>, + <&irqpin3 0 0>, <&irqpin3 1 0>, <&irqpin3 2 0>, <&irqpin3 3 0>, + <&irqpin3 4 0>, <&irqpin3 5 0>, <&irqpin3 6 0>, <&irqpin3 7 0>; + }; + + sh_fsi2: sound@ec230000 { + #sound-dai-cells = <1>; + compatible = "renesas,sh_fsi2"; + reg = <0xec230000 0x400>; + interrupt-parent = <&gic>; + interrupts = <0 146 0x4>; + status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index f936476c2753..537f1a5c07f5 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -79,6 +79,8 @@ #dma-cells = <1>; #dma-channels = <8>; #dma-requests = <32>; + clocks = <&l4_main_clk>; + clock-names = "apb_pclk"; }; }; @@ -467,6 +469,8 @@ interrupts = <0 38 0x04>; cache-unified; cache-level = <2>; + arm,tag-latency = <1 1 1>; + arm,data-latency = <2 1 1>; }; /* Local timer */ diff --git a/arch/arm/boot/dts/st-pincfg.h b/arch/arm/boot/dts/st-pincfg.h index 8c45d85ac13e..4851c387d52d 100644 --- a/arch/arm/boot/dts/st-pincfg.h +++ b/arch/arm/boot/dts/st-pincfg.h @@ -15,7 +15,7 @@ /* Pull Up */ #define PU (1 << 26) /* Open Drain */ -#define OD (1 << 26) +#define OD (1 << 25) #define RT (1 << 23) #define INVERTCLK (1 << 22) #define CLKNOTDATA (1 << 21) diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 7da99fe497e1..e0853ea02df2 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -913,6 +913,10 @@ interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + dmas = <&dma 31 0 0x12>, /* Logical - DevToMem - HighPrio */ + <&dma 31 0 0x10>; /* Logical - MemToDev - HighPrio */ + dma-names = "rx", "tx"; + clocks = <&prcc_kclk 1 3>, <&prcc_pclk 1 3>; clock-names = "msp", "apb_pclk"; @@ -925,6 +929,9 @@ interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + dmas = <&dma 30 0 0x10>; /* Logical - MemToDev - HighPrio */ + dma-names = "tx"; + clocks = <&prcc_kclk 1 4>, <&prcc_pclk 1 4>; clock-names = "msp", "apb_pclk"; @@ -938,6 +945,11 @@ interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + dmas = <&dma 14 0 0x12>, /* Logical - DevToMem - HighPrio */ + <&dma 14 1 0x19>; /* Physical Chan 1 - MemToDev + HighPrio - Fixed */ + dma-names = "rx", "tx"; + clocks = <&prcc_kclk 2 3>, <&prcc_pclk 2 5>; clock-names = "msp", "apb_pclk"; @@ -950,6 +962,9 @@ interrupts = <0 62 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; + dmas = <&dma 30 0 0x12>; /* Logical - DevToMem - HighPrio */ + dma-names = "rx"; + clocks = <&prcc_kclk 1 10>, <&prcc_pclk 1 11>; clock-names = "msp", "apb_pclk"; @@ -987,6 +1002,23 @@ status = "disabled"; }; + mcde@a0350000 { + compatible = "stericsson,mcde"; + reg = <0xa0350000 0x1000>, /* MCDE */ + <0xa0351000 0x1000>, /* DSI link 1 */ + <0xa0352000 0x1000>, /* DSI link 2 */ + <0xa0353000 0x1000>; /* DSI link 3 */ + interrupts = <0 48 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&prcmu_clk PRCMU_MCDECLK>, /* Main MCDE clock */ + <&prcmu_clk PRCMU_LCDCLK>, /* LCD clock */ + <&prcmu_clk PRCMU_PLLDSI>, /* HDMI clock */ + <&prcmu_clk PRCMU_DSI0CLK>, /* DSI 0 */ + <&prcmu_clk PRCMU_DSI1CLK>, /* DSI 1 */ + <&prcmu_clk PRCMU_DSI0ESCCLK>, /* TVout clock 0 */ + <&prcmu_clk PRCMU_DSI1ESCCLK>, /* TVout clock 1 */ + <&prcmu_clk PRCMU_DSI2ESCCLK>; /* TVout clock 2 */ + }; + cryp@a03cb000 { compatible = "stericsson,ux500-cryp"; reg = <0xa03cb000 0x1000>; diff --git a/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi new file mode 100644 index 000000000000..addfcc7c2750 --- /dev/null +++ b/arch/arm/boot/dts/ste-href-family-pinctrl.dtsi @@ -0,0 +1,745 @@ +/* + * Copyright 2013 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include "ste-nomadik-pinctrl.dtsi" + +/ { + soc { + pinctrl { + /* Settings for all UART default and sleep states */ + uart0 { + uart0_default_mode: uart0_default { + default_mux { + ste,function = "u0"; + ste,pins = "u0_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ + ste,config = <&in_pu>; + }; + + default_cfg2 { + ste,pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */ + ste,config = <&out_hi>; + }; + }; + + uart0_sleep_mode: uart0_sleep { + sleep_cfg1 { + ste,pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */ + ste,config = <&slpm_in_wkup_pdis>; + }; + + sleep_cfg2 { + ste,pins = "GPIO1_AJ3"; /* RTS */ + ste,config = <&slpm_out_hi_wkup_pdis>; + }; + + sleep_cfg3 { + ste,pins = "GPIO3_AH3"; /* TXD */ + ste,config = <&slpm_out_wkup_pdis>; + }; + }; + }; + + uart1 { + uart1_default_mode: uart1_default { + default_mux { + ste,function = "u1"; + ste,pins = "u1rxtx_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO4_AH6"; /* RXD */ + ste,config = <&in_pu>; + }; + + default_cfg2 { + ste,pins = "GPIO5_AG6"; /* TXD */ + ste,config = <&out_hi>; + }; + }; + + uart1_sleep_mode: uart1_sleep { + sleep_cfg1 { + ste,pins = "GPIO4_AH6"; /* RXD */ + ste,config = <&slpm_in_wkup_pdis>; + }; + + sleep_cfg2 { + ste,pins = "GPIO5_AG6"; /* TXD */ + ste,config = <&slpm_out_wkup_pdis>; + }; + }; + }; + + uart2 { + uart2_default_mode: uart2_default { + default_mux { + ste,function = "u2"; + ste,pins = "u2rxtx_c_1"; + }; + default_cfg1 { + ste,pins = "GPIO29_W2"; /* RXD */ + ste,config = <&in_pu>; + }; + + default_cfg2 { + ste,pins = "GPIO30_W3"; /* TXD */ + ste,config = <&out_hi>; + }; + }; + + uart2_sleep_mode: uart2_sleep { + sleep_cfg1 { + ste,pins = "GPIO29_W2"; /* RXD */ + ste,config = <&in_wkup_pdis>; + }; + + sleep_cfg2 { + ste,pins = "GPIO30_W3"; /* TXD */ + ste,config = <&out_wkup_pdis>; + }; + }; + }; + + /* Settings for all I2C default and sleep states */ + i2c0 { + i2c0_default_mode: i2c_default { + default_mux { + ste,function = "i2c0"; + ste,pins = "i2c0_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ + ste,config = <&in_pu>; + }; + }; + + i2c0_sleep_mode: i2c_sleep { + sleep_cfg1 { + ste,pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + i2c1 { + i2c1_default_mode: i2c_default { + default_mux { + ste,function = "i2c1"; + ste,pins = "i2c1_b_2"; + }; + default_cfg1 { + ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ + ste,config = <&in_pu>; + }; + }; + + i2c1_sleep_mode: i2c_sleep { + sleep_cfg1 { + ste,pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + i2c2 { + i2c2_default_mode: i2c_default { + default_mux { + ste,function = "i2c2"; + ste,pins = "i2c2_b_2"; + }; + default_cfg1 { + ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ + ste,config = <&in_pu>; + }; + }; + + i2c2_sleep_mode: i2c_sleep { + sleep_cfg1 { + ste,pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + i2c3 { + i2c3_default_mode: i2c_default { + default_mux { + ste,function = "i2c3"; + ste,pins = "i2c3_c_2"; + }; + default_cfg1 { + ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ + ste,config = <&in_pu>; + }; + }; + + i2c3_sleep_mode: i2c_sleep { + sleep_cfg1 { + ste,pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + /* + * Activating I2C4 will conflict with UART1 about the same pins so do not + * enable I2C4 and UART1 at the same time. + */ + i2c4 { + i2c4_default_mode: i2c_default { + default_mux { + ste,function = "i2c4"; + ste,pins = "i2c4_b_1"; + }; + default_cfg1 { + ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ + ste,config = <&in_pu>; + }; + }; + + i2c4_sleep_mode: i2c_sleep { + sleep_cfg1 { + ste,pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + /* Settings for all SPI default and sleep states */ + spi2 { + spi2_default_mode: spi_default { + default_mux { + ste,function = "spi2"; + ste,pins = "spi2_oc1_2"; + }; + default_cfg1 { + ste,pins = "GPIO216_AG12"; /* FRM */ + ste,config = <&gpio_out_hi>; + }; + default_cfg2 { + ste,pins = "GPIO218_AH11"; /* RXD */ + ste,config = <&in_pd>; + }; + default_cfg3 { + ste,pins = + "GPIO215_AH13", /* TXD */ + "GPIO217_AH12"; /* CLK */ + ste,config = <&out_lo>; + }; + }; + + spi2_idle_mode: spi_idle { + /* + * The idle mode is basically sleep mode sans wakeups. Also + * note that we have muxes the pins off the function here + * as we do not state any muxing. + */ + idle_cfg1 { + ste,pins = "GPIO218_AH11"; /* RXD */ + ste,config = <&slpm_in_pdis>; + }; + idle_cfg2 { + ste,pins = "GPIO215_AH13"; /* TXD */ + ste,config = <&slpm_out_lo_pdis>; + }; + idle_cfg3 { + ste,pins = "GPIO217_AH12"; /* CLK */ + ste,config = <&slpm_pdis>; + }; + }; + + spi2_sleep_mode: spi_sleep { + sleep_cfg1 { + ste,pins = + "GPIO216_AG12", /* FRM */ + "GPIO218_AH11"; /* RXD */ + ste,config = <&slpm_in_wkup_pdis>; + }; + sleep_cfg2 { + ste,pins = "GPIO215_AH13"; /* TXD */ + ste,config = <&slpm_out_lo_wkup_pdis>; + }; + sleep_cfg3 { + ste,pins = "GPIO217_AH12"; /* CLK */ + ste,config = <&slpm_wkup_pdis>; + }; + }; + }; + + /* Settings for all MMC/SD/SDIO default and sleep states */ + sdi0 { + /* This is the external SD card slot, 4 bits wide */ + sdi0_default_mode: sdi0_default { + default_mux { + ste,function = "mc0"; + ste,pins = "mc0_a_1"; + }; + default_cfg1 { + ste,pins = + "GPIO18_AC2", /* CMDDIR */ + "GPIO19_AC1", /* DAT0DIR */ + "GPIO20_AB4"; /* DAT2DIR */ + ste,config = <&out_hi>; + }; + default_cfg2 { + ste,pins = "GPIO22_AA3"; /* FBCLK */ + ste,config = <&in_nopull>; + }; + default_cfg3 { + ste,pins = "GPIO23_AA4"; /* CLK */ + ste,config = <&out_lo>; + }; + default_cfg4 { + ste,pins = + "GPIO24_AB2", /* CMD */ + "GPIO25_Y4", /* DAT0 */ + "GPIO26_Y2", /* DAT1 */ + "GPIO27_AA2", /* DAT2 */ + "GPIO28_AA1"; /* DAT3 */ + ste,config = <&in_pu>; + }; + }; + + sdi0_sleep_mode: sdi0_sleep { + sleep_cfg1 { + ste,pins = + "GPIO18_AC2", /* CMDDIR */ + "GPIO19_AC1", /* DAT0DIR */ + "GPIO20_AB4"; /* DAT2DIR */ + ste,config = <&slpm_out_hi_wkup_pdis>; + }; + sleep_cfg2 { + ste,pins = + "GPIO22_AA3", /* FBCLK */ + "GPIO24_AB2", /* CMD */ + "GPIO25_Y4", /* DAT0 */ + "GPIO26_Y2", /* DAT1 */ + "GPIO27_AA2", /* DAT2 */ + "GPIO28_AA1"; /* DAT3 */ + ste,config = <&slpm_in_wkup_pdis>; + }; + sleep_cfg3 { + ste,pins = "GPIO23_AA4"; /* CLK */ + ste,config = <&slpm_out_lo_wkup_pdis>; + }; + }; + }; + + sdi1 { + /* This is the WLAN SDIO 4 bits wide */ + sdi1_default_mode: sdi1_default { + default_mux { + ste,function = "mc1"; + ste,pins = "mc1_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO208_AH16"; /* CLK */ + ste,config = <&out_lo>; + }; + default_cfg2 { + ste,pins = "GPIO209_AG15"; /* FBCLK */ + ste,config = <&in_nopull>; + }; + default_cfg3 { + ste,pins = + "GPIO210_AJ15", /* CMD */ + "GPIO211_AG14", /* DAT0 */ + "GPIO212_AF13", /* DAT1 */ + "GPIO213_AG13", /* DAT2 */ + "GPIO214_AH15"; /* DAT3 */ + ste,config = <&in_pu>; + }; + }; + + sdi1_sleep_mode: sdi1_sleep { + sleep_cfg1 { + ste,pins = "GPIO208_AH16"; /* CLK */ + ste,config = <&slpm_out_lo_wkup_pdis>; + }; + sleep_cfg2 { + ste,pins = + "GPIO209_AG15", /* FBCLK */ + "GPIO210_AJ15", /* CMD */ + "GPIO211_AG14", /* DAT0 */ + "GPIO212_AF13", /* DAT1 */ + "GPIO213_AG13", /* DAT2 */ + "GPIO214_AH15"; /* DAT3 */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + sdi2 { + /* This is the eMMC 8 bits wide, usually PoP eMMC */ + sdi2_default_mode: sdi2_default { + default_mux { + ste,function = "mc2"; + ste,pins = "mc2_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO128_A5"; /* CLK */ + ste,config = <&out_lo>; + }; + default_cfg2 { + ste,pins = "GPIO130_C8"; /* FBCLK */ + ste,config = <&in_nopull>; + }; + default_cfg3 { + ste,pins = + "GPIO129_B4", /* CMD */ + "GPIO131_A12", /* DAT0 */ + "GPIO132_C10", /* DAT1 */ + "GPIO133_B10", /* DAT2 */ + "GPIO134_B9", /* DAT3 */ + "GPIO135_A9", /* DAT4 */ + "GPIO136_C7", /* DAT5 */ + "GPIO137_A7", /* DAT6 */ + "GPIO138_C5"; /* DAT7 */ + ste,config = <&in_pu>; + }; + }; + + sdi2_sleep_mode: sdi2_sleep { + sleep_cfg1 { + ste,pins = "GPIO128_A5"; /* CLK */ + ste,config = <&out_lo_wkup_pdis>; + }; + sleep_cfg2 { + ste,pins = + "GPIO130_C8", /* FBCLK */ + "GPIO129_B4"; /* CMD */ + ste,config = <&in_wkup_pdis_en>; + }; + sleep_cfg3 { + ste,pins = + "GPIO131_A12", /* DAT0 */ + "GPIO132_C10", /* DAT1 */ + "GPIO133_B10", /* DAT2 */ + "GPIO134_B9", /* DAT3 */ + "GPIO135_A9", /* DAT4 */ + "GPIO136_C7", /* DAT5 */ + "GPIO137_A7", /* DAT6 */ + "GPIO138_C5"; /* DAT7 */ + ste,config = <&in_wkup_pdis>; + }; + }; + }; + + sdi4 { + /* This is the eMMC 8 bits wide, usually PCB-mounted eMMC */ + sdi4_default_mode: sdi4_default { + default_mux { + ste,function = "mc4"; + ste,pins = "mc4_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO203_AE23"; /* CLK */ + ste,config = <&out_lo>; + }; + default_cfg2 { + ste,pins = "GPIO202_AF25"; /* FBCLK */ + ste,config = <&in_nopull>; + }; + default_cfg3 { + ste,pins = + "GPIO201_AF24", /* CMD */ + "GPIO200_AH26", /* DAT0 */ + "GPIO199_AH23", /* DAT1 */ + "GPIO198_AG25", /* DAT2 */ + "GPIO197_AH24", /* DAT3 */ + "GPIO207_AJ23", /* DAT4 */ + "GPIO206_AG24", /* DAT5 */ + "GPIO205_AG23", /* DAT6 */ + "GPIO204_AF23"; /* DAT7 */ + ste,config = <&in_pu>; + }; + }; + + sdi4_sleep_mode: sdi4_sleep { + sleep_cfg1 { + ste,pins = "GPIO203_AE23"; /* CLK */ + ste,config = <&out_lo_wkup_pdis>; + }; + sleep_cfg2 { + ste,pins = + "GPIO202_AF25", /* FBCLK */ + "GPIO201_AF24", /* CMD */ + "GPIO200_AH26", /* DAT0 */ + "GPIO199_AH23", /* DAT1 */ + "GPIO198_AG25", /* DAT2 */ + "GPIO197_AH24", /* DAT3 */ + "GPIO207_AJ23", /* DAT4 */ + "GPIO206_AG24", /* DAT5 */ + "GPIO205_AG23", /* DAT6 */ + "GPIO204_AF23"; /* DAT7 */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + /* + * Multi-rate serial ports (MSPs) - MSP3 output is internal and + * cannot be muxed onto any pins. + */ + msp0 { + msp0_default_mode: msp0_default { + default_msp0_mux { + ste,function = "msp0"; + ste,pins = "msp0txrx_a_1", "msp0tfstck_a_1"; + }; + default_msp0_cfg { + ste,pins = + "GPIO12_AC4", /* TXD */ + "GPIO15_AC3", /* RXD */ + "GPIO13_AF3", /* TFS */ + "GPIO14_AE3"; /* TCK */ + ste,config = <&in_nopull>; + }; + }; + }; + + msp1 { + msp1_default_mode: msp1_default { + default_mux { + ste,function = "msp1"; + ste,pins = "msp1txrx_a_1", "msp1_a_1"; + }; + default_cfg1 { + ste,pins = "GPIO33_AF2"; + ste,config = <&out_lo>; + }; + default_cfg2 { + ste,pins = + "GPIO34_AE1", + "GPIO35_AE2", + "GPIO36_AG2"; + ste,config = <&in_nopull>; + }; + + }; + }; + + msp2 { + msp2_default_mode: msp2_default { + /* MSP2 usually used for HDMI audio */ + default_mux { + ste,function = "msp2"; + ste,pins = "msp2_a_1"; + }; + default_cfg1 { + ste,pins = + "GPIO193_AH27", /* TXD */ + "GPIO194_AF27", /* TCK */ + "GPIO195_AG28"; /* TFS */ + ste,config = <&in_pd>; + }; + default_cfg2 { + ste,pins = "GPIO196_AG26"; /* RXD */ + ste,config = <&out_lo>; + }; + }; + }; + + + musb { + musb_default_mode: musb_default { + default_mux { + ste,function = "usb"; + ste,pins = "usb_a_1"; + }; + default_cfg1 { + ste,pins = + "GPIO256_AF28", /* NXT */ + "GPIO258_AD29", /* XCLK */ + "GPIO259_AC29", /* DIR */ + "GPIO260_AD28", /* DAT7 */ + "GPIO261_AD26", /* DAT6 */ + "GPIO262_AE26", /* DAT5 */ + "GPIO263_AG29", /* DAT4 */ + "GPIO264_AE27", /* DAT3 */ + "GPIO265_AD27", /* DAT2 */ + "GPIO266_AC28", /* DAT1 */ + "GPIO267_AC27"; /* DAT0 */ + ste,config = <&in_nopull>; + }; + default_cfg2 { + ste,pins = "GPIO257_AE29"; /* STP */ + ste,config = <&out_hi>; + }; + }; + + musb_sleep_mode: musb_sleep { + sleep_cfg1 { + ste,pins = + "GPIO256_AF28", /* NXT */ + "GPIO258_AD29", /* XCLK */ + "GPIO259_AC29"; /* DIR */ + ste,config = <&slpm_wkup_pdis_en>; + }; + sleep_cfg2 { + ste,pins = "GPIO257_AE29"; /* STP */ + ste,config = <&slpm_out_hi_wkup_pdis>; + }; + sleep_cfg3 { + ste,pins = + "GPIO260_AD28", /* DAT7 */ + "GPIO261_AD26", /* DAT6 */ + "GPIO262_AE26", /* DAT5 */ + "GPIO263_AG29", /* DAT4 */ + "GPIO264_AE27", /* DAT3 */ + "GPIO265_AD27", /* DAT2 */ + "GPIO266_AC28", /* DAT1 */ + "GPIO267_AC27"; /* DAT0 */ + ste,config = <&slpm_in_wkup_pdis_en>; + }; + }; + }; + + mcde { + lcd_default_mode: lcd_default { + default_mux { + /* Mux in VSI0 and all the data lines */ + ste,function = "lcd"; + ste,pins = + "lcdvsi0_a_1", /* VSI0 for LCD */ + "lcd_d0_d7_a_1", /* Data lines */ + "lcd_d8_d11_a_1", /* TV-out */ + "lcdaclk_b_1", /* Clock line for TV-out */ + "lcdvsi1_a_1"; /* VSI1 for HDMI */ + }; + default_cfg1 { + ste,pins = + "GPIO68_E1", /* VSI0 */ + "GPIO69_E2"; /* VSI1 */ + ste,config = <&in_pu>; + }; + }; + lcd_sleep_mode: lcd_sleep { + sleep_cfg1 { + ste,pins = "GPIO69_E2"; /* VSI1 */ + ste,config = <&slpm_in_wkup_pdis>; + }; + }; + }; + + ske { + /* SKE keys on position 2 in an 8x8 matrix */ + ske_kpa2_default_mode: ske_kpa2_default { + default_mux { + ste,function = "kp"; + ste,pins = "kp_a_2"; + }; + default_cfg1 { + ste,pins = + "GPIO153_B17", /* I7 */ + "GPIO154_C16", /* I6 */ + "GPIO155_C19", /* I5 */ + "GPIO156_C17", /* I4 */ + "GPIO161_D21", /* I3 */ + "GPIO162_D20", /* I2 */ + "GPIO163_C20", /* I1 */ + "GPIO164_B21"; /* I0 */ + ste,config = <&in_pd>; + }; + default_cfg2 { + ste,pins = + "GPIO157_A18", /* O7 */ + "GPIO158_C18", /* O6 */ + "GPIO159_B19", /* O5 */ + "GPIO160_B20", /* O4 */ + "GPIO165_C21", /* O3 */ + "GPIO166_A22", /* O2 */ + "GPIO167_B24", /* O1 */ + "GPIO168_C22"; /* O0 */ + ste,config = <&out_lo>; + }; + }; + ske_kpa2_sleep_mode: ske_kpa2_sleep { + sleep_cfg1 { + ste,pins = + "GPIO153_B17", /* I7 */ + "GPIO154_C16", /* I6 */ + "GPIO155_C19", /* I5 */ + "GPIO156_C17", /* I4 */ + "GPIO161_D21", /* I3 */ + "GPIO162_D20", /* I2 */ + "GPIO163_C20", /* I1 */ + "GPIO164_B21"; /* I0 */ + ste,config = <&slpm_in_pu_wkup_pdis_en>; + }; + sleep_cfg2 { + ste,pins = + "GPIO157_A18", /* O7 */ + "GPIO158_C18", /* O6 */ + "GPIO159_B19", /* O5 */ + "GPIO160_B20", /* O4 */ + "GPIO165_C21", /* O3 */ + "GPIO166_A22", /* O2 */ + "GPIO167_B24", /* O1 */ + "GPIO168_C22"; /* O0 */ + ste,config = <&slpm_out_lo_pdis>; + }; + }; + /* + * SKE keys on position 1 and "other C1" combi giving + * six rows of six keys. + */ + ske_kpaoc1_default_mode: ske_kpaoc1_default { + default_mux { + ste,function = "kp"; + ste,pins = "kp_a_1", "kp_oc1_1"; + }; + default_cfg1 { + ste,pins = + "GPIO91_B6", /* KP_O0 */ + "GPIO90_A3", /* KP_O1 */ + "GPIO87_B3", /* KP_O2 */ + "GPIO86_C6", /* KP_O3 */ + "GPIO96_D8", /* KP_O6 */ + "GPIO94_D7"; /* KP_O7 */ + ste,config = <&out_lo>; + }; + default_cfg2 { + ste,pins = + "GPIO93_B7", /* KP_I0 */ + "GPIO92_D6", /* KP_I1 */ + "GPIO89_E6", /* KP_I2 */ + "GPIO88_C4", /* KP_I3 */ + "GPIO97_D9", /* KP_I6 */ + "GPIO95_E8"; /* KP_I7 */ + ste,config = <&in_pu>; + }; + }; + }; + + wlan { + wlan_default_mode: wlan_default { + /* + * Activate this mode with the WLAN chip. + * These are plain GPIO pins used by WLAN + */ + default_cfg1 { + ste,pins = + "GPIO226_AF8", /* WLAN_PMU_EN */ + "GPIO85_D5"; /* WLAN_ENA */ + ste,config = <&gpio_out_lo>; + }; + default_cfg2 { + ste,pins = "GPIO4_AH6"; /* WLAN_IRQ on UART1 */ + ste,config = <&gpio_in_pu>; + }; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/ste-href-stuib.dtsi b/arch/arm/boot/dts/ste-href-stuib.dtsi index 76704ec0ffcc..1c3574435ea8 100644 --- a/arch/arm/boot/dts/ste-href-stuib.dtsi +++ b/arch/arm/boot/dts/ste-href-stuib.dtsi @@ -12,6 +12,28 @@ #include / { + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + vdd-supply = <&ab8500_ldo_aux1_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&prox_stuib_mode>, <&hall_stuib_mode>; + + button@139 { + /* Proximity sensor */ + gpios = <&gpio6 25 0x4>; + linux,code = <11>; /* SW_FRONT_PROXIMITY */ + label = "SFH7741 Proximity Sensor"; + }; + button@145 { + /* Hall sensor */ + gpios = <&gpio4 17 0x4>; + linux,code = <0>; /* SW_LID */ + label = "HED54XXU11 Hall Effect Sensor"; + }; + }; + soc { i2c@80004000 { stmpe1601: stmpe1601@40 { @@ -74,5 +96,24 @@ rohm,flip-y; }; }; + + pinctrl { + prox { + prox_stuib_mode: prox_stuib { + stuib_cfg { + ste,pins = "GPIO217_AH12"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + hall { + hall_stuib_mode: stuib_tvk { + stuib_cfg { + ste,pins = "GPIO145_C13"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + }; }; }; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi index 76d3ef13175f..c40565320978 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi @@ -14,27 +14,105 @@ #include / { + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + vdd-supply = <&ab8500_ldo_aux1_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&prox_tvk_mode>, <&hall_tvk_mode>; + + button@139 { + /* Proximity sensor */ + gpios = <&gpio6 25 0x4>; + linux,code = <11>; /* SW_FRONT_PROXIMITY */ + label = "SFH7741 Proximity Sensor"; + }; + button@145 { + /* Hall sensor */ + gpios = <&gpio4 17 0x4>; + linux,code = <0>; /* SW_LID */ + label = "HED54XXU11 Hall Effect Sensor"; + }; + }; + soc { - /* Add Synaptics touch screen, TC35892 keypad etc here */ + /* Add Synaptics touch screen, TC35893 keypad etc here */ i2c@80004000 { - tc3589x@44 { - compatible = "tc3589x"; + tc35893@44 { + compatible = "toshiba,tc35893"; reg = <0x44>; interrupt-parent = <&gpio6>; interrupts = <26 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&tc35893_tvk_mode>; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <1>; tc3589x_gpio { - compatible = "tc3589x-gpio"; - interrupts = <0 IRQ_TYPE_EDGE_RISING>; + compatible = "toshiba,tc3589x-gpio"; + interrupts = <0>; interrupt-controller; #interrupt-cells = <2>; gpio-controller; #gpio-cells = <2>; }; + tc3589x_keypad { + compatible = "toshiba,tc3589x-keypad"; + interrupts = <6>; + debounce-delay-ms = <4>; + keypad,num-columns = <8>; + keypad,num-rows = <8>; + linux,no-autorepeat; + linux,wakeup; + linux,keymap = <0x0301006b + 0x04010066 + 0x06040072 + 0x040200d7 + 0x0303006a + 0x0205000e + 0x0607008b + 0x0500001c + 0x0403000b + 0x03040034 + 0x05020067 + 0x0305006c + 0x040500e7 + 0x0005009e + 0x06020073 + 0x01030039 + 0x07060069 + 0x050500d9>; + }; + }; + }; + pinctrl { + /* Pull up this GPIO pin */ + tc35893 { + tc35893_tvk_mode: tc35893_tvk { + tvk_cfg { + ste,pins = "GPIO218_AH11"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + prox { + prox_tvk_mode: prox_tvk { + tvk_cfg { + ste,pins = "GPIO217_AH12"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + hall { + hall_tvk_mode: hall_tvk { + tvk_cfg { + ste,pins = "GPIO145_C13"; + ste,config = <&gpio_in_pu>; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index aa3f02060fdd..0c1e8d871ed1 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi @@ -11,37 +11,57 @@ #include #include "ste-dbx5x0.dtsi" +#include "ste-href-family-pinctrl.dtsi" / { memory { reg = <0x00000000 0x20000000>; }; - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - - button@1 { - linux,code = <11>; - label = "SFH7741 Proximity Sensor"; - }; - }; - soc { + usb_per5@a03e0000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&musb_default_mode>; + pinctrl-1 = <&musb_sleep_mode>; + }; + uart@80120000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&uart0_default_mode>; + pinctrl-1 = <&uart0_sleep_mode>; status = "okay"; }; uart@80121000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&uart1_default_mode>; + pinctrl-1 = <&uart1_sleep_mode>; status = "okay"; }; uart@80007000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&uart2_default_mode>; + pinctrl-1 = <&uart2_sleep_mode>; status = "okay"; }; + i2c@80004000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c0_default_mode>; + pinctrl-1 = <&i2c0_sleep_mode>; + }; + + i2c@80122000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c1_default_mode>; + pinctrl-1 = <&i2c1_sleep_mode>; + }; + i2c@80128000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c2_default_mode>; + pinctrl-1 = <&i2c2_sleep_mode>; lp5521@33 { compatible = "national,lp5521"; reg = <0x33>; @@ -85,6 +105,12 @@ }; }; + i2c@80110000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c3_default_mode>; + pinctrl-1 = <&i2c3_sleep_mode>; + }; + // External Micro SD slot sdi0_per1@80126000 { arm,primecell-periphid = <0x10480180>; @@ -94,8 +120,9 @@ mmc-cap-mmc-highspeed; vmmc-supply = <&ab8500_ldo_aux3_reg>; vqmmc-supply = <&vmmci>; - - cd-gpios = <&tc3589x_gpio 3 0x4>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi0_default_mode>; + pinctrl-1 = <&sdi0_sleep_mode>; status = "okay"; }; @@ -105,6 +132,9 @@ arm,primecell-periphid = <0x10480180>; max-frequency = <100000000>; bus-width = <4>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi1_default_mode>; + pinctrl-1 = <&sdi1_sleep_mode>; status = "okay"; }; @@ -115,6 +145,9 @@ max-frequency = <100000000>; bus-width = <8>; mmc-cap-mmc-highspeed; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi2_default_mode>; + pinctrl-1 = <&sdi2_sleep_mode>; status = "okay"; }; @@ -126,6 +159,9 @@ bus-width = <8>; mmc-cap-mmc-highspeed; vmmc-supply = <&ab8500_ldo_aux2_reg>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi4_default_mode>; + pinctrl-1 = <&sdi4_sleep_mode>; status = "okay"; }; @@ -137,7 +173,21 @@ stericsson,audio-codec = <&codec>; }; + msp0: msp@80123000 { + pinctrl-names = "default"; + pinctrl-0 = <&msp0_default_mode>; + status = "okay"; + }; + msp1: msp@80124000 { + pinctrl-names = "default"; + pinctrl-0 = <&msp1_default_mode>; + status = "okay"; + }; + + msp2: msp@80117000 { + pinctrl-names = "default"; + pinctrl-0 = <&msp2_default_mode>; status = "okay"; }; @@ -198,5 +248,11 @@ }; }; }; + + mcde@a0350000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&lcd_default_mode>; + pinctrl-1 = <&lcd_sleep_mode>; + }; }; }; diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi index b2cd7bc2752f..40f0ecdf9303 100644 --- a/arch/arm/boot/dts/ste-hrefprev60.dtsi +++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi @@ -28,18 +28,20 @@ reg = <0x33>; }; - tc3589x@42 { - compatible = "tc3589x"; + tc35892@42 { + compatible = "toshiba,tc35892"; reg = <0x42>; interrupt-parent = <&gpio6>; interrupts = <25 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&tc35892_hrefprev60_mode>; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <1>; tc3589x_gpio: tc3589x_gpio { compatible = "tc3589x-gpio"; - interrupts = <0 IRQ_TYPE_EDGE_RISING>; + interrupts = <0>; interrupt-controller; #interrupt-cells = <2>; @@ -49,11 +51,77 @@ }; }; + ssp@80002000 { + /* + * On the first generation boards, this SSP/SPI port was connected + * to the AB8500. + */ + pinctrl-names = "default"; + pinctrl-0 = <&ssp0_hrefprev60_mode>; + }; + + // External Micro SD slot + sdi0_per1@80126000 { + cd-gpios = <&tc3589x_gpio 3 0x4>; + }; + vmmci: regulator-gpio { gpios = <&tc3589x_gpio 18 0x4>; enable-gpio = <&tc3589x_gpio 17 0x4>; + }; - status = "okay"; + pinctrl { + /* Set this up using hogs */ + pinctrl-names = "default"; + pinctrl-0 = <&ipgpio_hrefprev60_mode>; + + ssp0 { + ssp0_hrefprev60_mode: ssp0_hrefprev60_default { + hrefprev60_mux { + ste,function = "ssp0"; + ste,pins = "ssp0_a_1"; + }; + hrefprev60_cfg1 { + ste,pins = "GPIO145_C13"; /* RXD */ + ste,config = <&in_pd>; + }; + + }; + }; + sdi0 { + /* This additional pin needed on early MOP500 and HREFs previous to v60 */ + sdi0_default_mode: sdi0_default { + hrefprev60_mux { + ste,function = "mc0"; + ste,pins = "mc0dat31dir_a_1"; + }; + hrefprev60_cfg1 { + ste,pins = "GPIO21_AB3"; /* DAT31DIR */ + ste,config = <&out_hi>; + }; + + }; + }; + tc35892 { + tc35892_hrefprev60_mode: tc35892_hrefprev60 { + hrefprev60_cfg { + ste,pins = "GPIO217_AH12"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + ipgpio { + ipgpio_hrefprev60_mode: ipgpio_hrefprev60 { + hrefprev60_mux { + ste,function = "ipgpio"; + ste,pins = "ipgpio0_c_1", "ipgpio1_c_1"; + }; + hrefprev60_cfg1 { + ste,pins = "GPIO6_AF6", "GPIO7_AG5"; + ste,config = <&in_pu>; + }; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/ste-hrefv60plus.dtsi b/arch/arm/boot/dts/ste-hrefv60plus.dtsi index aed511b47a9e..3b6d1181939b 100644 --- a/arch/arm/boot/dts/ste-hrefv60plus.dtsi +++ b/arch/arm/boot/dts/ste-hrefv60plus.dtsi @@ -16,55 +16,226 @@ model = "ST-Ericsson HREF (v60+) platform with Device Tree"; compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500"; - gpio_keys { - button@1 { - gpios = <&gpio5 25 0x4>; - }; - }; - soc { // External Micro SD slot sdi0_per1@80126000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <4>; - mmc-cap-sd-highspeed; - mmc-cap-mmc-highspeed; - vmmc-supply = <&ab8500_ldo_aux3_reg>; - cd-gpios = <&gpio2 31 0x4>; // 95 - - status = "okay"; }; - // WLAN SDIO channel - sdi1_per2@80118000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <4>; - - status = "okay"; + vmmci: regulator-gpio { + gpios = <&gpio0 5 0x4>; + enable-gpio = <&gpio5 9 0x4>; }; - // PoP:ed eMMC - sdi2_per3@80005000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <8>; - mmc-cap-mmc-highspeed; + pinctrl { + /* + * Set this up using hogs, as time goes by and as seems fit, these + * can be moved over to being controlled by respective device. + */ + pinctrl-names = "default"; + pinctrl-0 = <&ipgpio_hrefv60_mode>, + <&accel_hrefv60_mode>, + <&magneto_hrefv60_mode>, + <&etm_hrefv60_mode>, + <&nahj_hrefv60_mode>, + <&nfc_hrefv60_mode>, + <&force_hrefv60_mode>, + <&dipro_hrefv60_mode>, + <&vaudio_hf_hrefv60_mode>, + <&gbf_hrefv60_mode>, + <&hdtv_hrefv60_mode>, + <&touch_hrefv60_mode>; - status = "okay"; - }; - - // On-board eMMC - sdi4_per2@80114000 { - arm,primecell-periphid = <0x10480180>; - max-frequency = <100000000>; - bus-width = <8>; - mmc-cap-mmc-highspeed; - vmmc-supply = <&ab8500_ldo_aux2_reg>; - - status = "okay"; + sdi0 { + /* SD card detect GPIO pin, extend default state */ + sdi0_default_mode: sdi0_default { + default_hrefv60_cfg1 { + ste,pins = "GPIO95_E8"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + ipgpio { + /* + * XENON Flashgun on image processor GPIO (controlled from image + * processor firmware), mux in these image processor GPIO lines 0 + * (XENON_FLASH_ID), 1 (XENON_READY) and there is an assistant + * LED on IP GPIO 4 (XENON_EN2) on altfunction C, that need bias + * from GPIO21 so pull up 0, 1 and drive 4 and GPIO21 low as output. + */ + ipgpio_hrefv60_mode: ipgpio_hrefv60 { + hrefv60_mux { + ste,function = "ipgpio"; + ste,pins = "ipgpio0_c_1", "ipgpio1_c_1", "ipgpio4_c_1"; + }; + hrefv60_cfg1 { + ste,pins = "GPIO6_AF6", "GPIO7_AG5"; + ste,config = <&in_pu>; + }; + hrefv60_cfg2 { + ste,pins = "GPIO21_AB3"; + ste,config = <&gpio_out_lo>; + }; + hrefv60_cfg3 { + ste,pins = "GPIO64_F3"; + ste,config = <&out_lo>; + }; + }; + }; + accelerometer { + accel_hrefv60_mode: accel_hrefv60 { + /* Accelerometer interrupt lines 1 & 2 */ + hrefv60_cfg1 { + ste,pins = "GPIO82_C1", "GPIO83_D3"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + magnetometer { + magneto_hrefv60_mode: magneto_hrefv60 { + /* Magnetometer uses GPIO 31 and 32, pull these up/down respectively */ + hrefv60_cfg1 { + ste,pins = "GPIO31_V3"; + ste,config = <&gpio_in_pu>; + }; + hrefv60_cfg2 { + ste,pins = "GPIO32_V2"; + ste,config = <&gpio_in_pd>; + }; + }; + }; + etm { + /* + * Drive D19-D23 for the ETM PTM trace interface low, + * (presumably pins are unconnected therefore grounded here, + * the "other alt C1" setting enables these pins) + */ + etm_hrefv60_mode: etm_hrefv60 { + hrefv60_cfg1 { + ste,pins = + "GPIO70_G5", + "GPIO71_G4", + "GPIO72_H4", + "GPIO73_H3", + "GPIO74_J3"; + ste,config = <&gpio_out_lo>; + }; + }; + }; + nahj { + nahj_hrefv60_mode: nahj_hrefv60 { + /* NAHJ CTRL on GPIO76 to low, CTRL_INV on GPIO216 to high */ + hrefv60_cfg1 { + ste,pins = "GPIO76_J2"; + ste,config = <&gpio_out_lo>; + }; + hrefv60_cfg2 { + ste,pins = "GPIO216_AG12"; + ste,config = <&gpio_out_hi>; + }; + }; + }; + nfc { + nfc_hrefv60_mode: nfc_hrefv60 { + /* NFC ENA and RESET to low, pulldown IRQ line */ + hrefv60_cfg1 { + ste,pins = + "GPIO77_H1", /* NFC_ENA */ + "GPIO142_C11"; /* NFC_RESET */ + ste,config = <&gpio_out_lo>; + }; + hrefv60_cfg2 { + ste,pins = "GPIO144_B13"; /* NFC_IRQ */ + ste,config = <&gpio_in_pd>; + }; + }; + }; + force { + force_hrefv60_mode: force_hrefv60 { + hrefv60_cfg1 { + ste,pins = "GPIO91_B6"; /* FORCE_SENSING_INT */ + ste,config = <&gpio_in_pu>; + }; + hrefv60_cfg2 { + ste,pins = + "GPIO92_D6", /* FORCE_SENSING_RST */ + "GPIO97_D9"; /* FORCE_SENSING_WU */ + ste,config = <&gpio_out_lo>; + }; + }; + }; + dipro { + dipro_hrefv60_mode: dipro_hrefv60 { + hrefv60_cfg1 { + ste,pins = "GPIO139_C9"; /* DIPRO_INT */ + ste,config = <&gpio_in_pu>; + }; + }; + }; + vaudio_hf { + vaudio_hf_hrefv60_mode: vaudio_hf_hrefv60 { + /* Audio Amplifier HF enable GPIO */ + hrefv60_cfg1 { + ste,pins = "GPIO149_B14"; /* VAUDIO_HF_EN, enable MAX8968 */ + ste,config = <&gpio_out_hi>; + }; + }; + }; + gbf { + gbf_hrefv60_mode: gbf_hrefv60 { + /* + * GBF (GPS, Bluetooth, FM-radio) interface, + * pull low to reset state + */ + hrefv60_cfg1 { + ste,pins = "GPIO171_D23"; /* GBF_ENA_RESET */ + ste,config = <&gpio_out_lo>; + }; + }; + }; + hdtv { + hdtv_hrefv60_mode: hdtv_hrefv60 { + /* MSP : HDTV INTERFACE GPIO line */ + hrefv60_cfg1 { + ste,pins = "GPIO192_AJ27"; + ste,config = <&gpio_in_pd>; + }; + }; + }; + touch { + touch_hrefv60_mode: touch_hrefv60 { + /* + * Touch screen uses GPIO 143 for RST1, GPIO 146 for RST2 and + * GPIO 67 for interrupts. Pull-up the IRQ line and drive both + * reset signals low. + */ + hrefv60_cfg1 { + ste,pins = "GPIO143_D12", "GPIO146_D13"; + ste,config = <&gpio_out_lo>; + }; + hrefv60_cfg2 { + ste,pins = "GPIO67_G2"; + ste,config = <&gpio_in_pu>; + }; + }; + }; + mcde { + lcd_hrefv60_mode: lcd_hrefv60 { + /* + * Display Interface 1 uses GPIO 65 for RST (reset). + * Display Interface 2 uses GPIO 66 for RST (reset). + * Drive DISP1 reset high (not reset), driver DISP2 reset low (reset) + */ + hrefv60_cfg1 { + ste,pins ="GPIO65_F1"; + ste,config = <&gpio_out_hi>; + }; + hrefv60_cfg2 { + ste,pins ="GPIO66_G3"; + ste,config = <&gpio_out_lo>; + }; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi b/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi index efddee9403c4..e6f22b266420 100644 --- a/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi @@ -31,17 +31,57 @@ ste,output = ; }; + gpio_in_pu: gpio_input_pull_up { + ste,gpio = ; + ste,input = ; + }; + + gpio_in_pd: gpio_input_pull_down { + ste,gpio = ; + ste,input = ; + }; + gpio_out_lo: gpio_output_low { ste,gpio = ; ste,output = ; }; + gpio_out_hi: gpio_output_high { + ste,gpio = ; + ste,output = ; + }; + + slpm_pdis: slpm_pdis { + ste,sleep = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + + slpm_wkup_pdis: slpm_wkup_pdis { + ste,sleep = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + + slpm_wkup_pdis_en: slpm_wkup_pdis_en { + ste,sleep = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + slpm_in_pu: slpm_in_pu { ste,sleep = ; ste,sleep-input = ; ste,sleep-wakeup = ; }; + slpm_in_pdis: slpm_in_pdis { + ste,sleep = ; + ste,sleep-input = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + slpm_in_wkup_pdis: slpm_in_wkup_pdis { ste,sleep = ; ste,sleep-input = ; @@ -49,6 +89,20 @@ ste,sleep-pull-disable = ; }; + slpm_in_wkup_pdis_en: slpm_in_wkup_pdis_en { + ste,sleep = ; + ste,sleep-input = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + + slpm_in_pu_wkup_pdis_en: slpm_in_wkup_pdis_en { + ste,sleep = ; + ste,sleep-input = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + slpm_out_lo: slpm_out_lo { ste,sleep = ; ste,sleep-output = ; @@ -68,6 +122,20 @@ ste,sleep-pull-disable = ; }; + slpm_out_lo_pdis: slpm_out_lo_pdis { + ste,sleep = ; + ste,sleep-output = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + + slpm_out_lo_wkup_pdis: slpm_out_lo_wkup_pdis { + ste,sleep = ; + ste,sleep-output = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + slpm_out_wkup_pdis: slpm_out_wkup_pdis { ste,sleep = ; ste,sleep-output = ; @@ -81,6 +149,18 @@ ste,sleep-pull-disable = ; }; + in_wkup_pdis_en: in_wkup_pdis_en { + ste,sleep-input = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + + out_lo_wkup_pdis: out_lo_wkup_pdis { + ste,sleep-output = ; + ste,sleep-wakeup = ; + ste,sleep-pull-disable = ; + }; + out_hi_wkup_pdis: out_hi_wkup_pdis { ste,sleep-output = ; ste,sleep-wakeup = ; diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts index 16c3888b7b15..f557feb997f4 100644 --- a/arch/arm/boot/dts/ste-nomadik-s8815.dts +++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts @@ -67,10 +67,6 @@ /* Custom board node with GPIO pins to active etc */ usb-s8815 { - /* The S8815 is using this very GPIO pin for the SMSC91x IRQs */ - ethernet-gpio { - gpios = <&gpio3 8 0x1>; - }; /* This will bias the MMC/SD card detect line */ mmcsd-gpio { gpios = <&gpio3 16 0x1>; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index 79425e3836ce..5acc0449676a 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -769,14 +769,14 @@ #size-cells = <1>; ranges; - vica: intc@0x10140000 { + vica: intc@10140000 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; reg = <0x10140000 0x20>; }; - vicb: intc@0x10140020 { + vicb: intc@10140020 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index f0b39f835914..97d5d21b7db7 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "ste-dbx5x0.dtsi" +#include "ste-href-family-pinctrl.dtsi" / { model = "Calao Systems Snowball platform with device tree"; @@ -75,6 +76,8 @@ leds { compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&gpioled_snowball_mode>; used-led { label = "user_led"; gpios = <&gpio4 14 0x4>; @@ -84,6 +87,11 @@ }; soc { + usb_per5@a03e0000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&musb_default_mode>; + pinctrl-1 = <&musb_sleep_mode>; + }; sound { compatible = "stericsson,snd-soc-mop500"; @@ -92,7 +100,21 @@ stericsson,audio-codec = <&codec>; }; + msp0: msp@80123000 { + pinctrl-names = "default"; + pinctrl-0 = <&msp0_default_mode>; + status = "okay"; + }; + msp1: msp@80124000 { + pinctrl-names = "default"; + pinctrl-0 = <&msp1_default_mode>; + status = "okay"; + }; + + msp2: msp@80117000 { + pinctrl-names = "default"; + pinctrl-0 = <&msp2_default_mode>; status = "okay"; }; @@ -110,6 +132,8 @@ interrupt-parent = <&gpio4>; vdd33a-supply = <&en_3v3_reg>; vddvario-supply = <&db8500_vape_reg>; + pinctrl-names = "default"; + pinctrl-0 = <ð_snowball_mode>; reg-shift = <1>; reg-io-width = <2>; @@ -122,10 +146,8 @@ }; vmmci: regulator-gpio { - gpios = <&gpio6 25 0x4>; - enable-gpio = <&gpio7 4 0x4>; - - status = "okay"; + gpios = <&gpio7 4 0x4>; + enable-gpio = <&gpio6 25 0x4>; }; // External Micro SD slot @@ -136,6 +158,9 @@ mmc-cap-mmc-highspeed; vmmc-supply = <&ab8500_ldo_aux3_reg>; vqmmc-supply = <&vmmci>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi0_default_mode>; + pinctrl-1 = <&sdi0_sleep_mode>; cd-gpios = <&gpio6 26 0x4>; // 218 cd-inverted; @@ -143,6 +168,27 @@ status = "okay"; }; + // WLAN SDIO channel + sdi1_per2@80118000 { + arm,primecell-periphid = <0x10480180>; + max-frequency = <100000000>; + bus-width = <4>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi1_default_mode>; + pinctrl-1 = <&sdi1_sleep_mode>; + + status = "okay"; + }; + + // Unused PoP eMMC - register and put it to sleep by default */ + sdi2_per3@80005000 { + arm,primecell-periphid = <0x10480180>; + pinctrl-names = "default"; + pinctrl-0 = <&sdi2_sleep_mode>; + + status = "okay"; + }; + // On-board eMMC sdi4_per2@80114000 { arm,primecell-periphid = <0x10480180>; @@ -150,22 +196,63 @@ bus-width = <8>; mmc-cap-mmc-highspeed; vmmc-supply = <&ab8500_ldo_aux2_reg>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdi4_default_mode>; + pinctrl-1 = <&sdi4_sleep_mode>; status = "okay"; }; uart@80120000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&uart0_default_mode>; + pinctrl-1 = <&uart0_sleep_mode>; status = "okay"; }; uart@80121000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&uart1_default_mode>; + pinctrl-1 = <&uart1_sleep_mode>; status = "okay"; }; uart@80007000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&uart2_default_mode>; + pinctrl-1 = <&uart2_sleep_mode>; status = "okay"; }; + i2c@80004000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c0_default_mode>; + pinctrl-1 = <&i2c0_sleep_mode>; + }; + + i2c@80122000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c1_default_mode>; + pinctrl-1 = <&i2c1_sleep_mode>; + }; + + i2c@80128000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c2_default_mode>; + pinctrl-1 = <&i2c2_sleep_mode>; + }; + + i2c@80110000 { + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c3_default_mode>; + pinctrl-1 = <&i2c3_sleep_mode>; + }; + + ssp@80002000 { + pinctrl-names = "default"; + pinctrl-0 = <&ssp0_snowball_mode>; + }; + cpufreq-cooling { status = "okay"; }; @@ -266,5 +353,141 @@ }; }; }; + + pinctrl { + /* + * Set this up using hogs, as time goes by and as seems fit, these + * can be moved over to being controlled by respective device. + */ + pinctrl-names = "default"; + pinctrl-0 = <&accel_snowball_mode>, + <&magneto_snowball_mode>, + <&gbf_snowball_mode>, + <&wlan_snowball_mode>; + + ethernet { + /* + * Mux in "SM" which is used for the + * SMSC911x Ethernet adapter + */ + eth_snowball_mode: eth_snowball { + snowball_mux { + ste,function = "sm"; + ste,pins = "sm_b_1"; + }; + /* LAN IRQ pin */ + snowball_cfg1 { + ste,pins = "GPIO140_B11"; + ste,config = <&in_nopull>; + }; + /* LAN reset pin */ + snowball_cfg2 { + ste,pins = "GPIO141_C12"; + ste,config = <&gpio_out_hi>; + }; + + }; + }; + sdi0 { + sdi0_default_mode: sdi0_default { + snowball_mux { + ste,function = "mc0"; + ste,pins = "mc0dat31dir_a_1"; + }; + snowball_cfg1 { + ste,pins = "GPIO21_AB3"; /* DAT31DIR */ + ste,config = <&out_hi>; + }; + + }; + }; + ssp0 { + ssp0_snowball_mode: ssp0_snowball_default { + snowball_mux { + ste,function = "ssp0"; + ste,pins = "ssp0_a_1"; + }; + snowball_cfg1 { + ste,pins = "GPIO144_B13"; /* FRM */ + ste,config = <&gpio_out_hi>; + }; + snowball_cfg2 { + ste,pins = "GPIO145_C13"; /* RXD */ + ste,config = <&in_pd>; + }; + snowball_cfg3 { + ste,pins = + "GPIO146_D13", /* TXD */ + "GPIO143_D12"; /* CLK */ + ste,config = <&out_lo>; + }; + + }; + }; + gpio_led { + gpioled_snowball_mode: gpioled_default { + snowball_cfg1 { + ste,pins = "GPIO142_C11"; + ste,config = <&gpio_out_hi>; + }; + + }; + }; + accelerometer { + accel_snowball_mode: accel_snowball { + /* Accelerometer lines */ + snowball_cfg1 { + ste,pins = + "GPIO163_C20", /* ACCEL_IRQ1 */ + "GPIO164_B21"; /* ACCEL_IRQ2 */ + ste,config = <&gpio_in_pu>; + }; + }; + }; + magnetometer { + magneto_snowball_mode: magneto_snowball { + snowball_cfg1 { + ste,pins = "GPIO165_C21"; /* MAG_DRDY */ + ste,config = <&gpio_in_pu>; + }; + }; + }; + gbf { + gbf_snowball_mode: gbf_snowball { + /* + * GBF (GPS, Bluetooth, FM-radio) interface, + * pull low to reset state + */ + snowball_cfg1 { + ste,pins = "GPIO171_D23"; /* GBF_ENA_RESET */ + ste,config = <&gpio_out_lo>; + }; + }; + }; + wlan { + wlan_snowball_mode: wlan_snowball { + /* + * Activate this mode with the WLAN chip. + * These are plain GPIO pins used by WLAN + */ + snowball_cfg1 { + ste,pins = + "GPIO161_D21", /* WLAN_PMU_EN */ + "GPIO215_AH13"; /* WLAN_ENA */ + ste,config = <&gpio_out_lo>; + }; + snowball_cfg2 { + ste,pins = "GPIO216_AG12"; /* WLAN_IRQ */ + ste,config = <&gpio_in_pu>; + }; + }; + }; + }; + + mcde@a0350000 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&lcd_default_mode>; + pinctrl-1 = <&lcd_sleep_mode>; + }; }; }; diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts index 8a1032c1ffc9..a9da4800daf0 100644 --- a/arch/arm/boot/dts/ste-u300.dts +++ b/arch/arm/boot/dts/ste-u300.dts @@ -307,7 +307,7 @@ clocks = <&i2c0_clk>; #address-cells = <1>; #size-cells = <0>; - ab3100: ab3100@0x48 { + ab3100: ab3100@48 { compatible = "stericsson,ab3100"; reg = <0x48>; interrupt-parent = <&vica>; @@ -385,10 +385,10 @@ clocks = <&i2c1_clk>; #address-cells = <1>; #size-cells = <0>; - fwcam0: fwcam@0x10 { + fwcam0: fwcam@10 { reg = <0x10>; }; - fwcam1: fwcam@0x5d { + fwcam1: fwcam@5d { reg = <0x5d>; }; }; diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi index 1d322b24d1e4..e56449d41481 100644 --- a/arch/arm/boot/dts/stih415-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi @@ -86,6 +86,24 @@ }; }; }; + + sbc_i2c0 { + pinctrl_sbc_i2c0_default: sbc_i2c0-default { + st,pins { + sda = <&PIO4 6 ALT1 BIDIR>; + scl = <&PIO4 5 ALT1 BIDIR>; + }; + }; + }; + + sbc_i2c1 { + pinctrl_sbc_i2c1_default: sbc_i2c1-default { + st,pins { + sda = <&PIO3 2 ALT2 BIDIR>; + scl = <&PIO3 1 ALT2 BIDIR>; + }; + }; + }; }; pin-controller-front { @@ -143,6 +161,24 @@ reg = <0x7000 0x100>; st,bank-name = "PIO12"; }; + + i2c0 { + pinctrl_i2c0_default: i2c0-default { + st,pins { + sda = <&PIO9 3 ALT1 BIDIR>; + scl = <&PIO9 2 ALT1 BIDIR>; + }; + }; + }; + + i2c1 { + pinctrl_i2c1_default: i2c1-default { + st,pins { + sda = <&PIO12 1 ALT1 BIDIR>; + scl = <&PIO12 0 ALT1 BIDIR>; + }; + }; + }; }; pin-controller-rear { diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi index 74ab8ded4b49..d9c7dd1d95a4 100644 --- a/arch/arm/boot/dts/stih415.dtsi +++ b/arch/arm/boot/dts/stih415.dtsi @@ -9,6 +9,7 @@ #include "stih41x.dtsi" #include "stih415-clock.dtsi" #include "stih415-pinctrl.dtsi" +#include / { L2: cache-controller { @@ -83,5 +84,57 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sbc_serial1>; }; + + i2c@fed40000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfed40000 0x110>; + interrupts = ; + clocks = <&CLKS_ICN_REG_0>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0_default>; + + status = "disabled"; + }; + + i2c@fed41000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfed41000 0x110>; + interrupts = ; + clocks = <&CLKS_ICN_REG_0>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_default>; + + status = "disabled"; + }; + + i2c@fe540000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfe540000 0x110>; + interrupts = ; + clocks = <&CLK_SYSIN>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sbc_i2c0_default>; + + status = "disabled"; + }; + + i2c@fe541000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfe541000 0x110>; + interrupts = ; + clocks = <&CLK_SYSIN>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sbc_i2c1_default>; + + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi index 0f246c979262..b29ff4ba542c 100644 --- a/arch/arm/boot/dts/stih416-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi @@ -97,6 +97,24 @@ }; }; }; + + sbc_i2c0 { + pinctrl_sbc_i2c0_default: sbc_i2c0-default { + st,pins { + sda = <&PIO4 6 ALT1 BIDIR>; + scl = <&PIO4 5 ALT1 BIDIR>; + }; + }; + }; + + sbc_i2c1 { + pinctrl_sbc_i2c1_default: sbc_i2c1-default { + st,pins { + sda = <&PIO3 2 ALT2 BIDIR>; + scl = <&PIO3 1 ALT2 BIDIR>; + }; + }; + }; }; pin-controller-front { @@ -175,6 +193,23 @@ }; }; + i2c0 { + pinctrl_i2c0_default: i2c0-default { + st,pins { + sda = <&PIO9 3 ALT1 BIDIR>; + scl = <&PIO9 2 ALT1 BIDIR>; + }; + }; + }; + + i2c1 { + pinctrl_i2c1_default: i2c1-default { + st,pins { + sda = <&PIO12 1 ALT1 BIDIR>; + scl = <&PIO12 0 ALT1 BIDIR>; + }; + }; + }; }; pin-controller-rear { diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi index 1a0326ea7d07..b7ab47b95816 100644 --- a/arch/arm/boot/dts/stih416.dtsi +++ b/arch/arm/boot/dts/stih416.dtsi @@ -9,6 +9,7 @@ #include "stih41x.dtsi" #include "stih416-clock.dtsi" #include "stih416-pinctrl.dtsi" +#include / { L2: cache-controller { compatible = "arm,pl310-cache"; @@ -92,5 +93,57 @@ pinctrl-0 = <&pinctrl_sbc_serial1>; clocks = <&CLK_SYSIN>; }; + + i2c@fed40000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfed40000 0x110>; + interrupts = ; + clocks = <&CLK_S_ICN_REG_0>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0_default>; + + status = "disabled"; + }; + + i2c@fed41000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfed41000 0x110>; + interrupts = ; + clocks = <&CLK_S_ICN_REG_0>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_default>; + + status = "disabled"; + }; + + i2c@fe540000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfe540000 0x110>; + interrupts = ; + clocks = <&CLK_SYSIN>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sbc_i2c0_default>; + + status = "disabled"; + }; + + i2c@fe541000 { + compatible = "st,comms-ssc4-i2c"; + reg = <0xfe541000 0x110>; + interrupts = ; + clocks = <&CLK_SYSIN>; + clock-names = "ssc"; + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sbc_i2c1_default>; + + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/stih41x-b2000.dtsi b/arch/arm/boot/dts/stih41x-b2000.dtsi index 8e694d2b8f5b..1e6aa92772f5 100644 --- a/arch/arm/boot/dts/stih41x-b2000.dtsi +++ b/arch/arm/boot/dts/stih41x-b2000.dtsi @@ -37,5 +37,14 @@ }; }; + /* HDMI Tx I2C */ + i2c@fed41000 { + /* HDMI V1.3a supports Standard mode only */ + clock-frequency = <100000>; + i2c-min-scl-pulse-width-us = <0>; + i2c-min-sda-pulse-width-us = <5>; + + status = "okay"; + }; }; }; diff --git a/arch/arm/boot/dts/stih41x-b2020.dtsi b/arch/arm/boot/dts/stih41x-b2020.dtsi index 133e18143b1b..0ef0a69df8ea 100644 --- a/arch/arm/boot/dts/stih41x-b2020.dtsi +++ b/arch/arm/boot/dts/stih41x-b2020.dtsi @@ -38,5 +38,27 @@ default-state = "off"; }; }; + + i2c@fed40000 { + status = "okay"; + }; + + /* HDMI Tx I2C */ + i2c@fed41000 { + /* HDMI V1.3a supports Standard mode only */ + clock-frequency = <100000>; + i2c-min-scl-pulse-width-us = <0>; + i2c-min-sda-pulse-width-us = <5>; + + status = "okay"; + }; + + i2c@fe540000 { + status = "okay"; + }; + + i2c@fe541000 { + status = "okay"; + }; }; }; diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts index eb4d73b6a090..d4b081d6a167 100644 --- a/arch/arm/boot/dts/sun4i-a10-a1000.dts +++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts @@ -18,10 +18,6 @@ model = "Mele A1000"; compatible = "mele,a1000", "allwinner,sun4i-a10"; - aliases { - serial0 = &uart0; - }; - soc@01c00000 { emac: ethernet@01c0b000 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts index 425a7db898c5..b139ee6bcf99 100644 --- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts +++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts @@ -17,15 +17,6 @@ model = "Cubietech Cubieboard"; compatible = "cubietech,a10-cubieboard", "allwinner,sun4i-a10"; - aliases { - serial0 = &uart0; - serial1 = &uart1; - }; - - chosen { - bootargs = "earlyprintk console=ttyS0,115200"; - }; - soc@01c00000 { emac: ethernet@01c0b000 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts index b3ae51fa9372..3a1595f67823 100644 --- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts +++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts @@ -18,10 +18,6 @@ model = "Miniand Hackberry"; compatible = "miniand,hackberry", "allwinner,sun4i-a10"; - chosen { - bootargs = "earlyprintk console=ttyS0,115200"; - }; - soc@01c00000 { emac: ethernet@01c0b000 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts index 0c1447c68059..70b3323caf1a 100644 --- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts +++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts @@ -18,10 +18,6 @@ model = "PineRiver Mini X-Plus"; compatible = "pineriver,mini-xplus", "allwinner,sun4i-a10"; - chosen { - bootargs = "earlyprintk console=ttyS0,115200"; - }; - soc@01c00000 { uart0: serial@01c28000 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 319cc6b509da..040bb0eba152 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -15,6 +15,12 @@ / { interrupt-parent = <&intc>; + aliases { + ethernet0 = &emac; + serial0 = &uart0; + serial1 = &uart1; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -66,6 +72,29 @@ clocks = <&osc24M>; }; + pll4: pll4@01c20018 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-pll1-clk"; + reg = <0x01c20018 0x4>; + clocks = <&osc24M>; + }; + + pll5: pll5@01c20020 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll5-clk"; + reg = <0x01c20020 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll5_ddr", "pll5_other"; + }; + + pll6: pll6@01c20028 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6_sata", "pll6_other", "pll6"; + }; + /* dummy is 200M */ cpu: cpu@01c20054 { #clock-cells = <0>; @@ -131,12 +160,11 @@ "apb0_ir1", "apb0_keypad"; }; - /* dummy is pll62 */ apb1_mux: apb1_mux@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-apb1-mux-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&dummy>, <&osc32k>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; }; apb1: apb1@01c20058 { @@ -158,6 +186,126 @@ "apb1_uart4", "apb1_uart5", "apb1_uart6", "apb1_uart7"; }; + + nand_clk: clk@01c20080 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20080 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "nand"; + }; + + ms_clk: clk@01c20084 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20084 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ms"; + }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc0"; + }; + + mmc1_clk: clk@01c2008c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2008c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc1"; + }; + + mmc2_clk: clk@01c20090 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20090 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc2"; + }; + + mmc3_clk: clk@01c20094 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20094 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc3"; + }; + + ts_clk: clk@01c20098 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20098 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ts"; + }; + + ss_clk: clk@01c2009c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2009c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ss"; + }; + + spi0_clk: clk@01c200a0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi0"; + }; + + spi1_clk: clk@01c200a4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi1"; + }; + + spi2_clk: clk@01c200a8 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a8 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi2"; + }; + + pata_clk: clk@01c200ac { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200ac 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "pata"; + }; + + ir0_clk: clk@01c200b0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200b0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir0"; + }; + + ir1_clk: clk@01c200b4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200b4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir1"; + }; + + spi3_clk: clk@01c200d4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200d4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi3"; + }; }; soc@01c00000 { @@ -266,11 +414,23 @@ reg = <0x01c20c90 0x10>; }; + rtc: rtc@01c20d00 { + compatible = "allwinner,sun4i-rtc"; + reg = <0x01c20d00 0x20>; + interrupts = <24>; + }; + sid: eeprom@01c23800 { compatible = "allwinner,sun4i-sid"; reg = <0x01c23800 0x10>; }; + rtp: rtp@01c25000 { + compatible = "allwinner,sun4i-ts"; + reg = <0x01c25000 0x100>; + interrupts = <29>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 52476742a104..ea16054857a4 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -16,6 +16,10 @@ / { interrupt-parent = <&intc>; + aliases { + ethernet0 = &emac; + }; + cpus { cpu@0 { compatible = "arm,cortex-a8"; @@ -63,6 +67,29 @@ clocks = <&osc24M>; }; + pll4: pll4@01c20018 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-pll1-clk"; + reg = <0x01c20018 0x4>; + clocks = <&osc24M>; + }; + + pll5: pll5@01c20020 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll5-clk"; + reg = <0x01c20020 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll5_ddr", "pll5_other"; + }; + + pll6: pll6@01c20028 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6_sata", "pll6_other", "pll6"; + }; + /* dummy is 200M */ cpu: cpu@01c20054 { #clock-cells = <0>; @@ -123,12 +150,11 @@ "apb0_ir", "apb0_keypad"; }; - /* dummy is pll62 */ apb1_mux: apb1_mux@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-apb1-mux-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&dummy>, <&osc32k>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; }; apb1: apb1@01c20058 { @@ -147,6 +173,102 @@ "apb1_i2c2", "apb1_uart0", "apb1_uart1", "apb1_uart2", "apb1_uart3"; }; + + nand_clk: clk@01c20080 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20080 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "nand"; + }; + + ms_clk: clk@01c20084 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20084 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ms"; + }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc0"; + }; + + mmc1_clk: clk@01c2008c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2008c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc1"; + }; + + mmc2_clk: clk@01c20090 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20090 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc2"; + }; + + ts_clk: clk@01c20098 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20098 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ts"; + }; + + ss_clk: clk@01c2009c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2009c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ss"; + }; + + spi0_clk: clk@01c200a0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi0"; + }; + + spi1_clk: clk@01c200a4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi1"; + }; + + spi2_clk: clk@01c200a8 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a8 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi2"; + }; + + ir0_clk: clk@01c200b0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200b0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir0"; + }; + + mbus_clk: clk@01c2015c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2015c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mbus"; + }; }; soc@01c00000 { @@ -260,6 +382,12 @@ reg = <0x01c23800 0x10>; }; + rtp: rtp@01c25000 { + compatible = "allwinner,sun4i-ts"; + reg = <0x01c25000 0x100>; + interrupts = <29>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; @@ -332,5 +460,12 @@ clock-frequency = <100000>; status = "disabled"; }; + + timer@01c60000 { + compatible = "allwinner,sun5i-a13-hstimer"; + reg = <0x01c60000 0x1000>; + interrupts = <82>, <83>; + clocks = <&ahb_gates 28>; + }; }; }; diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts new file mode 100644 index 000000000000..fe2ce0acdb06 --- /dev/null +++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Maxime Ripard + * Copyright 2013 Hans de Goede + * + * Maxime Ripard + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "sun5i-a13.dtsi" + +/ { + model = "Olimex A13-Olinuxino Micro"; + compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13"; + + soc@01c00000 { + pinctrl@01c20800 { + led_pins_olinuxinom: led_pins@0 { + allwinner,pins = "PG9"; + allwinner,function = "gpio_out"; + allwinner,drive = <1>; + allwinner,pull = <0>; + }; + }; + + uart1: serial@01c28400 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_b>; + status = "okay"; + }; + + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; + + i2c2: i2c@01c2b400 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_olinuxinom>; + + power { + label = "a13-olinuxino-micro:green:power"; + gpios = <&pio 6 9 0>; + default-state = "on"; + }; + }; +}; diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts index 9e508dcc4245..a4ba5ff010cf 100644 --- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts +++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts @@ -18,10 +18,6 @@ model = "Olimex A13-Olinuxino"; compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13"; - chosen { - bootargs = "earlyprintk console=ttyS0,115200"; - }; - soc@01c00000 { pinctrl@01c20800 { led_pins_olinuxino: led_pins@0 { diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index ce8ef2a45be0..320335abfccd 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -67,6 +67,29 @@ clocks = <&osc24M>; }; + pll4: pll4@01c20018 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-pll1-clk"; + reg = <0x01c20018 0x4>; + clocks = <&osc24M>; + }; + + pll5: pll5@01c20020 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll5-clk"; + reg = <0x01c20020 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll5_ddr", "pll5_other"; + }; + + pll6: pll6@01c20028 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6_sata", "pll6_other", "pll6"; + }; + /* dummy is 200M */ cpu: cpu@01c20054 { #clock-cells = <0>; @@ -125,12 +148,11 @@ clock-output-names = "apb0_codec", "apb0_pio", "apb0_ir"; }; - /* dummy is pll6 */ apb1_mux: apb1_mux@01c20058 { #clock-cells = <0>; compatible = "allwinner,sun4i-apb1-mux-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&dummy>, <&osc32k>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; }; apb1: apb1@01c20058 { @@ -148,6 +170,102 @@ clock-output-names = "apb1_i2c0", "apb1_i2c1", "apb1_i2c2", "apb1_uart1", "apb1_uart3"; }; + + nand_clk: clk@01c20080 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20080 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "nand"; + }; + + ms_clk: clk@01c20084 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20084 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ms"; + }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc0"; + }; + + mmc1_clk: clk@01c2008c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2008c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc1"; + }; + + mmc2_clk: clk@01c20090 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20090 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc2"; + }; + + ts_clk: clk@01c20098 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20098 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ts"; + }; + + ss_clk: clk@01c2009c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2009c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ss"; + }; + + spi0_clk: clk@01c200a0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi0"; + }; + + spi1_clk: clk@01c200a4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi1"; + }; + + spi2_clk: clk@01c200a8 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a8 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi2"; + }; + + ir0_clk: clk@01c200b0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200b0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir0"; + }; + + mbus_clk: clk@01c2015c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2015c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mbus"; + }; }; soc@01c00000 { @@ -227,6 +345,12 @@ reg = <0x01c23800 0x10>; }; + rtp: rtp@01c25000 { + compatible = "allwinner,sun4i-ts"; + reg = <0x01c25000 0x100>; + interrupts = <29>; + }; + uart1: serial@01c28400 { compatible = "snps,dw-apb-uart"; reg = <0x01c28400 0x400>; @@ -273,5 +397,12 @@ clock-frequency = <100000>; status = "disabled"; }; + + timer@01c60000 { + compatible = "allwinner,sun5i-a13-hstimer"; + reg = <0x01c60000 0x1000>; + interrupts = <82>, <83>; + clocks = <&ahb_gates 28>; + }; }; }; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 7f5878c2784a..5256ad9be52c 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -212,6 +212,24 @@ }; }; + ahb1_rst: reset@01c202c0 { + #reset-cells = <1>; + compatible = "allwinner,sun6i-a31-ahb1-reset"; + reg = <0x01c202c0 0xc>; + }; + + apb1_rst: reset@01c202d0 { + #reset-cells = <1>; + compatible = "allwinner,sun6i-a31-clock-reset"; + reg = <0x01c202d0 0x4>; + }; + + apb2_rst: reset@01c202d8 { + #reset-cells = <1>; + compatible = "allwinner,sun6i-a31-clock-reset"; + reg = <0x01c202d8 0x4>; + }; + timer@01c20c00 { compatible = "allwinner,sun4i-timer"; reg = <0x01c20c00 0xa0>; @@ -235,6 +253,7 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&apb2_gates 16>; + resets = <&apb2_rst 16>; status = "disabled"; }; @@ -245,6 +264,7 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&apb2_gates 17>; + resets = <&apb2_rst 17>; status = "disabled"; }; @@ -255,6 +275,7 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&apb2_gates 18>; + resets = <&apb2_rst 18>; status = "disabled"; }; @@ -265,6 +286,7 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&apb2_gates 19>; + resets = <&apb2_rst 19>; status = "disabled"; }; @@ -275,6 +297,7 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&apb2_gates 20>; + resets = <&apb2_rst 20>; status = "disabled"; }; @@ -285,6 +308,7 @@ reg-shift = <2>; reg-io-width = <4>; clocks = <&apb2_gates 21>; + resets = <&apb2_rst 21>; status = "disabled"; }; @@ -298,5 +322,15 @@ #interrupt-cells = <3>; interrupts = <1 9 0xf04>; }; + + cpucfg@01f01c00 { + compatible = "allwinner,sun6i-a31-cpuconfig"; + reg = <0x01f01c00 0x300>; + }; + + prcm@01f01c00 { + compatible = "allwinner,sun6i-a31-prcm"; + reg = <0x01f01400 0x200>; + }; }; }; diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts index 8a1009d6c829..f9dcb61a5305 100644 --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts @@ -33,6 +33,24 @@ pinctrl-0 = <&uart0_pins_a>; status = "okay"; }; + + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; + + i2c2: i2c@01c2b400 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; + }; }; leds { diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 367611a0730b..119f066f0d98 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -16,6 +16,10 @@ / { interrupt-parent = <&gic>; + aliases { + ethernet0 = &emac; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -49,10 +53,11 @@ clock-frequency = <24000000>; }; - osc32k: osc32k { + osc32k: clk@0 { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32768>; + clock-output-names = "osc32k"; }; pll1: pll1@01c20000 { @@ -62,23 +67,34 @@ clocks = <&osc24M>; }; - /* - * This is a dummy clock, to be used as placeholder on - * other mux clocks when a specific parent clock is not - * yet implemented. It should be dropped when the driver - * is complete. - */ - pll6: pll6 { + pll4: pll4@01c20018 { #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <0>; + compatible = "allwinner,sun4i-pll1-clk"; + reg = <0x01c20018 0x4>; + clocks = <&osc24M>; + }; + + pll5: pll5@01c20020 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll5-clk"; + reg = <0x01c20020 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll5_ddr", "pll5_other"; + }; + + pll6: pll6@01c20028 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6_sata", "pll6_other", "pll6"; }; cpu: cpu@01c20054 { #clock-cells = <0>; compatible = "allwinner,sun4i-cpu-clk"; reg = <0x01c20054 0x4>; - clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6>; + clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll6 1>; }; axi: axi@01c20054 { @@ -137,7 +153,7 @@ #clock-cells = <0>; compatible = "allwinner,sun4i-apb1-mux-clk"; reg = <0x01c20058 0x4>; - clocks = <&osc24M>, <&pll6>, <&osc32k>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; }; apb1: apb1@01c20058 { @@ -159,6 +175,162 @@ "apb1_uart2", "apb1_uart3", "apb1_uart4", "apb1_uart5", "apb1_uart6", "apb1_uart7"; }; + + nand_clk: clk@01c20080 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20080 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "nand"; + }; + + ms_clk: clk@01c20084 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20084 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ms"; + }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc0"; + }; + + mmc1_clk: clk@01c2008c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2008c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc1"; + }; + + mmc2_clk: clk@01c20090 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20090 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc2"; + }; + + mmc3_clk: clk@01c20094 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20094 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc3"; + }; + + ts_clk: clk@01c20098 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c20098 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ts"; + }; + + ss_clk: clk@01c2009c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2009c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ss"; + }; + + spi0_clk: clk@01c200a0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi0"; + }; + + spi1_clk: clk@01c200a4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi1"; + }; + + spi2_clk: clk@01c200a8 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200a8 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi2"; + }; + + pata_clk: clk@01c200ac { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200ac 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "pata"; + }; + + ir0_clk: clk@01c200b0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200b0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir0"; + }; + + ir1_clk: clk@01c200b4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200b4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir1"; + }; + + spi3_clk: clk@01c200d4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c200d4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi3"; + }; + + mbus_clk: clk@01c2015c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-mod0-clk"; + reg = <0x01c2015c 0x4>; + clocks = <&osc24M>, <&pll6 2>, <&pll5 1>; + clock-output-names = "mbus"; + }; + + /* + * Dummy clock used by output clocks + */ + osc24M_32k: clk@1 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <750>; + clock-mult = <1>; + clocks = <&osc24M>; + clock-output-names = "osc24M_32k"; + }; + + clk_out_a: clk@01c201f0 { + #clock-cells = <0>; + compatible = "allwinner,sun7i-a20-out-clk"; + reg = <0x01c201f0 0x4>; + clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>; + clock-output-names = "clk_out_a"; + }; + + clk_out_b: clk@01c201f4 { + #clock-cells = <0>; + compatible = "allwinner,sun7i-a20-out-clk"; + reg = <0x01c201f4 0x4>; + clocks = <&osc24M_32k>, <&osc32k>, <&osc24M>; + clock-output-names = "clk_out_b"; + }; }; soc@01c00000 { @@ -246,6 +418,20 @@ allwinner,drive = <0>; allwinner,pull = <0>; }; + + clk_out_a_pins_a: clk_out_a@0 { + allwinner,pins = "PI12"; + allwinner,function = "clk_out_a"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + clk_out_b_pins_a: clk_out_b@0 { + allwinner,pins = "PI13"; + allwinner,function = "clk_out_b"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; }; timer@01c20c00 { @@ -265,11 +451,23 @@ reg = <0x01c20c90 0x10>; }; + rtc: rtc@01c20d00 { + compatible = "allwinner,sun7i-a20-rtc"; + reg = <0x01c20d00 0x20>; + interrupts = <0 24 1>; + }; + sid: eeprom@01c23800 { compatible = "allwinner,sun7i-a20-sid"; reg = <0x01c23800 0x200>; }; + rtp: rtp@01c25000 { + compatible = "allwinner,sun4i-ts"; + reg = <0x01c25000 0x100>; + interrupts = <0 29 4>; + }; + uart0: serial@01c28000 { compatible = "snps,dw-apb-uart"; reg = <0x01c28000 0x400>; @@ -395,6 +593,16 @@ status = "disabled"; }; + hstimer@01c60000 { + compatible = "allwinner,sun7i-a20-hstimer"; + reg = <0x01c60000 0x1000>; + interrupts = <0 81 1>, + <0 82 1>, + <0 83 1>, + <0 84 1>; + clocks = <&ahb_gates 28>; + }; + gic: interrupt-controller@01c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index cb5ec23b03a7..73aecfb57ccb 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts @@ -7,11 +7,42 @@ model = "NVIDIA Tegra114 Dalmore evaluation board"; compatible = "nvidia,dalmore", "nvidia,tegra114"; + aliases { + rtc0 = "/i2c@7000d000/tps65913@58"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x80000000 0x40000000>; }; - pinmux { + host1x@50000000 { + hdmi@54280000 { + status = "okay"; + + vdd-supply = <&vdd_hdmi_reg>; + pll-supply = <&palmas_smps3_reg>; + + nvidia,ddc-i2c-bus = <&hdmi_ddc>; + nvidia,hpd-gpio = + <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>; + }; + + dsi@54300000 { + status = "okay"; + + panel@0 { + compatible = "panasonic,vvx10f004b00", + "simple-panel"; + reg = <0>; + + power-supply = <&avdd_lcd_reg>; + backlight = <&backlight>; + }; + }; + }; + + pinmux@70000868 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -19,41 +50,41 @@ clk1_out_pw4 { nvidia,pins = "clk1_out_pw4"; nvidia,function = "extperiph1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap1_din_pn1 { nvidia,pins = "dap1_din_pn1"; nvidia,function = "i2s0"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap1_dout_pn2 { nvidia,pins = "dap1_dout_pn2", "dap1_fs_pn0", "dap1_sclk_pn3"; nvidia,function = "i2s0"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap2_din_pa4 { nvidia,pins = "dap2_din_pa4"; nvidia,function = "i2s1"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap2_dout_pa5 { nvidia,pins = "dap2_dout_pa5", "dap2_fs_pa2", "dap2_sclk_pa3"; nvidia,function = "i2s1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap4_din_pp5 { nvidia,pins = "dap4_din_pp5", @@ -61,17 +92,17 @@ "dap4_fs_pp4", "dap4_sclk_pp7"; nvidia,function = "i2s3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dvfs_pwm_px0 { nvidia,pins = "dvfs_pwm_px0", "dvfs_clk_px2"; nvidia,function = "cldvfs"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; ulpi_clk_py0 { nvidia,pins = "ulpi_clk_py0", @@ -84,128 +115,128 @@ "ulpi_data6_po7", "ulpi_data7_po0"; nvidia,function = "ulpi"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; ulpi_dir_py1 { nvidia,pins = "ulpi_dir_py1", "ulpi_nxt_py2"; nvidia,function = "ulpi"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; ulpi_stp_py3 { nvidia,pins = "ulpi_stp_py3"; nvidia,function = "ulpi"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; cam_i2c_scl_pbb1 { nvidia,pins = "cam_i2c_scl_pbb1", "cam_i2c_sda_pbb2"; nvidia,function = "i2c3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,open-drain = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; }; cam_mclk_pcc0 { nvidia,pins = "cam_mclk_pcc0", "pbb0"; nvidia,function = "vi_alt3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; - nvidia,lock = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; }; gen2_i2c_scl_pt5 { nvidia,pins = "gen2_i2c_scl_pt5", "gen2_i2c_sda_pt6"; nvidia,function = "i2c2"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,open-drain = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; }; gmi_a16_pj7 { nvidia,pins = "gmi_a16_pj7"; nvidia,function = "uartd"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_a17_pb0 { nvidia,pins = "gmi_a17_pb0", "gmi_a18_pb1"; nvidia,function = "uartd"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_a19_pk7 { nvidia,pins = "gmi_a19_pk7"; nvidia,function = "uartd"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad5_pg5 { nvidia,pins = "gmi_ad5_pg5", "gmi_cs6_n_pi3", "gmi_wr_n_pi0"; nvidia,function = "spi4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad6_pg6 { nvidia,pins = "gmi_ad6_pg6", "gmi_ad7_pg7"; nvidia,function = "spi4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad12_ph4 { nvidia,pins = "gmi_ad12_ph4"; nvidia,function = "rsvd4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad9_ph1 { nvidia,pins = "gmi_ad9_ph1"; nvidia,function = "pwm1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_cs1_n_pj2 { nvidia,pins = "gmi_cs1_n_pj2", "gmi_oe_n_pi1"; nvidia,function = "soc"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; clk2_out_pw5 { nvidia,pins = "clk2_out_pw5"; nvidia,function = "extperiph2"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc1_clk_pz0 { nvidia,pins = "sdmmc1_clk_pz0"; nvidia,function = "sdmmc1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc1_cmd_pz1 { nvidia,pins = "sdmmc1_cmd_pz1", @@ -214,23 +245,23 @@ "sdmmc1_dat2_py5", "sdmmc1_dat3_py4"; nvidia,function = "sdmmc1"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc1_wp_n_pv3 { nvidia,pins = "sdmmc1_wp_n_pv3"; nvidia,function = "spi4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc3_clk_pa6 { nvidia,pins = "sdmmc3_clk_pa6"; nvidia,function = "sdmmc3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc3_cmd_pa7 { nvidia,pins = "sdmmc3_cmd_pa7", @@ -242,16 +273,16 @@ "sdmmc3_clk_lb_out_pee4", "sdmmc3_clk_lb_in_pee5"; nvidia,function = "sdmmc3"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc4_clk_pcc4 { nvidia,pins = "sdmmc4_clk_pcc4"; nvidia,function = "sdmmc4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; sdmmc4_cmd_pt7 { nvidia,pins = "sdmmc4_cmd_pt7", @@ -264,16 +295,16 @@ "sdmmc4_dat6_paa6", "sdmmc4_dat7_paa7"; nvidia,function = "sdmmc4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; clk_32k_out_pa0 { nvidia,pins = "clk_32k_out_pa0"; nvidia,function = "blink"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_col0_pq0 { nvidia,pins = "kb_col0_pq0", @@ -283,265 +314,265 @@ "kb_row1_pr1", "kb_row2_pr2"; nvidia,function = "kbc"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap3_din_pp1 { nvidia,pins = "dap3_din_pp1", "dap3_sclk_pp3"; nvidia,function = "displayb"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pv0 { nvidia,pins = "pv0"; nvidia,function = "rsvd4"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_row7_pr7 { nvidia,pins = "kb_row7_pr7"; nvidia,function = "rsvd2"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_row10_ps2 { nvidia,pins = "kb_row10_ps2"; nvidia,function = "uarta"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_row9_ps1 { nvidia,pins = "kb_row9_ps1"; nvidia,function = "uarta"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pwr_i2c_scl_pz6 { nvidia,pins = "pwr_i2c_scl_pz6", "pwr_i2c_sda_pz7"; nvidia,function = "i2cpwr"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,open-drain = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; }; sys_clk_req_pz5 { nvidia,pins = "sys_clk_req_pz5"; nvidia,function = "sysclk"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; core_pwr_req { nvidia,pins = "core_pwr_req"; nvidia,function = "pwron"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; cpu_pwr_req { nvidia,pins = "cpu_pwr_req"; nvidia,function = "cpu"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pwr_int_n { nvidia,pins = "pwr_int_n"; nvidia,function = "pmi"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; reset_out_n { nvidia,pins = "reset_out_n"; nvidia,function = "reset_out_n"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; clk3_out_pee0 { nvidia,pins = "clk3_out_pee0"; nvidia,function = "extperiph3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gen1_i2c_scl_pc4 { nvidia,pins = "gen1_i2c_scl_pc4", "gen1_i2c_sda_pc5"; nvidia,function = "i2c1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,open-drain = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; }; uart2_cts_n_pj5 { nvidia,pins = "uart2_cts_n_pj5"; nvidia,function = "uartb"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; uart2_rts_n_pj6 { nvidia,pins = "uart2_rts_n_pj6"; nvidia,function = "uartb"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; uart2_rxd_pc3 { nvidia,pins = "uart2_rxd_pc3"; nvidia,function = "irda"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; uart2_txd_pc2 { nvidia,pins = "uart2_txd_pc2"; nvidia,function = "irda"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; uart3_cts_n_pa1 { nvidia,pins = "uart3_cts_n_pa1", "uart3_rxd_pw7"; nvidia,function = "uartc"; - nvidia,pull = <0>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; uart3_rts_n_pc0 { nvidia,pins = "uart3_rts_n_pc0", "uart3_txd_pw6"; nvidia,function = "uartc"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; owr { nvidia,pins = "owr"; nvidia,function = "owr"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; hdmi_cec_pee3 { nvidia,pins = "hdmi_cec_pee3"; nvidia,function = "cec"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,open-drain = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; }; ddc_scl_pv4 { nvidia,pins = "ddc_scl_pv4", "ddc_sda_pv5"; nvidia,function = "i2c4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,rcv-sel = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,rcv-sel = ; }; spdif_in_pk6 { nvidia,pins = "spdif_in_pk6"; nvidia,function = "usb"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; }; usb_vbus_en0_pn4 { nvidia,pins = "usb_vbus_en0_pn4"; nvidia,function = "usb"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; - nvidia,lock = <0>; - nvidia,open-drain = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + nvidia,lock = ; + nvidia,open-drain = ; }; gpio_x6_aud_px6 { nvidia,pins = "gpio_x6_aud_px6"; nvidia,function = "spi6"; - nvidia,pull = <2>; - nvidia,tristate = <1>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gpio_x4_aud_px4 { nvidia,pins = "gpio_x4_aud_px4", "gpio_x7_aud_px7"; nvidia,function = "rsvd1"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gpio_x5_aud_px5 { nvidia,pins = "gpio_x5_aud_px5"; nvidia,function = "rsvd1"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gpio_w2_aud_pw2 { nvidia,pins = "gpio_w2_aud_pw2"; nvidia,function = "rsvd2"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gpio_w3_aud_pw3 { nvidia,pins = "gpio_w3_aud_pw3"; nvidia,function = "spi6"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gpio_x1_aud_px1 { nvidia,pins = "gpio_x1_aud_px1"; nvidia,function = "rsvd4"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gpio_x3_aud_px3 { nvidia,pins = "gpio_x3_aud_px3"; nvidia,function = "rsvd4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap3_fs_pp0 { nvidia,pins = "dap3_fs_pp0"; nvidia,function = "i2s2"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; dap3_dout_pp2 { nvidia,pins = "dap3_dout_pp2"; nvidia,function = "i2s2"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pv1 { nvidia,pins = "pv1"; nvidia,function = "rsvd1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pbb3 { nvidia,pins = "pbb3", @@ -549,25 +580,25 @@ "pbb6", "pbb7"; nvidia,function = "rsvd4"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pcc1 { nvidia,pins = "pcc1", "pcc2"; nvidia,function = "rsvd4"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad0_pg0 { nvidia,pins = "gmi_ad0_pg0", "gmi_ad1_pg1"; nvidia,function = "gmi"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad10_ph2 { nvidia,pins = "gmi_ad10_ph2", @@ -576,17 +607,17 @@ "gmi_ad8_ph0", "gmi_clk_pk1"; nvidia,function = "gmi"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_ad2_pg2 { nvidia,pins = "gmi_ad2_pg2", "gmi_ad3_pg3"; nvidia,function = "gmi"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_adv_n_pk0 { nvidia,pins = "gmi_adv_n_pk0", @@ -598,39 +629,39 @@ "gmi_iordy_pi5", "gmi_wp_n_pc7"; nvidia,function = "gmi"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; gmi_cs3_n_pk4 { nvidia,pins = "gmi_cs3_n_pk4"; nvidia,function = "gmi"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; clk2_req_pcc5 { nvidia,pins = "clk2_req_pcc5"; nvidia,function = "rsvd4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_col3_pq3 { nvidia,pins = "kb_col3_pq3", "kb_col6_pq6", "kb_col7_pq7"; nvidia,function = "kbc"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_col5_pq5 { nvidia,pins = "kb_col5_pq5"; nvidia,function = "kbc"; - nvidia,pull = <2>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; kb_row3_pr3 { nvidia,pins = "kb_row3_pr3", @@ -638,77 +669,77 @@ "kb_row6_pr6", "kb_row8_ps0"; nvidia,function = "kbc"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; clk3_req_pee1 { nvidia,pins = "clk3_req_pee1"; nvidia,function = "rsvd4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pu4 { nvidia,pins = "pu4"; nvidia,function = "displayb"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; pu5 { nvidia,pins = "pu5", "pu6"; nvidia,function = "displayb"; - nvidia,pull = <0>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; hdmi_int_pn7 { nvidia,pins = "hdmi_int_pn7"; nvidia,function = "rsvd1"; - nvidia,pull = <1>; - nvidia,tristate = <0>; - nvidia,enable-input = <1>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; clk1_req_pee2 { nvidia,pins = "clk1_req_pee2", "usb_vbus_en1_pn5"; nvidia,function = "rsvd4"; - nvidia,pull = <1>; - nvidia,tristate = <1>; - nvidia,enable-input = <0>; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; }; drive_sdio1 { nvidia,pins = "drive_sdio1"; - nvidia,high-speed-mode = <1>; - nvidia,schmitt = <0>; - nvidia,low-power-mode = <3>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; nvidia,pull-down-strength = <36>; nvidia,pull-up-strength = <20>; - nvidia,slew-rate-rising = <2>; - nvidia,slew-rate-falling = <2>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; }; drive_sdio3 { nvidia,pins = "drive_sdio3"; - nvidia,high-speed-mode = <1>; - nvidia,schmitt = <0>; - nvidia,low-power-mode = <3>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; nvidia,pull-down-strength = <22>; nvidia,pull-up-strength = <36>; - nvidia,slew-rate-rising = <0>; - nvidia,slew-rate-falling = <0>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; }; drive_gma { nvidia,pins = "drive_gma"; - nvidia,high-speed-mode = <1>; - nvidia,schmitt = <0>; - nvidia,low-power-mode = <3>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; nvidia,pull-down-strength = <2>; nvidia,pull-up-strength = <1>; - nvidia,slew-rate-rising = <0>; - nvidia,slew-rate-falling = <0>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; nvidia,drive-type = <1>; }; }; @@ -718,11 +749,15 @@ status = "okay"; }; + pwm@7000a000 { + status = "okay"; + }; + i2c@7000c000 { status = "okay"; clock-frequency = <100000>; - battery: smart-battery { + battery: smart-battery@b { compatible = "ti,bq20z45", "sbs,sbs-battery"; reg = <0xb>; battery-name = "battery"; @@ -731,7 +766,7 @@ power-supplies = <&charger>; }; - rt5640: rt5640 { + rt5640: rt5640@1c { compatible = "realtek,rt5640"; reg = <0x1c>; interrupt-parent = <&gpio>; @@ -749,11 +784,15 @@ }; }; + hdmi_ddc: i2c@7000c700 { + status = "okay"; + }; + i2c@7000d000 { status = "okay"; clock-frequency = <400000>; - tps51632 { + tps51632@43 { compatible = "ti,tps51632"; reg = <0x43>; regulator-name = "vdd-cpu"; @@ -763,7 +802,7 @@ regulator-always-on; }; - tps65090 { + tps65090@48 { compatible = "ti,tps65090"; reg = <0x48>; interrupt-parent = <&gpio>; @@ -806,7 +845,7 @@ regulator-boot-on; }; - fet1 { + vdd_bl_reg: fet1 { regulator-name = "vdd-lcd-bl"; }; @@ -814,7 +853,7 @@ regulator-name = "vdd-modem-3v3"; }; - fet4 { + avdd_lcd_reg: fet4 { regulator-name = "avdd-lcd"; }; @@ -846,7 +885,7 @@ }; }; - palmas: tps65913 { + palmas: tps65913@58 { compatible = "ti,palmas"; reg = <0x58>; interrupts = <0 86 IRQ_TYPE_LEVEL_LOW>; @@ -1046,7 +1085,7 @@ }; }; - pmc { + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <500>; @@ -1057,7 +1096,7 @@ nvidia,sys-clock-req-active-high; }; - ahub { + ahub@70080000 { i2s@70080400 { status = "okay"; }; @@ -1084,12 +1123,23 @@ vbus-supply = <&usb3_vbus_reg>; }; + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_bl_reg>; + pwms = <&pwm 1 1000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + clocks { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -1150,16 +1200,6 @@ gpio = <&gpio TEGRA_GPIO(H, 5) GPIO_ACTIVE_HIGH>; }; - lcd_bl_en_reg: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "lcd_bl_en"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - gpio = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; - }; - usb1_vbus_reg: regulator@3 { compatible = "regulator-fixed"; reg = <3>; diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 8d42787c8ff1..389e987ec281 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -1,5 +1,6 @@ #include #include +#include #include #include "skeleton.dtsi" @@ -15,7 +16,113 @@ serial3 = &uartd; }; - gic: interrupt-controller { + host1x@50000000 { + compatible = "nvidia,tegra114-host1x", "simple-bus"; + reg = <0x50000000 0x00028000>; + interrupts = , /* syncpt */ + ; /* general */ + clocks = <&tegra_car TEGRA114_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; + + #address-cells = <1>; + #size-cells = <1>; + + ranges = <0x54000000 0x54000000 0x01000000>; + + gr2d@54140000 { + compatible = "nvidia,tegra114-gr2d", "nvidia,tegra20-gr2d"; + reg = <0x54140000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_GR2D>; + resets = <&tegra_car 21>; + reset-names = "2d"; + }; + + gr3d@54180000 { + compatible = "nvidia,tegra114-gr3d", "nvidia,tegra20-gr3d"; + reg = <0x54180000 0x00040000>; + clocks = <&tegra_car TEGRA114_CLK_GR3D>; + resets = <&tegra_car 24>; + reset-names = "3d"; + }; + + dc@54200000 { + compatible = "nvidia,tegra114-dc", "nvidia,tegra20-dc"; + reg = <0x54200000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_DISP1>, + <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "dc", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; + + rgb { + status = "disabled"; + }; + }; + + dc@54240000 { + compatible = "nvidia,tegra114-dc", "nvidia,tegra20-dc"; + reg = <0x54240000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_DISP2>, + <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "dc", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; + + rgb { + status = "disabled"; + }; + }; + + hdmi@54280000 { + compatible = "nvidia,tegra114-hdmi"; + reg = <0x54280000 0x00040000>; + interrupts = ; + clocks = <&tegra_car TEGRA114_CLK_HDMI>, + <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>; + clock-names = "hdmi", "parent"; + resets = <&tegra_car 51>; + reset-names = "hdmi"; + status = "disabled"; + }; + + dsi@54300000 { + compatible = "nvidia,tegra114-dsi"; + reg = <0x54300000 0x00040000>; + clocks = <&tegra_car TEGRA114_CLK_DSIA>, + <&tegra_car TEGRA114_CLK_DSIALP>, + <&tegra_car TEGRA114_CLK_PLL_D_OUT0>; + clock-names = "dsi", "lp", "parent"; + resets = <&tegra_car 48>; + reset-names = "dsi"; + nvidia,mipi-calibrate = <&mipi 0x060>; /* DSIA & DSIB pads */ + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + + dsi@54400000 { + compatible = "nvidia,tegra114-dsi"; + reg = <0x54400000 0x00040000>; + clocks = <&tegra_car TEGRA114_CLK_DSIB>, + <&tegra_car TEGRA114_CLK_DSIBLP>, + <&tegra_car TEGRA114_CLK_PLL_D2_OUT0>; + clock-names = "dsi", "lp", "parent"; + resets = <&tegra_car 82>; + reset-names = "dsi"; + nvidia,mipi-calibrate = <&mipi 0x180>; /* DSIC & DSID pads */ + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + gic: interrupt-controller@50041000 { compatible = "arm,cortex-a15-gic"; #interrupt-cells = <3>; interrupt-controller; @@ -39,13 +146,14 @@ clocks = <&tegra_car TEGRA114_CLK_TIMER>; }; - tegra_car: clock { + tegra_car: clock@60006000 { compatible = "nvidia,tegra114-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; - apbdma: dma { + apbdma: dma@6000a000 { compatible = "nvidia,tegra114-apbdma"; reg = <0x6000a000 0x1400>; interrupts = , @@ -81,14 +189,17 @@ , ; clocks = <&tegra_car TEGRA114_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; - ahb: ahb { + ahb: ahb@6000c004 { compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb"; reg = <0x6000c004 0x14c>; }; - gpio: gpio { + gpio: gpio@6000d000 { compatible = "nvidia,tegra114-gpio", "nvidia,tegra30-gpio"; reg = <0x6000d000 0x1000>; interrupts = , @@ -105,7 +216,7 @@ interrupt-controller; }; - pinmux: pinmux { + pinmux: pinmux@70000868 { compatible = "nvidia,tegra114-pinmux"; reg = <0x70000868 0x148 /* Pad control registers */ 0x70003000 0x40c>; /* Mux registers */ @@ -124,9 +235,12 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 8>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; + status = "disabled"; }; uartb: serial@70006040 { @@ -134,9 +248,12 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 9>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; + status = "disabled"; }; uartc: serial@70006200 { @@ -144,9 +261,12 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 10>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; + status = "disabled"; }; uartd: serial@70006300 { @@ -154,16 +274,21 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 19>; - status = "disabled"; clocks = <&tegra_car TEGRA114_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; + status = "disabled"; }; - pwm: pwm { + pwm: pwm@7000a000 { compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm"; reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA114_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; status = "disabled"; }; @@ -175,6 +300,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C1>; clock-names = "div-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -186,6 +315,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C2>; clock-names = "div-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -197,6 +330,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C3>; clock-names = "div-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -208,6 +345,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C4>; clock-names = "div-clk"; + resets = <&tegra_car 103>; + reset-names = "i2c"; + dmas = <&apbdma 26>, <&apbdma 26>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -219,6 +360,10 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_I2C5>; clock-names = "div-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -226,11 +371,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000d400 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 15>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC1>; clock-names = "spi"; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -238,11 +386,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000d600 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 16>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC2>; clock-names = "spi"; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -250,11 +401,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000d800 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC3>; clock-names = "spi"; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -262,11 +416,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000da00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 18>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC4>; clock-names = "spi"; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -274,11 +431,14 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000dc00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 27>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC5>; clock-names = "spi"; + resets = <&tegra_car 104>; + reset-names = "spi"; + dmas = <&apbdma 27>, <&apbdma 27>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -286,37 +446,42 @@ compatible = "nvidia,tegra114-spi"; reg = <0x7000de00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 28>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA114_CLK_SBC6>; clock-names = "spi"; + resets = <&tegra_car 105>; + reset-names = "spi"; + dmas = <&apbdma 28>, <&apbdma 28>; + dma-names = "rx", "tx"; status = "disabled"; }; - rtc { + rtc@7000e000 { compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = ; clocks = <&tegra_car TEGRA114_CLK_RTC>; }; - kbc { + kbc@7000e200 { compatible = "nvidia,tegra114-kbc"; reg = <0x7000e200 0x100>; interrupts = ; clocks = <&tegra_car TEGRA114_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; status = "disabled"; }; - pmc { + pmc@7000e400 { compatible = "nvidia,tegra114-pmc"; reg = <0x7000e400 0x400>; clocks = <&tegra_car TEGRA114_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; }; - iommu { + iommu@70019010 { compatible = "nvidia,tegra114-smmu", "nvidia,tegra30-smmu"; reg = <0x70019010 0x02c 0x700191f0 0x010 @@ -327,32 +492,45 @@ nvidia,ahb = <&ahb>; }; - ahub { + ahub@70080000 { compatible = "nvidia,tegra114-ahub"; reg = <0x70080000 0x200>, <0x70080200 0x100>, <0x70081000 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 1>, <&apbdma 2>, - <&apbdma 3>, <&apbdma 4>, <&apbdma 6>, <&apbdma 7>, - <&apbdma 12>, <&apbdma 13>, <&apbdma 14>, - <&apbdma 29>; clocks = <&tegra_car TEGRA114_CLK_D_AUDIO>, - <&tegra_car TEGRA114_CLK_APBIF>, - <&tegra_car TEGRA114_CLK_I2S0>, - <&tegra_car TEGRA114_CLK_I2S1>, - <&tegra_car TEGRA114_CLK_I2S2>, - <&tegra_car TEGRA114_CLK_I2S3>, - <&tegra_car TEGRA114_CLK_I2S4>, - <&tegra_car TEGRA114_CLK_DAM0>, - <&tegra_car TEGRA114_CLK_DAM1>, - <&tegra_car TEGRA114_CLK_DAM2>, - <&tegra_car TEGRA114_CLK_SPDIF_IN>, - <&tegra_car TEGRA114_CLK_AMX>, - <&tegra_car TEGRA114_CLK_ADX>; - clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + <&tegra_car TEGRA114_CLK_APBIF>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, /* d_audio */ + <&tegra_car 107>, /* apbif */ + <&tegra_car 30>, /* i2s0 */ + <&tegra_car 11>, /* i2s1 */ + <&tegra_car 18>, /* i2s2 */ + <&tegra_car 101>, /* i2s3 */ + <&tegra_car 102>, /* i2s4 */ + <&tegra_car 108>, /* dam0 */ + <&tegra_car 109>, /* dam1 */ + <&tegra_car 110>, /* dam2 */ + <&tegra_car 10>, /* spdif */ + <&tegra_car 153>, /* amx */ + <&tegra_car 154>; /* adx */ + reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", "i2s3", "i2s4", "dam0", "dam1", "dam2", - "spdif_in", "amx", "adx"; + "spdif", "amx", "adx"; + dmas = <&apbdma 1>, <&apbdma 1>, + <&apbdma 2>, <&apbdma 2>, + <&apbdma 3>, <&apbdma 3>, + <&apbdma 4>, <&apbdma 4>, + <&apbdma 6>, <&apbdma 6>, + <&apbdma 7>, <&apbdma 7>, + <&apbdma 12>, <&apbdma 12>, + <&apbdma 13>, <&apbdma 13>, + <&apbdma 14>, <&apbdma 14>, + <&apbdma 29>, <&apbdma 29>; + dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", + "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", + "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", + "rx9", "tx9"; ranges; #address-cells = <1>; #size-cells = <1>; @@ -362,6 +540,8 @@ reg = <0x70080300 0x100>; nvidia,ahub-cif-ids = <4 4>; clocks = <&tegra_car TEGRA114_CLK_I2S0>; + resets = <&tegra_car 30>; + reset-names = "i2s"; status = "disabled"; }; @@ -370,6 +550,8 @@ reg = <0x70080400 0x100>; nvidia,ahub-cif-ids = <5 5>; clocks = <&tegra_car TEGRA114_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; status = "disabled"; }; @@ -378,6 +560,8 @@ reg = <0x70080500 0x100>; nvidia,ahub-cif-ids = <6 6>; clocks = <&tegra_car TEGRA114_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; status = "disabled"; }; @@ -386,6 +570,8 @@ reg = <0x70080600 0x100>; nvidia,ahub-cif-ids = <7 7>; clocks = <&tegra_car TEGRA114_CLK_I2S3>; + resets = <&tegra_car 101>; + reset-names = "i2s"; status = "disabled"; }; @@ -394,15 +580,26 @@ reg = <0x70080700 0x100>; nvidia,ahub-cif-ids = <8 8>; clocks = <&tegra_car TEGRA114_CLK_I2S4>; + resets = <&tegra_car 102>; + reset-names = "i2s"; status = "disabled"; }; }; + mipi: mipi@700e3000 { + compatible = "nvidia,tegra114-mipi"; + reg = <0x700e3000 0x100>; + clocks = <&tegra_car TEGRA114_CLK_MIPI_CAL>; + #nvidia,mipi-calibrate-cells = <1>; + }; + sdhci@78000000 { compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci"; reg = <0x78000000 0x200>; interrupts = ; clocks = <&tegra_car TEGRA114_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; status = "disable"; }; @@ -411,6 +608,8 @@ reg = <0x78000200 0x200>; interrupts = ; clocks = <&tegra_car TEGRA114_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; status = "disable"; }; @@ -419,6 +618,8 @@ reg = <0x78000400 0x200>; interrupts = ; clocks = <&tegra_car TEGRA114_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; status = "disable"; }; @@ -427,6 +628,8 @@ reg = <0x78000600 0x200>; interrupts = ; clocks = <&tegra_car TEGRA114_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; status = "disable"; }; @@ -436,6 +639,8 @@ interrupts = ; phy_type = "utmi"; clocks = <&tegra_car TEGRA114_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; nvidia,phy = <&phy1>; status = "disabled"; }; @@ -467,6 +672,8 @@ interrupts = ; phy_type = "utmi"; clocks = <&tegra_car TEGRA114_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; nvidia,phy = <&phy3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts index 431d67a2b413..c6dcef513e5d 100644 --- a/arch/arm/boot/dts/tegra124-venice2.dts +++ b/arch/arm/boot/dts/tegra124-venice2.dts @@ -1,19 +1,917 @@ /dts-v1/; +#include #include "tegra124.dtsi" / { model = "NVIDIA Tegra124 Venice2"; compatible = "nvidia,venice2", "nvidia,tegra124"; + aliases { + rtc0 = "/i2c@7000d000/as3722@40"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x80000000 0x80000000>; }; + pinmux: pinmux@70000868 { + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_default>; + + pinmux_default: common { + dap_mclk1_pw4 { + nvidia,pins = "dap_mclk1_pw4"; + nvidia,function = "extperiph1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap1_din_pn1 { + nvidia,pins = "dap1_din_pn1"; + nvidia,function = "i2s0"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap1_dout_pn2 { + nvidia,pins = "dap1_dout_pn2", + "dap1_fs_pn0", + "dap1_sclk_pn3"; + nvidia,function = "i2s0"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap2_din_pa4 { + nvidia,pins = "dap2_din_pa4"; + nvidia,function = "i2s1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap2_dout_pa5 { + nvidia,pins = "dap2_dout_pa5", + "dap2_fs_pa2", + "dap2_sclk_pa3"; + nvidia,function = "i2s1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dvfs_pwm_px0 { + nvidia,pins = "dvfs_pwm_px0", + "dvfs_clk_px2"; + nvidia,function = "cldvfs"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + ulpi_clk_py0 { + nvidia,pins = "ulpi_clk_py0", + "ulpi_nxt_py2", + "ulpi_stp_py3"; + nvidia,function = "spi1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + ulpi_dir_py1 { + nvidia,pins = "ulpi_dir_py1"; + nvidia,function = "spi1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + cam_i2c_scl_pbb1 { + nvidia,pins = "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2"; + nvidia,function = "i2c3"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + gen2_i2c_scl_pt5 { + nvidia,pins = "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6"; + nvidia,function = "i2c2"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + pg4 { + nvidia,pins = "pg4", + "pg5", + "pg6", + "pi3"; + nvidia,function = "spi4"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + pg7 { + nvidia,pins = "pg7"; + nvidia,function = "spi4"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + ph1 { + nvidia,pins = "ph1"; + nvidia,function = "pwm1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + pk0 { + nvidia,pins = "pk0", + "kb_row15_ps7", + "clk_32k_out_pa0"; + nvidia,function = "soc"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + sdmmc1_clk_pz0 { + nvidia,pins = "sdmmc1_clk_pz0", + "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc1_cmd_pz1 { + nvidia,pins = "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4"; + nvidia,function = "sdmmc1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc3_clk_pa6 { + nvidia,pins = "sdmmc3_clk_pa6"; + nvidia,function = "sdmmc3"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc3_cmd_pa7 { + nvidia,pins = "sdmmc3_cmd_pa7", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "sdmmc3_clk_lb_out_pee4", + "sdmmc3_clk_lb_in_pee5"; + nvidia,function = "sdmmc3"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc4_clk_pcc4 { + nvidia,pins = "sdmmc4_clk_pcc4"; + nvidia,function = "sdmmc4"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + sdmmc4_cmd_pt7 { + nvidia,pins = "sdmmc4_cmd_pt7", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7"; + nvidia,function = "sdmmc4"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + pwr_i2c_scl_pz6 { + nvidia,pins = "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7"; + nvidia,function = "i2cpwr"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + jtag_rtck { + nvidia,pins = "jtag_rtck"; + nvidia,function = "rtck"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + clk_32k_in { + nvidia,pins = "clk_32k_in"; + nvidia,function = "clk"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + core_pwr_req { + nvidia,pins = "core_pwr_req"; + nvidia,function = "pwron"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + cpu_pwr_req { + nvidia,pins = "cpu_pwr_req"; + nvidia,function = "cpu"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + pwr_int_n { + nvidia,pins = "pwr_int_n"; + nvidia,function = "pmi"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + reset_out_n { + nvidia,pins = "reset_out_n"; + nvidia,function = "reset_out_n"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + clk3_out_pee0 { + nvidia,pins = "clk3_out_pee0"; + nvidia,function = "extperiph3"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap4_din_pp5 { + nvidia,pins = "dap4_din_pp5"; + nvidia,function = "i2s3"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + dap4_dout_pp6 { + nvidia,pins = "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7"; + nvidia,function = "i2s3"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + gen1_i2c_sda_pc5 { + nvidia,pins = "gen1_i2c_sda_pc5", + "gen1_i2c_scl_pc4"; + nvidia,function = "i2c1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + uart2_cts_n_pj5 { + nvidia,pins = "uart2_cts_n_pj5"; + nvidia,function = "uartb"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + uart2_rts_n_pj6 { + nvidia,pins = "uart2_rts_n_pj6"; + nvidia,function = "uartb"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + uart2_rxd_pc3 { + nvidia,pins = "uart2_rxd_pc3"; + nvidia,function = "irda"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + uart2_txd_pc2 { + nvidia,pins = "uart2_txd_pc2"; + nvidia,function = "irda"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + uart3_cts_n_pa1 { + nvidia,pins = "uart3_cts_n_pa1", + "uart3_rxd_pw7"; + nvidia,function = "uartc"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + uart3_rts_n_pc0 { + nvidia,pins = "uart3_rts_n_pc0", + "uart3_txd_pw6"; + nvidia,function = "uartc"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + hdmi_cec_pee3 { + nvidia,pins = "hdmi_cec_pee3"; + nvidia,function = "cec"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + hdmi_int_pn7 { + nvidia,pins = "hdmi_int_pn7"; + nvidia,function = "rsvd1"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + }; + ddc_scl_pv4 { + nvidia,pins = "ddc_scl_pv4", + "ddc_sda_pv5"; + nvidia,function = "i2c4"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,rcv-sel = ; + }; + pj7 { + nvidia,pins = "pj7", + "pk7"; + nvidia,function = "uartd"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + pb0 { + nvidia,pins = "pb0", + "pb1"; + nvidia,function = "uartd"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + ph0 { + nvidia,pins = "ph0"; + nvidia,function = "pwm0"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb_row10_ps2 { + nvidia,pins = "kb_row10_ps2"; + nvidia,function = "uarta"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb_row9_ps1 { + nvidia,pins = "kb_row9_ps1"; + nvidia,function = "uarta"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb_row6_pr6 { + nvidia,pins = "kb_row6_pr6"; + nvidia,function = "displaya_alt"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + usb_vbus_en0_pn4 { + nvidia,pins = "usb_vbus_en0_pn4"; + nvidia,function = "usb"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + usb_vbus_en1_pn5 { + nvidia,pins = "usb_vbus_en1_pn5"; + nvidia,function = "usb"; + nvidia,enable-input = ; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,lock = ; + nvidia,open-drain = ; + }; + drive_sdio1 { + nvidia,pins = "drive_sdio1"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <32>; + nvidia,pull-up-strength = <42>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + drive_sdio3 { + nvidia,pins = "drive_sdio3"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <20>; + nvidia,pull-up-strength = <36>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + drive_gma { + nvidia,pins = "drive_gma"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <1>; + nvidia,pull-up-strength = <2>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + nvidia,drive-type = <1>; + }; + als_irq_l { + nvidia,pins = "gpio_x3_aud_px3"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + codec_irq_l { + nvidia,pins = "ph4"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + lcd_bl_en { + nvidia,pins = "ph2"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + touch_irq_l { + nvidia,pins = "gpio_w3_aud_pw3"; + nvidia,function = "spi6"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + tpm_davint_l { + nvidia,pins = "ph6"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + ts_irq_l { + nvidia,pins = "pk2"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + ts_reset_l { + nvidia,pins = "pk4"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + ts_shdn_l { + nvidia,pins = "pk1"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + ph7 { + nvidia,pins = "ph7"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + kb_col0_ap { + nvidia,pins = "kb_col0_pq0"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + lid_open { + nvidia,pins = "kb_row4_pr4"; + nvidia,function = "rsvd3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + en_vdd_sd { + nvidia,pins = "kb_row0_pr0"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + ac_ok { + nvidia,pins = "pj0"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + sensor_irq_l { + nvidia,pins = "pi6"; + nvidia,function = "gmi"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + wifi_en { + nvidia,pins = "gpio_x7_aud_px7"; + nvidia,function = "rsvd4"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + wifi_rst_l { + nvidia,pins = "clk2_req_pcc5"; + nvidia,function = "dap"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + hp_det_l { + nvidia,pins = "ulpi_data1_po2"; + nvidia,function = "spi3"; + nvidia,pull = ; + nvidia,tristate = ; + nvidia,enable-input = ; + }; + }; + }; + serial@70006000 { status = "okay"; }; + pwm: pwm@7000a000 { + status = "okay"; + }; + + i2c@7000c000 { + status = "okay"; + clock-frequency = <100000>; + + acodec: audio-codec@10 { + compatible = "maxim,max98090"; + reg = <0x10>; + interrupt-parent = <&gpio>; + interrupts = ; + }; + }; + + i2c@7000c400 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000c500 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000c700 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + as3722: as3722@40 { + compatible = "ams,as3722"; + reg = <0x40>; + interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; + + #interrupt-cells = <2>; + interrupt-controller; + + gpio-controller; + #gpio-cells = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&as3722_default>; + + as3722_default: pinmux { + gpio0 { + pins = "gpio0"; + function = "gpio"; + bias-pull-down; + }; + + gpio1_2_4_7 { + pins = "gpio1", "gpio2", "gpio4", "gpio7"; + function = "gpio"; + bias-pull-up; + }; + + gpio3_6 { + pins = "gpio3", "gpio6"; + bias-high-impedance; + }; + + gpio5 { + pins = "gpio5"; + function = "clk32k-out"; + }; + }; + + regulators { + vsup-sd2-supply = <&vdd_ac_bat_reg>; + vsup-sd3-supply = <&vdd_ac_bat_reg>; + vsup-sd4-supply = <&vdd_ac_bat_reg>; + vsup-sd5-supply = <&vdd_ac_bat_reg>; + vin-ldo0-supply = <&as3722_sd2>; + vin-ldo1-6-supply = <&vdd_ac_bat_reg>; + vin-ldo2-5-7-supply = <&as3722_sd5>; + vin-ldo3-4-supply = <&vdd_ac_bat_reg>; + vin-ldo9-10-supply = <&vdd_ac_bat_reg>; + vin-ldo11-supply = <&vdd_ac_bat_reg>; + + sd0 { + regulator-name = "vdd-cpu"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1400000>; + regulator-min-microamp = <3500000>; + regulator-max-microamp = <3500000>; + regulator-always-on; + regulator-boot-on; + ams,external-control = <2>; + }; + + sd1 { + regulator-name = "vdd-core"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-min-microamp = <2500000>; + regulator-max-microamp = <2500000>; + regulator-always-on; + regulator-boot-on; + ams,external-control = <1>; + }; + + as3722_sd2: sd2 { + regulator-name = "vddio-ddr"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + sd3 { + regulator-name = "vddio-ddr-2phase"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + }; + + sd4 { + regulator-name = "avdd-pex-sata"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-boot-on; + regulator-always-on; + }; + + as3722_sd5: sd5 { + regulator-name = "vddio-sys"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + sd6 { + regulator-name = "vdd-gpu"; + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <1200000>; + regulator-min-microamp = <3500000>; + regulator-max-microamp = <3500000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo0 { + regulator-name = "avdd_pll"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-boot-on; + regulator-always-on; + ams,external-control = <1>; + }; + + ldo1 { + regulator-name = "run-cam-1.8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo2 { + regulator-name = "gen-avdd,vddio-hsic"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3 { + regulator-name = "vdd-rtc"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-boot-on; + regulator-always-on; + ams,enable-tracking; + }; + + ldo4 { + regulator-name = "vdd-cam"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5 { + regulator-name = "vdd-cam-front"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo6 { + regulator-name = "vddio-sdmmc3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo7 { + regulator-name = "vdd-cam-rear"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + }; + + ldo9 { + regulator-name = "vdd-touch"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo10 { + regulator-name = "vdd-cam-af"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + ldo11 { + regulator-name = "vpp-fuse"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + }; + }; + }; + + spi@7000d400 { + status = "okay"; + + cros-ec@0 { + compatible = "google,cros-ec-spi"; + spi-max-frequency = <4000000>; + interrupt-parent = <&gpio>; + interrupts = ; + reg = <0>; + + google,cros-ec-spi-msg-delay = <2000>; + + cros-ec-keyb { + compatible = "google,cros-ec-keyb"; + keypad,num-rows = <8>; + keypad,num-columns = <13>; + google,needs-ghost-filter; + + linux,keymap = < + MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA) + MATRIX_KEY(0x00, 0x02, KEY_F1) + MATRIX_KEY(0x00, 0x03, KEY_B) + MATRIX_KEY(0x00, 0x04, KEY_F10) + MATRIX_KEY(0x00, 0x06, KEY_N) + MATRIX_KEY(0x00, 0x08, KEY_EQUAL) + MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT) + + MATRIX_KEY(0x01, 0x01, KEY_ESC) + MATRIX_KEY(0x01, 0x02, KEY_F4) + MATRIX_KEY(0x01, 0x03, KEY_G) + MATRIX_KEY(0x01, 0x04, KEY_F7) + MATRIX_KEY(0x01, 0x06, KEY_H) + MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE) + MATRIX_KEY(0x01, 0x09, KEY_F9) + MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE) + + MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL) + MATRIX_KEY(0x02, 0x01, KEY_TAB) + MATRIX_KEY(0x02, 0x02, KEY_F3) + MATRIX_KEY(0x02, 0x03, KEY_T) + MATRIX_KEY(0x02, 0x04, KEY_F6) + MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE) + MATRIX_KEY(0x02, 0x06, KEY_Y) + MATRIX_KEY(0x02, 0x07, KEY_102ND) + MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE) + MATRIX_KEY(0x02, 0x09, KEY_F8) + + MATRIX_KEY(0x03, 0x01, KEY_GRAVE) + MATRIX_KEY(0x03, 0x02, KEY_F2) + MATRIX_KEY(0x03, 0x03, KEY_5) + MATRIX_KEY(0x03, 0x04, KEY_F5) + MATRIX_KEY(0x03, 0x06, KEY_6) + MATRIX_KEY(0x03, 0x08, KEY_MINUS) + MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH) + + MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL) + MATRIX_KEY(0x04, 0x01, KEY_A) + MATRIX_KEY(0x04, 0x02, KEY_D) + MATRIX_KEY(0x04, 0x03, KEY_F) + MATRIX_KEY(0x04, 0x04, KEY_S) + MATRIX_KEY(0x04, 0x05, KEY_K) + MATRIX_KEY(0x04, 0x06, KEY_J) + MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON) + MATRIX_KEY(0x04, 0x09, KEY_L) + MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH) + MATRIX_KEY(0x04, 0x0b, KEY_ENTER) + + MATRIX_KEY(0x05, 0x01, KEY_Z) + MATRIX_KEY(0x05, 0x02, KEY_C) + MATRIX_KEY(0x05, 0x03, KEY_V) + MATRIX_KEY(0x05, 0x04, KEY_X) + MATRIX_KEY(0x05, 0x05, KEY_COMMA) + MATRIX_KEY(0x05, 0x06, KEY_M) + MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT) + MATRIX_KEY(0x05, 0x08, KEY_SLASH) + MATRIX_KEY(0x05, 0x09, KEY_DOT) + MATRIX_KEY(0x05, 0x0b, KEY_SPACE) + + MATRIX_KEY(0x06, 0x01, KEY_1) + MATRIX_KEY(0x06, 0x02, KEY_3) + MATRIX_KEY(0x06, 0x03, KEY_4) + MATRIX_KEY(0x06, 0x04, KEY_2) + MATRIX_KEY(0x06, 0x05, KEY_8) + MATRIX_KEY(0x06, 0x06, KEY_7) + MATRIX_KEY(0x06, 0x08, KEY_0) + MATRIX_KEY(0x06, 0x09, KEY_9) + MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT) + MATRIX_KEY(0x06, 0x0b, KEY_DOWN) + MATRIX_KEY(0x06, 0x0c, KEY_RIGHT) + + MATRIX_KEY(0x07, 0x01, KEY_Q) + MATRIX_KEY(0x07, 0x02, KEY_E) + MATRIX_KEY(0x07, 0x03, KEY_R) + MATRIX_KEY(0x07, 0x04, KEY_W) + MATRIX_KEY(0x07, 0x05, KEY_I) + MATRIX_KEY(0x07, 0x06, KEY_U) + MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT) + MATRIX_KEY(0x07, 0x08, KEY_P) + MATRIX_KEY(0x07, 0x09, KEY_O) + MATRIX_KEY(0x07, 0x0b, KEY_UP) + MATRIX_KEY(0x07, 0x0c, KEY_LEFT) + >; + }; + }; + }; + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; @@ -24,4 +922,170 @@ nvidia,core-power-req-active-high; nvidia,sys-clock-req-active-high; }; + + sdhci@700b0400 { + cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>; + status = "okay"; + bus-width = <4>; + }; + + sdhci@700b0600 { + status = "okay"; + bus-width = <8>; + }; + + ahub@70300000 { + i2s@70301100 { + status = "okay"; + }; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk32k_in: clock@0 { + compatible = "fixed-clock"; + reg=<0>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + gpio-key,wakeup; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_ac_bat_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_ac_bat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + vdd_3v3_reg: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&as3722 1 GPIO_ACTIVE_HIGH>; + }; + + vdd_3v3_modem_reg: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "vdd-modem-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&as3722 2 GPIO_ACTIVE_HIGH>; + }; + + vdd_hdmi_5v0_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "vdd-hdmi-5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>; + }; + + vdd_bl_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "vdd-bl"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_LOW>; + }; + + vdd_ts_sw_5v0: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + regulator-name = "vdd_ts_sw"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_LOW>; + }; + + usb1_vbus_reg: regulator@6 { + compatible = "regulator-fixed"; + reg = <6>; + regulator-name = "usb1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; + gpio-open-drain; + }; + + usb3_vbus_reg: regulator@7 { + compatible = "regulator-fixed"; + reg = <7>; + regulator-name = "usb3_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + enable-active-high; + gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>; + gpio-open-drain; + }; + + panel_3v3_reg: regulator@8 { + compatible = "regulator-fixed"; + reg = <8>; + regulator-name = "panel_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpio = <&as3722 4 GPIO_ACTIVE_HIGH>; + }; + }; + + sound { + compatible = "nvidia,tegra-audio-max98090-venice2", + "nvidia,tegra-audio-max98090"; + nvidia,model = "NVIDIA Tegra Venice2"; + + nvidia,audio-routing = + "Headphones", "HPR", + "Headphones", "HPL", + "Speakers", "SPKR", + "Speakers", "SPKL", + "Mic Jack", "MICBIAS", + "IN34", "Mic Jack"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&acodec>; + + clocks = <&tegra_car TEGRA124_CLK_PLL_A>, + <&tegra_car TEGRA124_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA124_CLK_EXTERN1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; + }; }; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index b7413004ee77..ec0698a8354a 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -1,4 +1,6 @@ +#include #include +#include #include #include "skeleton.dtsi" @@ -28,6 +30,14 @@ , , ; + clocks = <&tegra_car TEGRA124_CLK_TIMER>; + }; + + tegra_car: clock@60006000 { + compatible = "nvidia,tegra124-car"; + reg = <0x60006000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; }; gpio: gpio@6000d000 { @@ -47,6 +57,53 @@ interrupt-controller; }; + apbdma: dma@60020000 { + compatible = "nvidia,tegra124-apbdma", "nvidia,tegra148-apbdma"; + reg = <0x60020000 0x1400>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + clocks = <&tegra_car TEGRA124_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; + }; + + pinmux: pinmux@70000868 { + compatible = "nvidia,tegra124-pinmux"; + reg = <0x70000868 0x164>, /* Pad control registers */ + <0x70003000 0x434>; /* Mux registers */ + }; + /* * There are two serial driver i.e. 8250 based simple serial * driver and APB DMA based serial driver for higher baudrate @@ -60,6 +117,11 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -68,6 +130,11 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -76,6 +143,11 @@ reg = <0x70006200 0x40>; reg-shift = <2>; interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -84,6 +156,11 @@ reg = <0x70006300 0x40>; reg-shift = <2>; interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -92,6 +169,201 @@ reg = <0x70006400 0x40>; reg-shift = <2>; interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_UARTE>; + resets = <&tegra_car 66>; + reset-names = "serial"; + dmas = <&apbdma 20>, <&apbdma 20>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + pwm@7000a000 { + compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm"; + reg = <0x7000a000 0x100>; + #pwm-cells = <2>; + clocks = <&tegra_car TEGRA124_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; + status = "disabled"; + }; + + i2c@7000c000 { + compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c"; + reg = <0x7000c000 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_I2C1>; + clock-names = "div-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000c400 { + compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c"; + reg = <0x7000c400 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_I2C2>; + clock-names = "div-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000c500 { + compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c"; + reg = <0x7000c500 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_I2C3>; + clock-names = "div-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000c700 { + compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c"; + reg = <0x7000c700 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_I2C4>; + clock-names = "div-clk"; + resets = <&tegra_car 103>; + reset-names = "i2c"; + dmas = <&apbdma 26>, <&apbdma 26>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000d000 { + compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c"; + reg = <0x7000d000 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_I2C5>; + clock-names = "div-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + i2c@7000d100 { + compatible = "nvidia,tegra124-i2c", "nvidia,tegra114-i2c"; + reg = <0x7000d100 0x100>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_I2C6>; + clock-names = "div-clk"; + resets = <&tegra_car 166>; + reset-names = "i2c"; + dmas = <&apbdma 30>, <&apbdma 30>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000d400 { + compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi"; + reg = <0x7000d400 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_SBC1>; + clock-names = "spi"; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000d600 { + compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi"; + reg = <0x7000d600 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_SBC2>; + clock-names = "spi"; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000d800 { + compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi"; + reg = <0x7000d800 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_SBC3>; + clock-names = "spi"; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000da00 { + compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi"; + reg = <0x7000da00 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_SBC4>; + clock-names = "spi"; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000dc00 { + compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi"; + reg = <0x7000dc00 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_SBC5>; + clock-names = "spi"; + resets = <&tegra_car 104>; + reset-names = "spi"; + dmas = <&apbdma 27>, <&apbdma 27>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + spi@7000de00 { + compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi"; + reg = <0x7000de00 0x200>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&tegra_car TEGRA124_CLK_SBC6>; + clock-names = "spi"; + resets = <&tegra_car 105>; + reset-names = "spi"; + dmas = <&apbdma 28>, <&apbdma 28>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -99,11 +371,157 @@ compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_RTC>; }; pmc@7000e400 { compatible = "nvidia,tegra124-pmc"; reg = <0x7000e400 0x400>; + clocks = <&tegra_car TEGRA124_CLK_PCLK>, <&clk32k_in>; + clock-names = "pclk", "clk32k_in"; + }; + + sdhci@700b0000 { + compatible = "nvidia,tegra124-sdhci"; + reg = <0x700b0000 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; + status = "disable"; + }; + + sdhci@700b0200 { + compatible = "nvidia,tegra124-sdhci"; + reg = <0x700b0200 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; + status = "disable"; + }; + + sdhci@700b0400 { + compatible = "nvidia,tegra124-sdhci"; + reg = <0x700b0400 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; + status = "disable"; + }; + + sdhci@700b0600 { + compatible = "nvidia,tegra124-sdhci"; + reg = <0x700b0600 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; + status = "disable"; + }; + + ahub@70300000 { + compatible = "nvidia,tegra124-ahub"; + reg = <0x70300000 0x200>, + <0x70300800 0x800>, + <0x70300200 0x600>; + interrupts = ; + clocks = <&tegra_car TEGRA124_CLK_D_AUDIO>, + <&tegra_car TEGRA124_CLK_APBIF>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, /* d_audio */ + <&tegra_car 107>, /* apbif */ + <&tegra_car 30>, /* i2s0 */ + <&tegra_car 11>, /* i2s1 */ + <&tegra_car 18>, /* i2s2 */ + <&tegra_car 101>, /* i2s3 */ + <&tegra_car 102>, /* i2s4 */ + <&tegra_car 108>, /* dam0 */ + <&tegra_car 109>, /* dam1 */ + <&tegra_car 110>, /* dam2 */ + <&tegra_car 10>, /* spdif */ + <&tegra_car 153>, /* amx */ + <&tegra_car 185>, /* amx1 */ + <&tegra_car 154>, /* adx */ + <&tegra_car 180>, /* adx1 */ + <&tegra_car 186>, /* afc0 */ + <&tegra_car 187>, /* afc1 */ + <&tegra_car 188>, /* afc2 */ + <&tegra_car 189>, /* afc3 */ + <&tegra_car 190>, /* afc4 */ + <&tegra_car 191>; /* afc5 */ + reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + "i2s3", "i2s4", "dam0", "dam1", "dam2", + "spdif", "amx", "amx1", "adx", "adx1", + "afc0", "afc1", "afc2", "afc3", "afc4", "afc5"; + dmas = <&apbdma 1>, <&apbdma 1>, + <&apbdma 2>, <&apbdma 2>, + <&apbdma 3>, <&apbdma 3>, + <&apbdma 4>, <&apbdma 4>, + <&apbdma 6>, <&apbdma 6>, + <&apbdma 7>, <&apbdma 7>, + <&apbdma 12>, <&apbdma 12>, + <&apbdma 13>, <&apbdma 13>, + <&apbdma 14>, <&apbdma 14>, + <&apbdma 29>, <&apbdma 29>; + dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", + "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", + "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", + "rx9", "tx9"; + ranges; + #address-cells = <1>; + #size-cells = <1>; + + tegra_i2s0: i2s@70301000 { + compatible = "nvidia,tegra124-i2s"; + reg = <0x70301000 0x100>; + nvidia,ahub-cif-ids = <4 4>; + clocks = <&tegra_car TEGRA124_CLK_I2S0>; + resets = <&tegra_car 30>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s1: i2s@70301100 { + compatible = "nvidia,tegra124-i2s"; + reg = <0x70301100 0x100>; + nvidia,ahub-cif-ids = <5 5>; + clocks = <&tegra_car TEGRA124_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s2: i2s@70301200 { + compatible = "nvidia,tegra124-i2s"; + reg = <0x70301200 0x100>; + nvidia,ahub-cif-ids = <6 6>; + clocks = <&tegra_car TEGRA124_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s3: i2s@70301300 { + compatible = "nvidia,tegra124-i2s"; + reg = <0x70301300 0x100>; + nvidia,ahub-cif-ids = <7 7>; + clocks = <&tegra_car TEGRA124_CLK_I2S3>; + resets = <&tegra_car 101>; + reset-names = "i2s"; + status = "disabled"; + }; + + tegra_i2s4: i2s@70301400 { + compatible = "nvidia,tegra124-i2s"; + reg = <0x70301400 0x100>; + nvidia,ahub-cif-ids = <8 8>; + clocks = <&tegra_car TEGRA124_CLK_I2S4>; + resets = <&tegra_car 102>; + reset-names = "i2s"; + status = "disabled"; + }; }; cpus { diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi index d5c9bca01232..8e0066ad9628 100644 --- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi +++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi @@ -4,12 +4,17 @@ model = "Toradex Colibri T20 512MB"; compatible = "toradex,colibri_t20-512", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x20000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { vdd-supply = <&hdmi_vdd_reg>; pll-supply = <&hdmi_pll_reg>; @@ -19,7 +24,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -27,20 +32,20 @@ audio_refclk { nvidia,pins = "cdev1"; nvidia,function = "plla_out"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; crt { nvidia,pins = "crtp"; nvidia,function = "crt"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; dap3 { nvidia,pins = "dap3"; nvidia,function = "dap3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; displaya { nvidia,pins = "ld0", "ld1", "ld2", "ld3", @@ -50,155 +55,163 @@ "lhs", "lpw0", "lpw2", "lsc0", "lsc1", "lsck", "lsda", "lspi", "lvs"; nvidia,function = "displaya"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; gpio_dte { nvidia,pins = "dte"; nvidia,function = "rsvd1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; gpio_gmi { nvidia,pins = "ata", "atc", "atd", "ate", "dap1", "dap2", "dap4", "gpu", "irrx", "irtx", "spia", "spib", "spic"; nvidia,function = "gmi"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; gpio_pta { nvidia,pins = "pta"; nvidia,function = "rsvd4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; gpio_uac { nvidia,pins = "uac"; nvidia,function = "rsvd2"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; hdint { nvidia,pins = "hdint"; nvidia,function = "hdmi"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; i2c1 { nvidia,pins = "rm"; nvidia,function = "i2c1"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; i2c3 { nvidia,pins = "dtf"; nvidia,function = "i2c3"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; i2cddc { nvidia,pins = "ddc"; nvidia,function = "i2c2"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; i2cp { nvidia,pins = "i2cp"; nvidia,function = "i2cp"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; irda { nvidia,pins = "uad"; nvidia,function = "irda"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; nand { nvidia,pins = "kbca", "kbcc", "kbcd", "kbce", "kbcf"; nvidia,function = "nand"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; owc { nvidia,pins = "owc"; nvidia,function = "owr"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; pmc { nvidia,pins = "pmc"; nvidia,function = "pwr_on"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; pwm { nvidia,pins = "sdb", "sdc", "sdd"; nvidia,function = "pwm"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; sdio4 { nvidia,pins = "atb", "gma", "gme"; nvidia,function = "sdio4"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; spi1 { nvidia,pins = "spid", "spie", "spif"; nvidia,function = "spi1"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; spi4 { nvidia,pins = "slxa", "slxc", "slxd", "slxk"; nvidia,function = "spi4"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; uarta { nvidia,pins = "sdio1"; nvidia,function = "uarta"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; uartd { nvidia,pins = "gmc"; nvidia,function = "uartd"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; ulpi { nvidia,pins = "uaa", "uab", "uda"; nvidia,function = "ulpi"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; ulpi_refclk { nvidia,pins = "cdev2"; nvidia,function = "pllp_out4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; usb_gpio { nvidia,pins = "spig", "spih"; nvidia,function = "spi2_alt"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; vi { nvidia,pins = "dta", "dtb", "dtc", "dtd"; nvidia,function = "vi"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; vi_sc { nvidia,pins = "csus"; nvidia,function = "vi_sensor_clk"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; }; }; + ac97: ac97@70002000 { + status = "okay"; + nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0) + GPIO_ACTIVE_HIGH>; + nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0) + GPIO_ACTIVE_HIGH>; + }; + i2c@7000c000 { clock-frequency = <400000>; }; @@ -225,15 +238,15 @@ #gpio-cells = <2>; gpio-controller; - sys-supply = <&vdd_5v0_reg>; + sys-supply = <&vdd_3v3_reg>; vin-sm0-supply = <&sys_reg>; vin-sm1-supply = <&sys_reg>; vin-sm2-supply = <&sys_reg>; vinldo01-supply = <&sm2_reg>; - vinldo23-supply = <&sm2_reg>; - vinldo4-supply = <&sm2_reg>; - vinldo678-supply = <&sm2_reg>; - vinldo9-supply = <&sm2_reg>; + vinldo23-supply = <&vdd_3v3_reg>; + vinldo4-supply = <&vdd_3v3_reg>; + vinldo678-supply = <&vdd_3v3_reg>; + vinldo9-supply = <&vdd_3v3_reg>; regulators { #address-cells = <1>; @@ -250,8 +263,8 @@ reg = <1>; regulator-compatible = "sm0"; regulator-name = "vdd_sm0,vdd_core"; - regulator-min-microvolt = <1275000>; - regulator-max-microvolt = <1275000>; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; regulator-always-on; }; @@ -259,8 +272,8 @@ reg = <2>; regulator-compatible = "sm1"; regulator-name = "vdd_sm1,vdd_cpu"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; regulator-always-on; }; @@ -268,8 +281,8 @@ reg = <3>; regulator-compatible = "sm2"; regulator-name = "vdd_sm2,vin_ldo*"; - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-always-on; }; @@ -316,8 +329,8 @@ reg = <10>; regulator-compatible = "ldo6"; regulator-name = "vdd_ldo6,avdd_vdac,vddio_vi,vddio_cam"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; }; hdmi_vdd_reg: regulator@11 { @@ -362,7 +375,7 @@ }; }; - pmc { + pmc@7000e400 { nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <5000>; nvidia,cpu-pwr-off-time = <5000>; @@ -442,14 +455,6 @@ }; }; - ac97: ac97 { - status = "okay"; - nvidia,codec-reset-gpio = <&gpio TEGRA_GPIO(V, 0) - GPIO_ACTIVE_HIGH>; - nvidia,codec-sync-gpio = <&gpio TEGRA_GPIO(P, 0) - GPIO_ACTIVE_HIGH>; - }; - usb@c5004000 { status = "okay"; nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1) @@ -471,7 +476,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -479,6 +484,33 @@ }; }; + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_3v3_reg: regulator@100 { + compatible = "regulator-fixed"; + reg = <100>; + regulator-name = "vdd_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + regulator@101 { + compatible = "regulator-fixed"; + reg = <101>; + regulator-name = "internal_usb"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-boot-on; + regulator-always-on; + gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>; + }; + }; + sound { compatible = "nvidia,tegra-audio-wm9712-colibri_t20", "nvidia,tegra-audio-wm9712"; @@ -498,31 +530,4 @@ <&tegra_car TEGRA20_CLK_CDEV1>; clock-names = "pll_a", "pll_a_out0", "mclk"; }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - vdd_5v0_reg: regulator@100 { - compatible = "regulator-fixed"; - reg = <100>; - regulator-name = "vdd_5v0"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - }; - - regulator@101 { - compatible = "regulator-fixed"; - reg = <101>; - regulator-name = "internal_usb"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-boot-on; - regulator-always-on; - gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>; - }; - }; }; diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts index e156ab30e763..3fb1f50f6d46 100644 --- a/arch/arm/boot/dts/tegra20-harmony.dts +++ b/arch/arm/boot/dts/tegra20-harmony.dts @@ -1,17 +1,31 @@ /dts-v1/; +#include #include "tegra20.dtsi" / { model = "NVIDIA Tegra20 Harmony evaluation board"; compatible = "nvidia,harmony", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x40000000>; }; - host1x { - hdmi { + host1x@50000000 { + dc@54200000 { + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + }; + }; + + hdmi@54280000 { status = "okay"; vdd-supply = <&hdmi_vdd_reg>; @@ -23,7 +37,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -184,50 +198,50 @@ "gmb", "gmc", "gmd", "gme", "gpu7", "gpv", "i2cp", "pta", "rm", "slxa", "slxk", "spia", "spib", "uac"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_csus { nvidia,pins = "csus", "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_crtp { nvidia,pins = "crtp", "dap2", "dap3", "dap4", "dtc", "dte", "dtf", "gpu", "sdio1", "slxc", "slxd", "spdi", "spdo", "spig", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ddc { nvidia,pins = "ddc", "dta", "dtd", "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", "sdc"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_hdint { nvidia,pins = "hdint", "lcsn", "ldc", "lm1", "lpw1", "lsc1", "lsck", "lsda", "lsdi", "lvp0", "owc", "sdb"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; conf_irrx { nvidia,pins = "irrx", "irtx", "sdd", "spic", "spie", "spih", "uaa", "uab", "uad", "uca", "ucb"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_lc { nvidia,pins = "lc", "ls"; - nvidia,pull = <2>; + nvidia,pull = ; }; conf_ld0 { nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4", @@ -237,12 +251,12 @@ "lhp1", "lhp2", "lhs", "lm0", "lpp", "lpw0", "lpw2", "lsc0", "lspi", "lvp1", "lvs", "pmc"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; }; }; @@ -255,6 +269,10 @@ status = "okay"; }; + pwm: pwm@7000a000 { + status = "okay"; + }; + i2c@7000c000 { status = "okay"; clock-frequency = <400000>; @@ -415,7 +433,124 @@ }; }; - pmc { + kbc@7000e200 { + status = "okay"; + nvidia,debounce-delay-ms = <2>; + nvidia,repeat-delay-ms = <160>; + nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; + nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>; + linux,keymap = ; + }; + + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <5000>; @@ -425,7 +560,7 @@ nvidia,sys-clock-req-active-high; }; - pcie-controller { + pcie-controller@80003000 { pex-clk-supply = <&pci_clk_reg>; vdd-supply = <&pci_vdd_reg>; status = "okay"; @@ -483,12 +618,23 @@ bus-width = <8>; }; + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(B, 5) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_bl_reg>; + pwms = <&pwm 0 5000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + clocks { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -502,126 +648,18 @@ power { label = "Power"; gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; - linux,code = <116>; /* KEY_POWER */ + linux,code = ; gpio-key,wakeup; }; }; - kbc { - status = "okay"; - nvidia,debounce-delay-ms = <2>; - nvidia,repeat-delay-ms = <160>; - nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; - nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>; - linux,keymap = <0x00020011 /* KEY_W */ - 0x0003001F /* KEY_S */ - 0x0004001E /* KEY_A */ - 0x0005002C /* KEY_Z */ - 0x000701D0 /* KEY_FN */ - 0x0107008B /* KEY_MENU */ - 0x02060038 /* KEY_LEFTALT */ - 0x02070064 /* KEY_RIGHTALT */ - 0x03000006 /* KEY_5 */ - 0x03010005 /* KEY_4 */ - 0x03020013 /* KEY_R */ - 0x03030012 /* KEY_E */ - 0x03040021 /* KEY_F */ - 0x03050020 /* KEY_D */ - 0x0306002D /* KEY_X */ - 0x04000008 /* KEY_7 */ - 0x04010007 /* KEY_6 */ - 0x04020014 /* KEY_T */ - 0x04030023 /* KEY_H */ - 0x04040022 /* KEY_G */ - 0x0405002F /* KEY_V */ - 0x0406002E /* KEY_C */ - 0x04070039 /* KEY_SPACE */ - 0x0500000A /* KEY_9 */ - 0x05010009 /* KEY_8 */ - 0x05020016 /* KEY_U */ - 0x05030015 /* KEY_Y */ - 0x05040024 /* KEY_J */ - 0x05050031 /* KEY_N */ - 0x05060030 /* KEY_B */ - 0x0507002B /* KEY_BACKSLASH */ - 0x0600000C /* KEY_MINUS */ - 0x0601000B /* KEY_0 */ - 0x06020018 /* KEY_O */ - 0x06030017 /* KEY_I */ - 0x06040026 /* KEY_L */ - 0x06050025 /* KEY_K */ - 0x06060033 /* KEY_COMMA */ - 0x06070032 /* KEY_M */ - 0x0701000D /* KEY_EQUAL */ - 0x0702001B /* KEY_RIGHTBRACE */ - 0x0703001C /* KEY_ENTER */ - 0x0707008B /* KEY_MENU */ - 0x0804002A /* KEY_LEFTSHIFT */ - 0x08050036 /* KEY_RIGHTSHIFT */ - 0x0905001D /* KEY_LEFTCTRL */ - 0x09070061 /* KEY_RIGHTCTRL */ - 0x0B00001A /* KEY_LEFTBRACE */ - 0x0B010019 /* KEY_P */ - 0x0B020028 /* KEY_APOSTROPHE */ - 0x0B030027 /* KEY_SEMICOLON */ - 0x0B040035 /* KEY_SLASH */ - 0x0B050034 /* KEY_DOT */ - 0x0C000044 /* KEY_F10 */ - 0x0C010043 /* KEY_F9 */ - 0x0C02000E /* KEY_BACKSPACE */ - 0x0C030004 /* KEY_3 */ - 0x0C040003 /* KEY_2 */ - 0x0C050067 /* KEY_UP */ - 0x0C0600D2 /* KEY_PRINT */ - 0x0C070077 /* KEY_PAUSE */ - 0x0D00006E /* KEY_INSERT */ - 0x0D01006F /* KEY_DELETE */ - 0x0D030068 /* KEY_PAGEUP */ - 0x0D04006D /* KEY_PAGEDOWN */ - 0x0D05006A /* KEY_RIGHT */ - 0x0D06006C /* KEY_DOWN */ - 0x0D070069 /* KEY_LEFT */ - 0x0E000057 /* KEY_F11 */ - 0x0E010058 /* KEY_F12 */ - 0x0E020042 /* KEY_F8 */ - 0x0E030010 /* KEY_Q */ - 0x0E04003E /* KEY_F4 */ - 0x0E05003D /* KEY_F3 */ - 0x0E060002 /* KEY_1 */ - 0x0E070041 /* KEY_F7 */ - 0x0F000001 /* KEY_ESC */ - 0x0F010029 /* KEY_GRAVE */ - 0x0F02003F /* KEY_F5 */ - 0x0F03000F /* KEY_TAB */ - 0x0F04003B /* KEY_F1 */ - 0x0F05003C /* KEY_F2 */ - 0x0F06003A /* KEY_CAPSLOCK */ - 0x0F070040 /* KEY_F6 */ - 0x14000047 /* KEY_KP7 */ - 0x15000049 /* KEY_KP9 */ - 0x15010048 /* KEY_KP8 */ - 0x1502004B /* KEY_KP4 */ - 0x1504004F /* KEY_KP1 */ - 0x1601004E /* KEY_KPSLASH */ - 0x1602004D /* KEY_KP6 */ - 0x1603004C /* KEY_KP5 */ - 0x16040051 /* KEY_KP3 */ - 0x16050050 /* KEY_KP2 */ - 0x16070052 /* KEY_KP0 */ - 0x1B010037 /* KEY_KPASTERISK */ - 0x1B03004A /* KEY_KPMINUS */ - 0x1B04004E /* KEY_KPPLUS */ - 0x1B050053 /* KEY_KPDOT */ - 0x1C050073 /* KEY_VOLUMEUP */ - 0x1D030066 /* KEY_HOME */ - 0x1D04006B /* KEY_END */ - 0x1D0500E1 /* KEY_BRIGHTNESSUP */ - 0x1D060072 /* KEY_VOLUMEDOWN */ - 0x1D0700E0 /* KEY_BRIGHTNESSDOWN */ - 0x1E000045 /* KEY_NUMLOCK */ - 0x1E010046 /* KEY_SCROLLLOCK */ - 0x1E020071 /* KEY_MUTE */ - 0x1F0400D6>; /* KEY_QUESTION */ + panel: panel { + compatible = "auo,b101aw03", "simple-panel"; + + power-supply = <&vdd_pnl_reg>; + enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; }; regulators { @@ -667,7 +705,7 @@ enable-active-high; }; - regulator@4 { + vdd_pnl_reg: regulator@4 { compatible = "regulator-fixed"; reg = <4>; regulator-name = "vdd_pnl"; @@ -677,7 +715,7 @@ enable-active-high; }; - regulator@5 { + vdd_bl_reg: regulator@5 { compatible = "regulator-fixed"; reg = <5>; regulator-name = "vdd_bl"; diff --git a/arch/arm/boot/dts/tegra20-iris-512.dts b/arch/arm/boot/dts/tegra20-iris-512.dts index f2222bd74eab..8cfb83f42e1f 100644 --- a/arch/arm/boot/dts/tegra20-iris-512.dts +++ b/arch/arm/boot/dts/tegra20-iris-512.dts @@ -6,36 +6,48 @@ model = "Toradex Colibri T20 512MB on Iris"; compatible = "toradex,iris", "toradex,colibri_t20-512", "nvidia,tegra20"; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; }; }; - pinmux { + pinmux@70000014 { state_default: pinmux { hdint { - nvidia,tristate = <0>; + nvidia,tristate = ; }; i2cddc { - nvidia,tristate = <0>; + nvidia,tristate = ; }; sdio4 { - nvidia,tristate = <0>; + nvidia,tristate = ; }; uarta { - nvidia,tristate = <0>; + nvidia,tristate = ; }; uartd { - nvidia,tristate = <0>; + nvidia,tristate = ; }; }; }; + serial@70006000 { + status = "okay"; + }; + + serial@70006300 { + status = "okay"; + }; + + i2c_ddc: i2c@7000c400 { + status = "okay"; + }; + usb@c5000000 { status = "okay"; }; @@ -52,18 +64,6 @@ status = "okay"; }; - serial@70006000 { - status = "okay"; - }; - - serial@70006300 { - status = "okay"; - }; - - i2c_ddc: i2c@7000c400 { - status = "okay"; - }; - sdhci@c8000600 { status = "okay"; bus-width = <4>; diff --git a/arch/arm/boot/dts/tegra20-medcom-wide.dts b/arch/arm/boot/dts/tegra20-medcom-wide.dts index 7580578903cf..6d3a4cbc36cc 100644 --- a/arch/arm/boot/dts/tegra20-medcom-wide.dts +++ b/arch/arm/boot/dts/tegra20-medcom-wide.dts @@ -6,7 +6,7 @@ model = "Avionic Design Medcom-Wide board"; compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20"; - pwm { + pwm@7000a000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index 8d71fc9d8a2f..c7cd8e6802d7 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts @@ -1,17 +1,23 @@ /dts-v1/; +#include #include "tegra20.dtsi" / { model = "Toshiba AC100 / Dynabook AZ"; compatible = "compal,paz00", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x20000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; vdd-supply = <&hdmi_vdd_reg>; @@ -23,7 +29,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -177,39 +183,39 @@ "gpu", "gpu7", "gpv", "i2cp", "pta", "rm", "sdio1", "slxk", "spdo", "uac", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_crtp { nvidia,pins = "crtp", "dap3", "dap4", "dtb", "dtc", "dte", "slxa", "slxc", "slxd", "spdi"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_csus { nvidia,pins = "csus", "spia", "spib", "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ddc { nvidia,pins = "ddc", "irrx", "irtx", "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", "spic", "spig", "uaa", "uab"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_dta { nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd", "spie", "spih", "uad", "uca", "ucb"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_hdint { nvidia,pins = "hdint", "ld0", "ld1", "ld2", @@ -218,23 +224,23 @@ "ld13", "ld14", "ld15", "ld16", "ld17", "ldc", "ldi", "lhs", "lsc0", "lspi", "lvs", "pmc"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; conf_lc { nvidia,pins = "lc", "ls"; - nvidia,pull = <2>; + nvidia,pull = ; }; conf_lcsn { nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2", "lm0", "lm1", "lpp", "lpw0", "lpw1", "lpw2", "lsc1", "lsck", "lsda", "lsdi", "lvp0", "lvp1", "sdb"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; }; }; @@ -268,7 +274,7 @@ clock-frequency = <100000>; }; - nvec { + nvec@7000c500 { compatible = "nvidia,nvec"; reg = <0x7000c500 0x100>; interrupts = ; @@ -280,6 +286,8 @@ clocks = <&tegra_car TEGRA20_CLK_I2C3>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; }; i2c@7000d000 { @@ -415,7 +423,7 @@ }; }; - pmc { + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <2000>; @@ -472,7 +480,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -486,7 +494,7 @@ power { label = "Power"; gpios = <&gpio TEGRA_GPIO(J, 7) GPIO_ACTIVE_LOW>; - linux,code = <116>; /* KEY_POWER */ + linux,code = ; gpio-key,wakeup; }; }; diff --git a/arch/arm/boot/dts/tegra20-plutux.dts b/arch/arm/boot/dts/tegra20-plutux.dts index d7a358a6a647..29051a2ae0ae 100644 --- a/arch/arm/boot/dts/tegra20-plutux.dts +++ b/arch/arm/boot/dts/tegra20-plutux.dts @@ -6,8 +6,8 @@ model = "Avionic Design Plutux board"; compatible = "ad,plutux", "ad,tamonten", "nvidia,tegra20"; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index 315aae26c3cd..a11b6e7b4759 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts @@ -1,17 +1,23 @@ /dts-v1/; +#include #include "tegra20.dtsi" / { model = "NVIDIA Seaboard"; compatible = "nvidia,seaboard", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x40000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; vdd-supply = <&hdmi_vdd_reg>; @@ -23,7 +29,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -189,53 +195,53 @@ "irtx", "pta", "rm", "sdc", "sdd", "slxd", "slxk", "spdi", "spdo", "uac", "uad", "uca", "ucb", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ate { nvidia,pins = "ate", "csus", "dap3", "gpv", "owc", "slxc", "spib", "spid", "spie"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_crtp { nvidia,pins = "crtp", "gmb", "slxa", "spia", "spig", "spih"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_dta { nvidia,pins = "dta", "dtb", "dtc", "dtd"; - nvidia,pull = <1>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_dte { nvidia,pins = "dte", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_hdint { nvidia,pins = "hdint", "lcsn", "ldc", "lm1", "lpw1", "lsc1", "lsck", "lsda", "lsdi", "lvp0"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; conf_kbca { nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", "sdio1", "spic", "uaa", "uab"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_lc { nvidia,pins = "lc", "ls"; - nvidia,pull = <2>; + nvidia,pull = ; }; conf_ld0 { nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4", @@ -245,22 +251,22 @@ "lhp1", "lhp2", "lhs", "lm0", "lpp", "lpw0", "lpw2", "lsc0", "lspi", "lvp1", "lvs", "pmc", "sdb"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; drive_sdio1 { nvidia,pins = "drive_sdio1"; - nvidia,high-speed-mode = <0>; - nvidia,schmitt = <0>; - nvidia,low-power-mode = <3>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; nvidia,pull-down-strength = <31>; nvidia,pull-up-strength = <31>; - nvidia,slew-rate-rising = <3>; - nvidia,slew-rate-falling = <3>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; }; }; @@ -386,6 +392,13 @@ status = "okay"; clock-frequency = <400000>; + magnetometer@c { + compatible = "ak,ak8975"; + reg = <0xc>; + interrupt-parent = <&gpio>; + interrupts = ; + }; + pmic: tps6586x@34 { compatible = "ti,tps6586x"; reg = <0x34>; @@ -507,16 +520,149 @@ compatible = "onnn,nct1008"; reg = <0x4c>; }; - - magnetometer@c { - compatible = "ak,ak8975"; - reg = <0xc>; - interrupt-parent = <&gpio>; - interrupts = ; - }; }; - pmc { + kbc@7000e200 { + status = "okay"; + nvidia,debounce-delay-ms = <32>; + nvidia,repeat-delay-ms = <160>; + nvidia,ghost-filter; + nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; + nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>; + linux,keymap = ; + }; + + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <5000>; @@ -621,7 +767,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -635,7 +781,7 @@ power { label = "Power"; gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; - linux,code = <116>; /* KEY_POWER */ + linux,code = ; gpio-key,wakeup; }; @@ -649,145 +795,6 @@ }; }; - kbc { - status = "okay"; - nvidia,debounce-delay-ms = <32>; - nvidia,repeat-delay-ms = <160>; - nvidia,ghost-filter; - nvidia,kbc-row-pins = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>; - nvidia,kbc-col-pins = <16 17 18 19 20 21 22 23>; - linux,keymap = <0x00020011 /* KEY_W */ - 0x0003001F /* KEY_S */ - 0x0004001E /* KEY_A */ - 0x0005002C /* KEY_Z */ - 0x000701d0 /* KEY_FN */ - - 0x0107007D /* KEY_LEFTMETA */ - 0x02060064 /* KEY_RIGHTALT */ - 0x02070038 /* KEY_LEFTALT */ - - 0x03000006 /* KEY_5 */ - 0x03010005 /* KEY_4 */ - 0x03020013 /* KEY_R */ - 0x03030012 /* KEY_E */ - 0x03040021 /* KEY_F */ - 0x03050020 /* KEY_D */ - 0x0306002D /* KEY_X */ - - 0x04000008 /* KEY_7 */ - 0x04010007 /* KEY_6 */ - 0x04020014 /* KEY_T */ - 0x04030023 /* KEY_H */ - 0x04040022 /* KEY_G */ - 0x0405002F /* KEY_V */ - 0x0406002E /* KEY_C */ - 0x04070039 /* KEY_SPACE */ - - 0x0500000A /* KEY_9 */ - 0x05010009 /* KEY_8 */ - 0x05020016 /* KEY_U */ - 0x05030015 /* KEY_Y */ - 0x05040024 /* KEY_J */ - 0x05050031 /* KEY_N */ - 0x05060030 /* KEY_B */ - 0x0507002B /* KEY_BACKSLASH */ - - 0x0600000C /* KEY_MINUS */ - 0x0601000B /* KEY_0 */ - 0x06020018 /* KEY_O */ - 0x06030017 /* KEY_I */ - 0x06040026 /* KEY_L */ - 0x06050025 /* KEY_K */ - 0x06060033 /* KEY_COMMA */ - 0x06070032 /* KEY_M */ - - 0x0701000D /* KEY_EQUAL */ - 0x0702001B /* KEY_RIGHTBRACE */ - 0x0703001C /* KEY_ENTER */ - 0x0707008B /* KEY_MENU */ - - 0x08040036 /* KEY_RIGHTSHIFT */ - 0x0805002A /* KEY_LEFTSHIFT */ - - 0x09050061 /* KEY_RIGHTCTRL */ - 0x0907001D /* KEY_LEFTCTRL */ - - 0x0B00001A /* KEY_LEFTBRACE */ - 0x0B010019 /* KEY_P */ - 0x0B020028 /* KEY_APOSTROPHE */ - 0x0B030027 /* KEY_SEMICOLON */ - 0x0B040035 /* KEY_SLASH */ - 0x0B050034 /* KEY_DOT */ - - 0x0C000044 /* KEY_F10 */ - 0x0C010043 /* KEY_F9 */ - 0x0C02000E /* KEY_BACKSPACE */ - 0x0C030004 /* KEY_3 */ - 0x0C040003 /* KEY_2 */ - 0x0C050067 /* KEY_UP */ - 0x0C0600D2 /* KEY_PRINT */ - 0x0C070077 /* KEY_PAUSE */ - - 0x0D00006E /* KEY_INSERT */ - 0x0D01006F /* KEY_DELETE */ - 0x0D030068 /* KEY_PAGEUP */ - 0x0D04006D /* KEY_PAGEDOWN */ - 0x0D05006A /* KEY_RIGHT */ - 0x0D06006C /* KEY_DOWN */ - 0x0D070069 /* KEY_LEFT */ - - 0x0E000057 /* KEY_F11 */ - 0x0E010058 /* KEY_F12 */ - 0x0E020042 /* KEY_F8 */ - 0x0E030010 /* KEY_Q */ - 0x0E04003E /* KEY_F4 */ - 0x0E05003D /* KEY_F3 */ - 0x0E060002 /* KEY_1 */ - 0x0E070041 /* KEY_F7 */ - - 0x0F000001 /* KEY_ESC */ - 0x0F010029 /* KEY_GRAVE */ - 0x0F02003F /* KEY_F5 */ - 0x0F03000F /* KEY_TAB */ - 0x0F04003B /* KEY_F1 */ - 0x0F05003C /* KEY_F2 */ - 0x0F06003A /* KEY_CAPSLOCK */ - 0x0F070040 /* KEY_F6 */ - - /* Software Handled Function Keys */ - 0x14000047 /* KEY_KP7 */ - - 0x15000049 /* KEY_KP9 */ - 0x15010048 /* KEY_KP8 */ - 0x1502004B /* KEY_KP4 */ - 0x1504004F /* KEY_KP1 */ - - 0x1601004E /* KEY_KPSLASH */ - 0x1602004D /* KEY_KP6 */ - 0x1603004C /* KEY_KP5 */ - 0x16040051 /* KEY_KP3 */ - 0x16050050 /* KEY_KP2 */ - 0x16070052 /* KEY_KP0 */ - - 0x1B010037 /* KEY_KPASTERISK */ - 0x1B03004A /* KEY_KPMINUS */ - 0x1B04004E /* KEY_KPPLUS */ - 0x1B050053 /* KEY_KPDOT */ - - 0x1C050073 /* KEY_VOLUMEUP */ - - 0x1D030066 /* KEY_HOME */ - 0x1D04006B /* KEY_END */ - 0x1D0500E0 /* KEY_BRIGHTNESSDOWN */ - 0x1D060072 /* KEY_VOLUMEDOWN */ - 0x1D0700E1 /* KEY_BRIGHTNESSUP */ - - 0x1E000045 /* KEY_NUMLOCK */ - 0x1E010046 /* KEY_SCROLLLOCK */ - 0x1E020071 /* KEY_MUTE */ - - 0x1F04008A>; /* KEY_HELP */ - }; regulators { compatible = "simple-bus"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi index 7726dab3d08d..a1b0d965757f 100644 --- a/arch/arm/boot/dts/tegra20-tamonten.dtsi +++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi @@ -4,12 +4,17 @@ model = "Avionic Design Tamonten SOM"; compatible = "ad,tamonten", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x20000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { vdd-supply = <&hdmi_vdd_reg>; pll-supply = <&hdmi_pll_reg>; @@ -19,7 +24,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -176,50 +181,50 @@ "gmb", "gmc", "gmd", "gme", "gpu7", "gpv", "i2cp", "pta", "rm", "slxa", "slxk", "spia", "spib", "uac"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_csus { nvidia,pins = "csus", "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_crtp { nvidia,pins = "crtp", "dap2", "dap3", "dap4", "dtc", "dte", "dtf", "gpu", "sdio1", "slxc", "slxd", "spdi", "spdo", "spig", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ddc { nvidia,pins = "ddc", "dta", "dtd", "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", "sdc"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_hdint { nvidia,pins = "hdint", "lcsn", "ldc", "lm1", "lpw1", "lsc1", "lsck", "lsda", "lsdi", "lvp0", "owc", "sdb"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; conf_irrx { nvidia,pins = "irrx", "irtx", "sdd", "spic", "spie", "spih", "uaa", "uab", "uad", "uca", "ucb"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_lc { nvidia,pins = "lc", "ls"; - nvidia,pull = <2>; + nvidia,pull = ; }; conf_ld0 { nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4", @@ -229,12 +234,12 @@ "lhp1", "lhp2", "lhs", "lm0", "lpp", "lpw0", "lpw2", "lsc0", "lspi", "lvp1", "lvs", "pmc"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; }; @@ -457,7 +462,7 @@ }; }; - pmc { + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <5000>; @@ -467,7 +472,7 @@ nvidia,sys-clock-req-active-high; }; - pcie-controller { + pcie-controller@80003000 { pex-clk-supply = <&pci_clk_reg>; vdd-supply = <&pci_vdd_reg>; }; @@ -492,7 +497,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; diff --git a/arch/arm/boot/dts/tegra20-tec.dts b/arch/arm/boot/dts/tegra20-tec.dts index 3ada3cb67f07..890562c667fb 100644 --- a/arch/arm/boot/dts/tegra20-tec.dts +++ b/arch/arm/boot/dts/tegra20-tec.dts @@ -6,8 +6,8 @@ model = "Avionic Design Tamonten Evaluation Carrier"; compatible = "ad,tec", "ad,tamonten", "nvidia,tegra20"; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; }; }; @@ -32,7 +32,7 @@ }; }; - pcie-controller { + pcie-controller@80003000 { status = "okay"; pci@1,0 { diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts index 78deea5c0d21..216fa6d50c65 100644 --- a/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/arch/arm/boot/dts/tegra20-trimslice.dts @@ -1,17 +1,23 @@ /dts-v1/; +#include #include "tegra20.dtsi" / { model = "Compulab TrimSlice board"; compatible = "compulab,trimslice", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000c500/rtc@56"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x40000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; vdd-supply = <&hdmi_vdd_reg>; @@ -23,7 +29,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -191,49 +197,49 @@ "dtb", "dtc", "dtd", "dte", "gmb", "gme", "i2cp", "pta", "slxc", "slxd", "spdi", "spdo", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_atb { nvidia,pins = "atb", "cdev1", "cdev2", "dap1", "gma", "gmc", "gmd", "gpu", "gpu7", "gpv", "sdio1", "slxa", "slxk", "uac"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_csus { nvidia,pins = "csus", "spia", "spib", "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ddc { nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_hdint { nvidia,pins = "hdint", "lcsn", "ldc", "lm1", "lpw1", "lsc1", "lsck", "lsda", "lsdi", "lvp0", "pmc"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; conf_irrx { nvidia,pins = "irrx", "irtx", "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", "owc", "spic", "spie", "spig", "spih", "uaa", "uab", "uad", "uca", "ucb"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_lc { nvidia,pins = "lc", "ls"; - nvidia,pull = <2>; + nvidia,pull = ; }; conf_ld0 { nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4", @@ -243,17 +249,17 @@ "lhp1", "lhp2", "lhs", "lm0", "lpp", "lpw0", "lpw2", "lsc0", "lspi", "lvp1", "lvs", "sdb"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; conf_spif { nvidia,pins = "spif"; - nvidia,pull = <1>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; }; }; @@ -301,7 +307,7 @@ }; }; - pmc { + pmc@7000e400 { nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <5000>; nvidia,cpu-pwr-off-time = <5000>; @@ -310,7 +316,7 @@ nvidia,sys-clock-req-active-high; }; - pcie-controller { + pcie-controller@80003000 { status = "okay"; pex-clk-supply = <&pci_clk_reg>; vdd-supply = <&pci_vdd_reg>; @@ -366,7 +372,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -380,7 +386,7 @@ power { label = "Power"; gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>; - linux,code = <116>; /* KEY_POWER */ + linux,code = ; gpio-key,wakeup; }; }; diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts index aab872cd0530..571d12e6ac2d 100644 --- a/arch/arm/boot/dts/tegra20-ventana.dts +++ b/arch/arm/boot/dts/tegra20-ventana.dts @@ -1,17 +1,23 @@ /dts-v1/; +#include #include "tegra20.dtsi" / { model = "NVIDIA Tegra20 Ventana evaluation board"; compatible = "nvidia,ventana", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x40000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; vdd-supply = <&hdmi_vdd_reg>; @@ -23,7 +29,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -189,50 +195,50 @@ "irtx", "pta", "rm", "sdc", "sdd", "slxc", "slxd", "slxk", "spdi", "spdo", "uac", "uad", "uca", "ucb", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ate { nvidia,pins = "ate", "csus", "dap3", "gmd", "gpv", "owc", "spia", "spib", "spic", "spid", "spie", "spig"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_crtp { nvidia,pins = "crtp", "gmb", "slxa", "spih"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_dta { nvidia,pins = "dta", "dtb", "dtc", "dtd"; - nvidia,pull = <1>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_dte { nvidia,pins = "dte", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_hdint { nvidia,pins = "hdint", "lcsn", "ldc", "lm1", "lpw1", "lsck", "lsda", "lsdi", "lvp0"; - nvidia,tristate = <1>; + nvidia,tristate = ; }; conf_kbca { nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", "sdio1", "uaa", "uab"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_lc { nvidia,pins = "lc", "ls"; - nvidia,pull = <2>; + nvidia,pull = ; }; conf_ld0 { nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4", @@ -242,22 +248,22 @@ "lhp1", "lhp2", "lhs", "lm0", "lpp", "lpw0", "lpw2", "lsc0", "lsc1", "lspi", "lvp1", "lvs", "pmc", "sdb"; - nvidia,tristate = <0>; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; drive_sdio1 { nvidia,pins = "drive_sdio1"; - nvidia,high-speed-mode = <0>; - nvidia,schmitt = <1>; - nvidia,low-power-mode = <3>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; nvidia,pull-down-strength = <31>; nvidia,pull-up-strength = <31>; - nvidia,slew-rate-rising = <3>; - nvidia,slew-rate-falling = <3>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; }; }; @@ -492,7 +498,7 @@ }; }; - pmc { + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <2000>; @@ -556,7 +562,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -570,7 +576,7 @@ power { label = "Power"; gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; - linux,code = <116>; /* KEY_POWER */ + linux,code = ; gpio-key,wakeup; }; }; diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts index d33a73cf167c..1843725785c9 100644 --- a/arch/arm/boot/dts/tegra20-whistler.dts +++ b/arch/arm/boot/dts/tegra20-whistler.dts @@ -1,17 +1,23 @@ /dts-v1/; +#include #include "tegra20.dtsi" / { model = "NVIDIA Tegra20 Whistler evaluation board"; compatible = "nvidia,whistler", "nvidia,tegra20"; + aliases { + rtc0 = "/i2c@7000d000/max8907@3c"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x00000000 0x20000000>; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; vdd-supply = <&hdmi_vdd_reg>; @@ -23,7 +29,7 @@ }; }; - pinmux { + pinmux@70000014 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -189,8 +195,8 @@ "kbcf", "sdc", "sdd", "spie", "spig", "spih", "uaa", "uab", "uad", "uca", "ucb"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_atd { nvidia,pins = "atd", "ate", "cdev1", "csus", @@ -198,54 +204,54 @@ "dtf", "gpu", "gpu7", "gpv", "i2cp", "rm", "sdio1", "slxa", "slxc", "slxd", "slxk", "spdi", "spdo", "uac", "uda"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_cdev2 { nvidia,pins = "cdev2", "spia", "spib"; - nvidia,pull = <1>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ck32 { nvidia,pins = "ck32", "ddrc", "lc", "pmca", "pmcb", "pmcc", "pmcd", "xm2c", "xm2d"; - nvidia,pull = <0>; + nvidia,pull = ; }; conf_crtp { nvidia,pins = "crtp"; - nvidia,pull = <0>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_dta { nvidia,pins = "dta", "dtb", "dtc", "dtd", "spid", "spif"; - nvidia,pull = <1>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_gme { nvidia,pins = "gme", "owc", "pta", "spic"; - nvidia,pull = <2>; - nvidia,tristate = <1>; + nvidia,pull = ; + nvidia,tristate = ; }; conf_ld17_0 { nvidia,pins = "ld17_0", "ld19_18", "ld21_20", "ld23_22"; - nvidia,pull = <1>; + nvidia,pull = ; }; conf_ls { nvidia,pins = "ls", "pmce"; - nvidia,pull = <2>; + nvidia,pull = ; }; drive_dap1 { nvidia,pins = "drive_dap1"; - nvidia,high-speed-mode = <0>; - nvidia,schmitt = <1>; - nvidia,low-power-mode = <0>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; nvidia,pull-down-strength = <0>; nvidia,pull-up-strength = <0>; - nvidia,slew-rate-rising = <0>; - nvidia,slew-rate-falling = <0>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; }; }; }; @@ -495,7 +501,20 @@ }; }; - pmc { + kbc@7000e200 { + status = "okay"; + nvidia,debounce-delay-ms = <20>; + nvidia,repeat-delay-ms = <160>; + nvidia,kbc-row-pins = <0 1 2>; + nvidia,kbc-col-pins = <16 17>; + nvidia,wakeup-source; + linux,keymap = ; + }; + + pmc@7000e400 { nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <2000>; @@ -543,7 +562,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -551,25 +570,12 @@ }; }; - kbc { - status = "okay"; - nvidia,debounce-delay-ms = <20>; - nvidia,repeat-delay-ms = <160>; - nvidia,kbc-row-pins = <0 1 2>; - nvidia,kbc-col-pins = <16 17>; - nvidia,wakeup-source; - linux,keymap = <0x00000074 /* KEY_POWER */ - 0x01000066 /* KEY_HOME */ - 0x0101009E /* KEY_BACK */ - 0x0201008B>; /* KEY_MENU */ - }; - regulators { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; - usb0_vbus_reg: regulator { + usb0_vbus_reg: regulator@0 { compatible = "regulator-fixed"; reg = <0>; regulator-name = "usb0_vbus"; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index df40b54fd8bc..480ecda3416b 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -1,5 +1,6 @@ #include #include +#include #include #include "skeleton.dtsi" @@ -16,57 +17,71 @@ serial4 = &uarte; }; - host1x { + host1x@50000000 { compatible = "nvidia,tegra20-host1x", "simple-bus"; reg = <0x50000000 0x00024000>; interrupts = , /* syncpt */ ; /* general */ clocks = <&tegra_car TEGRA20_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; #address-cells = <1>; #size-cells = <1>; ranges = <0x54000000 0x54000000 0x04000000>; - mpe { + mpe@54040000 { compatible = "nvidia,tegra20-mpe"; reg = <0x54040000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_MPE>; + resets = <&tegra_car 60>; + reset-names = "mpe"; }; - vi { + vi@54080000 { compatible = "nvidia,tegra20-vi"; reg = <0x54080000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; }; - epp { + epp@540c0000 { compatible = "nvidia,tegra20-epp"; reg = <0x540c0000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_EPP>; + resets = <&tegra_car 19>; + reset-names = "epp"; }; - isp { + isp@54100000 { compatible = "nvidia,tegra20-isp"; reg = <0x54100000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_ISP>; + resets = <&tegra_car 23>; + reset-names = "isp"; }; - gr2d { + gr2d@54140000 { compatible = "nvidia,tegra20-gr2d"; reg = <0x54140000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_GR2D>; + resets = <&tegra_car 21>; + reset-names = "2d"; }; - gr3d { + gr3d@54140000 { compatible = "nvidia,tegra20-gr3d"; - reg = <0x54180000 0x00040000>; + reg = <0x54140000 0x00040000>; clocks = <&tegra_car TEGRA20_CLK_GR3D>; + resets = <&tegra_car 24>; + reset-names = "3d"; }; dc@54200000 { @@ -75,7 +90,9 @@ interrupts = ; clocks = <&tegra_car TEGRA20_CLK_DISP1>, <&tegra_car TEGRA20_CLK_PLL_P>; - clock-names = "disp1", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; rgb { status = "disabled"; @@ -88,24 +105,28 @@ interrupts = ; clocks = <&tegra_car TEGRA20_CLK_DISP2>, <&tegra_car TEGRA20_CLK_PLL_P>; - clock-names = "disp2", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; rgb { status = "disabled"; }; }; - hdmi { + hdmi@54280000 { compatible = "nvidia,tegra20-hdmi"; reg = <0x54280000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_HDMI>, <&tegra_car TEGRA20_CLK_PLL_D_OUT0>; clock-names = "hdmi", "parent"; + resets = <&tegra_car 51>; + reset-names = "hdmi"; status = "disabled"; }; - tvo { + tvo@542c0000 { compatible = "nvidia,tegra20-tvo"; reg = <0x542c0000 0x00040000>; interrupts = ; @@ -113,10 +134,12 @@ status = "disabled"; }; - dsi { + dsi@542c0000 { compatible = "nvidia,tegra20-dsi"; - reg = <0x54300000 0x00040000>; + reg = <0x542c0000 0x00040000>; clocks = <&tegra_car TEGRA20_CLK_DSI>; + resets = <&tegra_car 48>; + reset-names = "dsi"; status = "disabled"; }; }; @@ -129,7 +152,7 @@ clocks = <&tegra_car TEGRA20_CLK_TWD>; }; - intc: interrupt-controller { + intc: interrupt-controller@50041000 { compatible = "arm,cortex-a9-gic"; reg = <0x50041000 0x1000 0x50040100 0x0100>; @@ -137,7 +160,7 @@ #interrupt-cells = <3>; }; - cache-controller { + cache-controller@50043000 { compatible = "arm,pl310-cache"; reg = <0x50043000 0x1000>; arm,data-latency = <5 5 2>; @@ -156,13 +179,14 @@ clocks = <&tegra_car TEGRA20_CLK_TIMER>; }; - tegra_car: clock { + tegra_car: clock@60006000 { compatible = "nvidia,tegra20-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; - apbdma: dma { + apbdma: dma@6000a000 { compatible = "nvidia,tegra20-apbdma"; reg = <0x6000a000 0x1200>; interrupts = , @@ -182,14 +206,17 @@ , ; clocks = <&tegra_car TEGRA20_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; - ahb { + ahb@6000c004 { compatible = "nvidia,tegra20-ahb"; reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */ }; - gpio: gpio { + gpio: gpio@6000d000 { compatible = "nvidia,tegra20-gpio"; reg = <0x6000d000 0x1000>; interrupts = , @@ -205,7 +232,7 @@ interrupt-controller; }; - pinmux: pinmux { + pinmux: pinmux@70000014 { compatible = "nvidia,tegra20-pinmux"; reg = <0x70000014 0x10 /* Tri-state registers */ 0x70000080 0x20 /* Mux registers */ @@ -213,17 +240,20 @@ 0x70000868 0xa8>; /* Pad control registers */ }; - das { + das@70000c00 { compatible = "nvidia,tegra20-das"; reg = <0x70000c00 0x80>; }; - tegra_ac97: ac97 { + tegra_ac97: ac97@70002000 { compatible = "nvidia,tegra20-ac97"; reg = <0x70002000 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 12>; clocks = <&tegra_car TEGRA20_CLK_AC97>; + resets = <&tegra_car 3>; + reset-names = "ac97"; + dmas = <&apbdma 12>, <&apbdma 12>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -231,8 +261,11 @@ compatible = "nvidia,tegra20-i2s"; reg = <0x70002800 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 2>; clocks = <&tegra_car TEGRA20_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; + dmas = <&apbdma 2>, <&apbdma 2>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -240,8 +273,11 @@ compatible = "nvidia,tegra20-i2s"; reg = <0x70002a00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 1>; clocks = <&tegra_car TEGRA20_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; + dmas = <&apbdma 1>, <&apbdma 1>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -257,8 +293,11 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 8>; clocks = <&tegra_car TEGRA20_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -267,8 +306,11 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 9>; clocks = <&tegra_car TEGRA20_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -277,8 +319,11 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 10>; clocks = <&tegra_car TEGRA20_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -287,8 +332,11 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 19>; clocks = <&tegra_car TEGRA20_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -297,20 +345,25 @@ reg = <0x70006400 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 20>; clocks = <&tegra_car TEGRA20_CLK_UARTE>; + resets = <&tegra_car 66>; + reset-names = "serial"; + dmas = <&apbdma 20>, <&apbdma 20>; + dma-names = "rx", "tx"; status = "disabled"; }; - pwm: pwm { + pwm: pwm@7000a000 { compatible = "nvidia,tegra20-pwm"; reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA20_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; status = "disabled"; }; - rtc { + rtc@7000e000 { compatible = "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = ; @@ -326,6 +379,10 @@ clocks = <&tegra_car TEGRA20_CLK_I2C1>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -333,10 +390,13 @@ compatible = "nvidia,tegra20-sflash"; reg = <0x7000c380 0x80>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 11>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SPI>; + resets = <&tegra_car 43>; + reset-names = "spi"; + dmas = <&apbdma 11>, <&apbdma 11>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -349,6 +409,10 @@ clocks = <&tegra_car TEGRA20_CLK_I2C2>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -361,6 +425,10 @@ clocks = <&tegra_car TEGRA20_CLK_I2C3>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -373,6 +441,10 @@ clocks = <&tegra_car TEGRA20_CLK_DVC>, <&tegra_car TEGRA20_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -380,10 +452,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000d400 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 15>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC1>; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -391,10 +466,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000d600 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 16>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC2>; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -402,10 +480,13 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000d800 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC3>; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -413,22 +494,27 @@ compatible = "nvidia,tegra20-slink"; reg = <0x7000da00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 18>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA20_CLK_SBC4>; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; status = "disabled"; }; - kbc { + kbc@7000e200 { compatible = "nvidia,tegra20-kbc"; reg = <0x7000e200 0x100>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; status = "disabled"; }; - pmc { + pmc@7000e400 { compatible = "nvidia,tegra20-pmc"; reg = <0x7000e400 0x400>; clocks = <&tegra_car TEGRA20_CLK_PCLK>, <&clk32k_in>; @@ -442,7 +528,7 @@ interrupts = ; }; - iommu { + iommu@7000f024 { compatible = "nvidia,tegra20-gart"; reg = <0x7000f024 0x00000018 /* controller registers */ 0x58000000 0x02000000>; /* GART aperture */ @@ -455,7 +541,7 @@ #size-cells = <0>; }; - pcie-controller { + pcie-controller@80003000 { compatible = "nvidia,tegra20-pcie"; device_type = "pci"; reg = <0x80003000 0x00000800 /* PADS registers */ @@ -478,9 +564,12 @@ clocks = <&tegra_car TEGRA20_CLK_PEX>, <&tegra_car TEGRA20_CLK_AFI>, - <&tegra_car TEGRA20_CLK_PCIE_XCLK>, <&tegra_car TEGRA20_CLK_PLL_E>; - clock-names = "pex", "afi", "pcie_xclk", "pll_e"; + clock-names = "pex", "afi", "pll_e"; + resets = <&tegra_car 70>, + <&tegra_car 72>, + <&tegra_car 74>; + reset-names = "pex", "afi", "pcie_x"; status = "disabled"; pci@1,0 { @@ -517,6 +606,8 @@ phy_type = "utmi"; nvidia,has-legacy-mode; clocks = <&tegra_car TEGRA20_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; nvidia,needs-double-reset; nvidia,phy = <&phy1>; status = "disabled"; @@ -548,6 +639,8 @@ interrupts = ; phy_type = "ulpi"; clocks = <&tegra_car TEGRA20_CLK_USB2>; + resets = <&tegra_car 58>; + reset-names = "usb"; nvidia,phy = <&phy2>; status = "disabled"; }; @@ -569,6 +662,8 @@ interrupts = ; phy_type = "utmi"; clocks = <&tegra_car TEGRA20_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; nvidia,phy = <&phy3>; status = "disabled"; }; @@ -597,6 +692,8 @@ reg = <0xc8000000 0x200>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; status = "disabled"; }; @@ -605,6 +702,8 @@ reg = <0xc8000200 0x200>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; status = "disabled"; }; @@ -613,6 +712,8 @@ reg = <0xc8000400 0x200>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; status = "disabled"; }; @@ -621,6 +722,8 @@ reg = <0xc8000600 0x200>; interrupts = ; clocks = <&tegra_car TEGRA20_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts index 08cad696e89f..e93fe45b7803 100644 --- a/arch/arm/boot/dts/tegra30-beaver.dts +++ b/arch/arm/boot/dts/tegra30-beaver.dts @@ -6,11 +6,16 @@ model = "NVIDIA Tegra30 Beaver evaluation board"; compatible = "nvidia,beaver", "nvidia,tegra30"; + aliases { + rtc0 = "/i2c@7000d000/tps65911@2d"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x80000000 0x7ff00000>; }; - pcie-controller { + pcie-controller@00003000 { status = "okay"; pex-clk-supply = <&sys_3v3_pexs_reg>; vdd-supply = <&ldo1_reg>; @@ -31,8 +36,8 @@ }; }; - host1x { - hdmi { + host1x@50000000 { + hdmi@54280000 { status = "okay"; vdd-supply = <&sys_3v3_reg>; @@ -44,7 +49,7 @@ }; }; - pinmux { + pinmux@70000868 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -52,8 +57,8 @@ sdmmc1_clk_pz0 { nvidia,pins = "sdmmc1_clk_pz0"; nvidia,function = "sdmmc1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc1_cmd_pz1 { nvidia,pins = "sdmmc1_cmd_pz1", @@ -62,14 +67,14 @@ "sdmmc1_dat2_py5", "sdmmc1_dat3_py4"; nvidia,function = "sdmmc1"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc3_clk_pa6 { nvidia,pins = "sdmmc3_clk_pa6"; nvidia,function = "sdmmc3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc3_cmd_pa7 { nvidia,pins = "sdmmc3_cmd_pa7", @@ -78,15 +83,15 @@ "sdmmc3_dat2_pb5", "sdmmc3_dat3_pb4"; nvidia,function = "sdmmc3"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc4_clk_pcc4 { nvidia,pins = "sdmmc4_clk_pcc4", "sdmmc4_rst_n_pcc3"; nvidia,function = "sdmmc4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc4_dat0_paa0 { nvidia,pins = "sdmmc4_dat0_paa0", @@ -98,8 +103,8 @@ "sdmmc4_dat6_paa6", "sdmmc4_dat7_paa7"; nvidia,function = "sdmmc4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; dap2_fs_pa2 { nvidia,pins = "dap2_fs_pa2", @@ -107,18 +112,18 @@ "dap2_din_pa4", "dap2_dout_pa5"; nvidia,function = "i2s1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; pex_l1_prsnt_n_pdd4 { nvidia,pins = "pex_l1_prsnt_n_pdd4", "pex_l1_clkreq_n_pdd6"; - nvidia,pull = <2>; + nvidia,pull = ; }; sdio3 { nvidia,pins = "drive_sdio3"; - nvidia,high-speed-mode = <0>; - nvidia,schmitt = <0>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; nvidia,pull-down-strength = <46>; nvidia,pull-up-strength = <42>; nvidia,slew-rate-rising = <1>; @@ -159,7 +164,7 @@ status = "okay"; clock-frequency = <100000>; - rt5640: rt5640 { + rt5640: rt5640@1c { compatible = "realtek,rt5640"; reg = <0x1c>; interrupt-parent = <&gpio>; @@ -168,19 +173,6 @@ <&gpio TEGRA_GPIO(X, 2) GPIO_ACTIVE_HIGH>; }; - tps62361 { - compatible = "ti,tps62361"; - reg = <0x60>; - - regulator-name = "tps62361-vout"; - regulator-min-microvolt = <500000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - ti,vsel0-state-high; - ti,vsel1-state-high; - }; - pmic: tps65911@2d { compatible = "ti,tps65911"; reg = <0x2d>; @@ -284,6 +276,19 @@ }; }; }; + + tps62361@60 { + compatible = "ti,tps62361"; + reg = <0x60>; + + regulator-name = "tps62361-vout"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + ti,vsel0-state-high; + ti,vsel1-state-high; + }; }; spi@7000da00 { @@ -296,13 +301,7 @@ }; }; - ahub { - i2s@70080400 { - status = "okay"; - }; - }; - - pmc { + pmc@7000e400 { status = "okay"; nvidia,invert-interrupt; nvidia,suspend-mode = <1>; @@ -314,6 +313,12 @@ nvidia,sys-clock-req-active-high; }; + ahub@70080000 { + i2s@70080400 { + status = "okay"; + }; + }; + sdhci@78000000 { status = "okay"; cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; @@ -328,6 +333,15 @@ non-removable; }; + usb@7d004000 { + status = "okay"; + }; + + phy2: usb-phy@7d004000 { + vbus-supply = <&sys_3v3_reg>; + status = "okay"; + }; + usb@7d008000 { status = "okay"; }; @@ -342,7 +356,7 @@ #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -350,6 +364,19 @@ }; }; + gpio-leds { + compatible = "gpio-leds"; + + gpled1 { + label = "LED1"; /* CR5A1 (blue) */ + gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>; + }; + gpled2 { + label = "LED2"; /* CR4A2 (green) */ + gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>; + }; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -453,19 +480,6 @@ }; }; - gpio-leds { - compatible = "gpio-leds"; - - gpled1 { - label = "LED1"; /* CR5A1 (blue) */ - gpios = <&gpio TEGRA_GPIO(L, 1) GPIO_ACTIVE_HIGH>; - }; - gpled2 { - label = "LED2"; /* CR4A2 (green) */ - gpios = <&gpio TEGRA_GPIO(L, 0) GPIO_ACTIVE_HIGH>; - }; - }; - sound { compatible = "nvidia,tegra-audio-rt5640-beaver", "nvidia,tegra-audio-rt5640"; diff --git a/arch/arm/boot/dts/tegra30-cardhu-a02.dts b/arch/arm/boot/dts/tegra30-cardhu-a02.dts index 1082c5ed90d1..c9bfedcca6ed 100644 --- a/arch/arm/boot/dts/tegra30-cardhu-a02.dts +++ b/arch/arm/boot/dts/tegra30-cardhu-a02.dts @@ -8,6 +8,13 @@ model = "NVIDIA Tegra30 Cardhu A02 evaluation board"; compatible = "nvidia,cardhu-a02", "nvidia,cardhu", "nvidia,tegra30"; + sdhci@78000400 { + status = "okay"; + power-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>; + bus-width = <4>; + keep-power-in-suspend; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -83,12 +90,5 @@ gpio = <&gpio TEGRA_GPIO(K, 3) GPIO_ACTIVE_HIGH>; }; }; - - sdhci@78000400 { - status = "okay"; - power-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>; - bus-width = <4>; - keep-power-in-suspend; - }; }; diff --git a/arch/arm/boot/dts/tegra30-cardhu-a04.dts b/arch/arm/boot/dts/tegra30-cardhu-a04.dts index bf012bddaafb..fadf55e46b2b 100644 --- a/arch/arm/boot/dts/tegra30-cardhu-a04.dts +++ b/arch/arm/boot/dts/tegra30-cardhu-a04.dts @@ -8,6 +8,13 @@ model = "NVIDIA Tegra30 Cardhu A04 (A05, A06, A07) evaluation board"; compatible = "nvidia,cardhu-a04", "nvidia,cardhu", "nvidia,tegra30"; + sdhci@78000400 { + status = "okay"; + power-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>; + bus-width = <4>; + keep-power-in-suspend; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; @@ -95,11 +102,4 @@ gpio = <&gpio TEGRA_GPIO(DD, 0) GPIO_ACTIVE_HIGH>; }; }; - - sdhci@78000400 { - status = "okay"; - power-gpios = <&gpio TEGRA_GPIO(D, 3) GPIO_ACTIVE_HIGH>; - bus-width = <4>; - keep-power-in-suspend; - }; }; diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index 5ea7dfa4d9fa..9104224124ee 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -27,11 +27,16 @@ model = "NVIDIA Tegra30 Cardhu evaluation board"; compatible = "nvidia,cardhu", "nvidia,tegra30"; + aliases { + rtc0 = "/i2c@7000d000/tps6586x@34"; + rtc1 = "/rtc@7000e000"; + }; + memory { reg = <0x80000000 0x40000000>; }; - pcie-controller { + pcie-controller@00003000 { status = "okay"; pex-clk-supply = <&pex_hvdd_3v3_reg>; vdd-supply = <&ldo1_reg>; @@ -51,7 +56,17 @@ }; }; - pinmux { + host1x@50000000 { + dc@54200000 { + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + }; + }; + }; + + pinmux@70000868 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; @@ -59,8 +74,8 @@ sdmmc1_clk_pz0 { nvidia,pins = "sdmmc1_clk_pz0"; nvidia,function = "sdmmc1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc1_cmd_pz1 { nvidia,pins = "sdmmc1_cmd_pz1", @@ -69,14 +84,14 @@ "sdmmc1_dat2_py5", "sdmmc1_dat3_py4"; nvidia,function = "sdmmc1"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc3_clk_pa6 { nvidia,pins = "sdmmc3_clk_pa6"; nvidia,function = "sdmmc3"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc3_cmd_pa7 { nvidia,pins = "sdmmc3_cmd_pa7", @@ -85,15 +100,15 @@ "sdmmc3_dat2_pb5", "sdmmc3_dat3_pb4"; nvidia,function = "sdmmc3"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc4_clk_pcc4 { nvidia,pins = "sdmmc4_clk_pcc4", "sdmmc4_rst_n_pcc3"; nvidia,function = "sdmmc4"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdmmc4_dat0_paa0 { nvidia,pins = "sdmmc4_dat0_paa0", @@ -105,8 +120,8 @@ "sdmmc4_dat6_paa6", "sdmmc4_dat7_paa7"; nvidia,function = "sdmmc4"; - nvidia,pull = <2>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; dap2_fs_pa2 { nvidia,pins = "dap2_fs_pa2", @@ -114,17 +129,17 @@ "dap2_din_pa4", "dap2_dout_pa5"; nvidia,function = "i2s1"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; sdio3 { nvidia,pins = "drive_sdio3"; - nvidia,high-speed-mode = <0>; - nvidia,schmitt = <0>; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; nvidia,pull-down-strength = <46>; nvidia,pull-up-strength = <42>; - nvidia,slew-rate-rising = <1>; - nvidia,slew-rate-falling = <1>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; }; uart3_txd_pw6 { nvidia,pins = "uart3_txd_pw6", @@ -132,8 +147,8 @@ "uart3_rts_n_pc0", "uart3_rxd_pw7"; nvidia,function = "uartc"; - nvidia,pull = <0>; - nvidia,tristate = <0>; + nvidia,pull = ; + nvidia,tristate = ; }; }; }; @@ -147,7 +162,11 @@ status = "okay"; }; - i2c@7000c000 { + pwm@7000a000 { + status = "okay"; + }; + + panelddc: i2c@7000c000 { status = "okay"; clock-frequency = <100000>; }; @@ -302,7 +321,7 @@ interrupts = ; }; - tps62361 { + tps62361@60 { compatible = "ti,tps62361"; reg = <0x60>; @@ -326,13 +345,7 @@ }; }; - ahub { - i2s@70080400 { - status = "okay"; - }; - }; - - pmc { + pmc@7000e400 { status = "okay"; nvidia,invert-interrupt; nvidia,suspend-mode = <1>; @@ -344,6 +357,12 @@ nvidia,sys-clock-req-active-high; }; + ahub@70080000 { + i2s@70080400 { + status = "okay"; + }; + }; + sdhci@78000000 { status = "okay"; cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; @@ -367,12 +386,23 @@ status = "okay"; }; + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_bl_reg>; + pwms = <&pwm 0 5000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + clocks { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; - clk32k_in: clock { + clk32k_in: clock@0 { compatible = "fixed-clock"; reg=<0>; #clock-cells = <0>; @@ -380,6 +410,16 @@ }; }; + panel: panel { + compatible = "chunghwa,claa101wb01", "simple-panel"; + ddc-i2c-bus = <&panelddc>; + + power-supply = <&vdd_pnl1_reg>; + enable-gpios = <&gpio TEGRA_GPIO(L, 2) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + }; + regulators { compatible = "simple-bus"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 2bd55cfd88ad..ed8e7700b46d 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -1,5 +1,6 @@ #include #include +#include #include #include "skeleton.dtsi" @@ -16,7 +17,7 @@ serial4 = &uarte; }; - pcie-controller { + pcie-controller@00003000 { compatible = "nvidia,tegra30-pcie"; device_type = "pci"; reg = <0x00003000 0x00000800 /* PADS registers */ @@ -40,10 +41,13 @@ clocks = <&tegra_car TEGRA30_CLK_PCIE>, <&tegra_car TEGRA30_CLK_AFI>, - <&tegra_car TEGRA30_CLK_PCIEX>, <&tegra_car TEGRA30_CLK_PLL_E>, <&tegra_car TEGRA30_CLK_CML0>; - clock-names = "pex", "afi", "pcie_xclk", "pll_e", "cml"; + clock-names = "pex", "afi", "pll_e", "cml"; + resets = <&tegra_car 70>, + <&tegra_car 72>, + <&tegra_car 74>; + reset-names = "pex", "afi", "pcie_x"; status = "disabled"; pci@1,0 { @@ -86,59 +90,74 @@ }; }; - host1x { + host1x@50000000 { compatible = "nvidia,tegra30-host1x", "simple-bus"; reg = <0x50000000 0x00024000>; interrupts = , /* syncpt */ ; /* general */ clocks = <&tegra_car TEGRA30_CLK_HOST1X>; + resets = <&tegra_car 28>; + reset-names = "host1x"; #address-cells = <1>; #size-cells = <1>; ranges = <0x54000000 0x54000000 0x04000000>; - mpe { + mpe@54040000 { compatible = "nvidia,tegra30-mpe"; reg = <0x54040000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_MPE>; + resets = <&tegra_car 60>; + reset-names = "mpe"; }; - vi { + vi@54080000 { compatible = "nvidia,tegra30-vi"; reg = <0x54080000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_VI>; + resets = <&tegra_car 20>; + reset-names = "vi"; }; - epp { + epp@540c0000 { compatible = "nvidia,tegra30-epp"; reg = <0x540c0000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_EPP>; + resets = <&tegra_car 19>; + reset-names = "epp"; }; - isp { + isp@54100000 { compatible = "nvidia,tegra30-isp"; reg = <0x54100000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_ISP>; + resets = <&tegra_car 23>; + reset-names = "isp"; }; - gr2d { + gr2d@54140000 { compatible = "nvidia,tegra30-gr2d"; reg = <0x54140000 0x00040000>; interrupts = ; + resets = <&tegra_car 21>; + reset-names = "2d"; clocks = <&tegra_car TEGRA30_CLK_GR2D>; }; - gr3d { + gr3d@54180000 { compatible = "nvidia,tegra30-gr3d"; reg = <0x54180000 0x00040000>; clocks = <&tegra_car TEGRA30_CLK_GR3D &tegra_car TEGRA30_CLK_GR3D2>; clock-names = "3d", "3d2"; + resets = <&tegra_car 24>, + <&tegra_car 98>; + reset-names = "3d", "3d2"; }; dc@54200000 { @@ -147,7 +166,9 @@ interrupts = ; clocks = <&tegra_car TEGRA30_CLK_DISP1>, <&tegra_car TEGRA30_CLK_PLL_P>; - clock-names = "disp1", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 27>; + reset-names = "dc"; rgb { status = "disabled"; @@ -160,24 +181,28 @@ interrupts = ; clocks = <&tegra_car TEGRA30_CLK_DISP2>, <&tegra_car TEGRA30_CLK_PLL_P>; - clock-names = "disp2", "parent"; + clock-names = "dc", "parent"; + resets = <&tegra_car 26>; + reset-names = "dc"; rgb { status = "disabled"; }; }; - hdmi { + hdmi@54280000 { compatible = "nvidia,tegra30-hdmi"; reg = <0x54280000 0x00040000>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_HDMI>, <&tegra_car TEGRA30_CLK_PLL_D2_OUT0>; clock-names = "hdmi", "parent"; + resets = <&tegra_car 51>; + reset-names = "hdmi"; status = "disabled"; }; - tvo { + tvo@542c0000 { compatible = "nvidia,tegra30-tvo"; reg = <0x542c0000 0x00040000>; interrupts = ; @@ -185,10 +210,12 @@ status = "disabled"; }; - dsi { + dsi@54300000 { compatible = "nvidia,tegra30-dsi"; reg = <0x54300000 0x00040000>; clocks = <&tegra_car TEGRA30_CLK_DSIA>; + resets = <&tegra_car 48>; + reset-names = "dsi"; status = "disabled"; }; }; @@ -201,7 +228,7 @@ clocks = <&tegra_car TEGRA30_CLK_TWD>; }; - intc: interrupt-controller { + intc: interrupt-controller@50041000 { compatible = "arm,cortex-a9-gic"; reg = <0x50041000 0x1000 0x50040100 0x0100>; @@ -209,7 +236,7 @@ #interrupt-cells = <3>; }; - cache-controller { + cache-controller@50043000 { compatible = "arm,pl310-cache"; reg = <0x50043000 0x1000>; arm,data-latency = <6 6 2>; @@ -230,13 +257,14 @@ clocks = <&tegra_car TEGRA30_CLK_TIMER>; }; - tegra_car: clock { + tegra_car: clock@60006000 { compatible = "nvidia,tegra30-car"; reg = <0x60006000 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; - apbdma: dma { + apbdma: dma@6000a000 { compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; reg = <0x6000a000 0x1400>; interrupts = , @@ -272,14 +300,17 @@ , ; clocks = <&tegra_car TEGRA30_CLK_APBDMA>; + resets = <&tegra_car 34>; + reset-names = "dma"; + #dma-cells = <1>; }; - ahb: ahb { + ahb: ahb@6000c004 { compatible = "nvidia,tegra30-ahb"; reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */ }; - gpio: gpio { + gpio: gpio@6000d000 { compatible = "nvidia,tegra30-gpio"; reg = <0x6000d000 0x1000>; interrupts = , @@ -296,7 +327,7 @@ interrupt-controller; }; - pinmux: pinmux { + pinmux: pinmux@70000868 { compatible = "nvidia,tegra30-pinmux"; reg = <0x70000868 0xd4 /* Pad control registers */ 0x70003000 0x3e4>; /* Mux registers */ @@ -315,8 +346,11 @@ reg = <0x70006000 0x40>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 8>; clocks = <&tegra_car TEGRA30_CLK_UARTA>; + resets = <&tegra_car 6>; + reset-names = "serial"; + dmas = <&apbdma 8>, <&apbdma 8>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -325,8 +359,11 @@ reg = <0x70006040 0x40>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 9>; clocks = <&tegra_car TEGRA30_CLK_UARTB>; + resets = <&tegra_car 7>; + reset-names = "serial"; + dmas = <&apbdma 9>, <&apbdma 9>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -335,8 +372,11 @@ reg = <0x70006200 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 10>; clocks = <&tegra_car TEGRA30_CLK_UARTC>; + resets = <&tegra_car 55>; + reset-names = "serial"; + dmas = <&apbdma 10>, <&apbdma 10>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -345,8 +385,11 @@ reg = <0x70006300 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 19>; clocks = <&tegra_car TEGRA30_CLK_UARTD>; + resets = <&tegra_car 65>; + reset-names = "serial"; + dmas = <&apbdma 19>, <&apbdma 19>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -355,20 +398,25 @@ reg = <0x70006400 0x100>; reg-shift = <2>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 20>; clocks = <&tegra_car TEGRA30_CLK_UARTE>; + resets = <&tegra_car 66>; + reset-names = "serial"; + dmas = <&apbdma 20>, <&apbdma 20>; + dma-names = "rx", "tx"; status = "disabled"; }; - pwm: pwm { + pwm: pwm@7000a000 { compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm"; reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA30_CLK_PWM>; + resets = <&tegra_car 17>; + reset-names = "pwm"; status = "disabled"; }; - rtc { + rtc@7000e000 { compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc"; reg = <0x7000e000 0x100>; interrupts = ; @@ -384,6 +432,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C1>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 12>; + reset-names = "i2c"; + dmas = <&apbdma 21>, <&apbdma 21>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -396,6 +448,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C2>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 54>; + reset-names = "i2c"; + dmas = <&apbdma 22>, <&apbdma 22>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -408,6 +464,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C3>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 67>; + reset-names = "i2c"; + dmas = <&apbdma 23>, <&apbdma 23>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -419,7 +479,11 @@ #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_I2C4>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; + resets = <&tegra_car 103>; + reset-names = "i2c"; clock-names = "div-clk", "fast-clk"; + dmas = <&apbdma 26>, <&apbdma 26>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -432,6 +496,10 @@ clocks = <&tegra_car TEGRA30_CLK_I2C5>, <&tegra_car TEGRA30_CLK_PLL_P_OUT3>; clock-names = "div-clk", "fast-clk"; + resets = <&tegra_car 47>; + reset-names = "i2c"; + dmas = <&apbdma 24>, <&apbdma 24>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -439,10 +507,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000d400 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 15>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC1>; + resets = <&tegra_car 41>; + reset-names = "spi"; + dmas = <&apbdma 15>, <&apbdma 15>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -450,10 +521,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000d600 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 16>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC2>; + resets = <&tegra_car 44>; + reset-names = "spi"; + dmas = <&apbdma 16>, <&apbdma 16>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -461,10 +535,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000d800 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 17>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC3>; + resets = <&tegra_car 46>; + reset-names = "spi"; + dmas = <&apbdma 17>, <&apbdma 17>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -472,10 +549,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000da00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 18>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC4>; + resets = <&tegra_car 68>; + reset-names = "spi"; + dmas = <&apbdma 18>, <&apbdma 18>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -483,10 +563,13 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000dc00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 27>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC5>; + resets = <&tegra_car 104>; + reset-names = "spi"; + dmas = <&apbdma 27>, <&apbdma 27>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -494,29 +577,34 @@ compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink"; reg = <0x7000de00 0x200>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 28>; #address-cells = <1>; #size-cells = <0>; clocks = <&tegra_car TEGRA30_CLK_SBC6>; + resets = <&tegra_car 106>; + reset-names = "spi"; + dmas = <&apbdma 28>, <&apbdma 28>; + dma-names = "rx", "tx"; status = "disabled"; }; - kbc { + kbc@7000e200 { compatible = "nvidia,tegra30-kbc", "nvidia,tegra20-kbc"; reg = <0x7000e200 0x100>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_KBC>; + resets = <&tegra_car 36>; + reset-names = "kbc"; status = "disabled"; }; - pmc { + pmc@7000e400 { compatible = "nvidia,tegra30-pmc"; reg = <0x7000e400 0x400>; clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>; clock-names = "pclk", "clk32k_in"; }; - memory-controller { + memory-controller@7000f000 { compatible = "nvidia,tegra30-mc"; reg = <0x7000f000 0x010 0x7000f03c 0x1b4 @@ -525,7 +613,7 @@ interrupts = ; }; - iommu { + iommu@7000f010 { compatible = "nvidia,tegra30-smmu"; reg = <0x7000f010 0x02c 0x7000f1f0 0x010 @@ -535,26 +623,34 @@ nvidia,ahb = <&ahb>; }; - ahub { + ahub@70080000 { compatible = "nvidia,tegra30-ahub"; reg = <0x70080000 0x200 0x70080200 0x100>; interrupts = ; - nvidia,dma-request-selector = <&apbdma 1>; clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>, - <&tegra_car TEGRA30_CLK_APBIF>, - <&tegra_car TEGRA30_CLK_I2S0>, - <&tegra_car TEGRA30_CLK_I2S1>, - <&tegra_car TEGRA30_CLK_I2S2>, - <&tegra_car TEGRA30_CLK_I2S3>, - <&tegra_car TEGRA30_CLK_I2S4>, - <&tegra_car TEGRA30_CLK_DAM0>, - <&tegra_car TEGRA30_CLK_DAM1>, - <&tegra_car TEGRA30_CLK_DAM2>, - <&tegra_car TEGRA30_CLK_SPDIF_IN>; - clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + <&tegra_car TEGRA30_CLK_APBIF>; + clock-names = "d_audio", "apbif"; + resets = <&tegra_car 106>, /* d_audio */ + <&tegra_car 107>, /* apbif */ + <&tegra_car 30>, /* i2s0 */ + <&tegra_car 11>, /* i2s1 */ + <&tegra_car 18>, /* i2s2 */ + <&tegra_car 101>, /* i2s3 */ + <&tegra_car 102>, /* i2s4 */ + <&tegra_car 108>, /* dam0 */ + <&tegra_car 109>, /* dam1 */ + <&tegra_car 110>, /* dam2 */ + <&tegra_car 10>; /* spdif */ + reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", "i2s3", "i2s4", "dam0", "dam1", "dam2", - "spdif_in"; + "spdif"; + dmas = <&apbdma 1>, <&apbdma 1>, + <&apbdma 2>, <&apbdma 2>, + <&apbdma 3>, <&apbdma 3>, + <&apbdma 4>, <&apbdma 4>; + dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", + "rx3", "tx3"; ranges; #address-cells = <1>; #size-cells = <1>; @@ -564,6 +660,8 @@ reg = <0x70080300 0x100>; nvidia,ahub-cif-ids = <4 4>; clocks = <&tegra_car TEGRA30_CLK_I2S0>; + resets = <&tegra_car 30>; + reset-names = "i2s"; status = "disabled"; }; @@ -572,6 +670,8 @@ reg = <0x70080400 0x100>; nvidia,ahub-cif-ids = <5 5>; clocks = <&tegra_car TEGRA30_CLK_I2S1>; + resets = <&tegra_car 11>; + reset-names = "i2s"; status = "disabled"; }; @@ -580,6 +680,8 @@ reg = <0x70080500 0x100>; nvidia,ahub-cif-ids = <6 6>; clocks = <&tegra_car TEGRA30_CLK_I2S2>; + resets = <&tegra_car 18>; + reset-names = "i2s"; status = "disabled"; }; @@ -588,6 +690,8 @@ reg = <0x70080600 0x100>; nvidia,ahub-cif-ids = <7 7>; clocks = <&tegra_car TEGRA30_CLK_I2S3>; + resets = <&tegra_car 101>; + reset-names = "i2s"; status = "disabled"; }; @@ -596,6 +700,8 @@ reg = <0x70080700 0x100>; nvidia,ahub-cif-ids = <8 8>; clocks = <&tegra_car TEGRA30_CLK_I2S4>; + resets = <&tegra_car 102>; + reset-names = "i2s"; status = "disabled"; }; }; @@ -605,6 +711,8 @@ reg = <0x78000000 0x200>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_SDMMC1>; + resets = <&tegra_car 14>; + reset-names = "sdhci"; status = "disabled"; }; @@ -613,6 +721,8 @@ reg = <0x78000200 0x200>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_SDMMC2>; + resets = <&tegra_car 9>; + reset-names = "sdhci"; status = "disabled"; }; @@ -621,6 +731,8 @@ reg = <0x78000400 0x200>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_SDMMC3>; + resets = <&tegra_car 69>; + reset-names = "sdhci"; status = "disabled"; }; @@ -629,6 +741,8 @@ reg = <0x78000600 0x200>; interrupts = ; clocks = <&tegra_car TEGRA30_CLK_SDMMC4>; + resets = <&tegra_car 15>; + reset-names = "sdhci"; status = "disabled"; }; @@ -638,6 +752,8 @@ interrupts = ; phy_type = "utmi"; clocks = <&tegra_car TEGRA30_CLK_USBD>; + resets = <&tegra_car 22>; + reset-names = "usb"; nvidia,needs-double-reset; nvidia,phy = <&phy1>; status = "disabled"; @@ -669,20 +785,33 @@ compatible = "nvidia,tegra30-ehci", "usb-ehci"; reg = <0x7d004000 0x4000>; interrupts = ; - phy_type = "ulpi"; + phy_type = "utmi"; clocks = <&tegra_car TEGRA30_CLK_USB2>; + resets = <&tegra_car 58>; + reset-names = "usb"; nvidia,phy = <&phy2>; status = "disabled"; }; phy2: usb-phy@7d004000 { compatible = "nvidia,tegra30-usb-phy"; - reg = <0x7d004000 0x4000>; - phy_type = "ulpi"; + reg = <0x7d004000 0x4000 0x7d000000 0x4000>; + phy_type = "utmi"; clocks = <&tegra_car TEGRA30_CLK_USB2>, <&tegra_car TEGRA30_CLK_PLL_U>, - <&tegra_car TEGRA30_CLK_CDEV2>; - clock-names = "reg", "pll_u", "ulpi-link"; + <&tegra_car TEGRA30_CLK_USBD>; + clock-names = "reg", "pll_u", "utmi-pads"; + nvidia,hssync-start-delay = <9>; + nvidia,idle-wait-delay = <17>; + nvidia,elastic-limit = <16>; + nvidia,term-range-adj = <6>; + nvidia,xcvr-setup = <51>; + nvidia.xcvr-setup-use-fuses; + nvidia,xcvr-lsfslew = <2>; + nvidia,xcvr-lsrslew = <2>; + nvidia,xcvr-hsslew = <32>; + nvidia,hssquelch-level = <2>; + nvidia,hsdiscon-level = <5>; status = "disabled"; }; @@ -692,6 +821,8 @@ interrupts = ; phy_type = "utmi"; clocks = <&tegra_car TEGRA30_CLK_USB3>; + resets = <&tegra_car 59>; + reset-names = "usb"; nvidia,phy = <&phy3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index e7f73b2e4550..5d7681be0580 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -15,6 +15,25 @@ / { compatible = "xlnx,zynq-7000"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <0>; + clocks = <&clkc 3>; + }; + + cpu@1 { + compatible = "arm,cortex-a9"; + device_type = "cpu"; + reg = <1>; + clocks = <&clkc 3>; + }; + }; + pmu { compatible = "arm,cortex-a9-pmu"; interrupts = <0 5 4>, <0 6 4>; @@ -65,6 +84,24 @@ interrupts = <0 50 4>; }; + gem0: ethernet@e000b000 { + compatible = "cdns,gem"; + reg = <0xe000b000 0x4000>; + status = "disabled"; + interrupts = <0 22 4>; + clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>; + clock-names = "pclk", "hclk", "tx_clk"; + }; + + gem1: ethernet@e000c000 { + compatible = "cdns,gem"; + reg = <0xe000c000 0x4000>; + status = "disabled"; + interrupts = <0 45 4>; + clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>; + clock-names = "pclk", "hclk", "tx_clk"; + }; + slcr: slcr@f8000000 { compatible = "xlnx,zynq-slcr"; reg = <0xF8000000 0x1000>; @@ -106,7 +143,6 @@ compatible = "cdns,ttc"; clocks = <&clkc 6>; reg = <0xF8001000 0x1000>; - clock-ranges; }; ttc1: ttc1@f8002000 { @@ -115,7 +151,6 @@ compatible = "cdns,ttc"; clocks = <&clkc 6>; reg = <0xF8002000 0x1000>; - clock-ranges; }; scutimer: scutimer@f8f00600 { interrupt-parent = <&intc>; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index 21aea99a067b..34d680a46b7e 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -29,6 +29,11 @@ }; +&gem0 { + status = "okay"; + phy-mode = "rgmii"; +}; + &uart1 { status = "okay"; }; diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts index 79009e0b74b9..b2835d5fc09a 100644 --- a/arch/arm/boot/dts/zynq-zc706.dts +++ b/arch/arm/boot/dts/zynq-zc706.dts @@ -30,6 +30,11 @@ }; +&gem0 { + status = "okay"; + phy-mode = "rgmii"; +}; + &uart1 { status = "okay"; }; diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts index d6acf2b1cdf4..2eda06889dfc 100644 --- a/arch/arm/boot/dts/zynq-zed.dts +++ b/arch/arm/boot/dts/zynq-zed.dts @@ -30,6 +30,11 @@ }; +&gem0 { + status = "okay"; + phy-mode = "rgmii"; +}; + &uart1 { status = "okay"; }; diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 001f4913799c..5114b68e99d5 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -257,7 +257,7 @@ static int it8152_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t s */ static int it8152_pci_platform_notify(struct device *dev) { - if (dev->bus == &pci_bus_type) { + if (dev_is_pci(dev)) { if (dev->dma_mask) *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; @@ -268,7 +268,7 @@ static int it8152_pci_platform_notify(struct device *dev) static int it8152_pci_platform_notify_remove(struct device *dev) { - if (dev->bus == &pci_bus_type) + if (dev_is_pci(dev)) dmabounce_unregister_dev(dev); return 0; diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index 26020a03f659..1e361abc29eb 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c @@ -35,8 +35,7 @@ void mcpm_set_early_poke(unsigned cpu, unsigned cluster, unsigned long *poke = &mcpm_entry_early_pokes[cluster][cpu][0]; poke[0] = poke_phys_addr; poke[1] = poke_val; - __cpuc_flush_dcache_area((void *)poke, 8); - outer_clean_range(__pa(poke), __pa(poke + 2)); + __sync_cache_range_w(poke, 2 * sizeof(*poke)); } static const struct mcpm_platform_ops *platform_ops; @@ -167,7 +166,7 @@ void __mcpm_cpu_down(unsigned int cpu, unsigned int cluster) dmb(); mcpm_sync.clusters[cluster].cpus[cpu].cpu = CPU_DOWN; sync_cache_w(&mcpm_sync.clusters[cluster].cpus[cpu].cpu); - dsb_sev(); + sev(); } /* @@ -183,7 +182,7 @@ void __mcpm_outbound_leave_critical(unsigned int cluster, int state) dmb(); mcpm_sync.clusters[cluster].cluster = state; sync_cache_w(&mcpm_sync.clusters[cluster].cluster); - dsb_sev(); + sev(); } /* diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index ce922d0ea7aa..53c6a26b633d 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -66,7 +66,7 @@ static long __init sp804_get_clock_rate(struct clk *clk) static void __iomem *sched_clock_base; -static u32 sp804_read(void) +static u64 notrace sp804_read(void) { return ~readl_relaxed(sched_clock_base + TIMER_VALUE); } @@ -104,7 +104,7 @@ void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, if (use_sched_clock) { sched_clock_base = base; - setup_sched_clock(sp804_read, 32, rate); + sched_clock_register(sp804_read, 32, rate); } } diff --git a/arch/arm/configs/ape6evm_defconfig b/arch/arm/configs/ape6evm_defconfig index 1ce39940795d..cb26c62dc722 100644 --- a/arch/arm/configs/ape6evm_defconfig +++ b/arch/arm/configs/ape6evm_defconfig @@ -13,7 +13,7 @@ CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y CONFIG_SLAB=y # CONFIG_BLOCK is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A73A4=y CONFIG_MACH_APE6EVM=y # CONFIG_ARM_THUMB is not set diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig index fae939d3d7f0..9287a62de830 100644 --- a/arch/arm/configs/armadillo800eva_defconfig +++ b/arch/arm/configs/armadillo800eva_defconfig @@ -15,7 +15,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A7740=y CONFIG_MACH_ARMADILLO800EVA=y # CONFIG_SH_TIMER_TMU is not set @@ -105,6 +105,7 @@ CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=y CONFIG_FB_SH_MOBILE_HDMI=y CONFIG_LCD_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y @@ -130,6 +131,8 @@ CONFIG_DMADEVICES=y CONFIG_SH_DMAE=y CONFIG_UIO=y CONFIG_UIO_PDRV_GENIRQ=y +CONFIG_PWM=y +CONFIG_PWM_RENESAS_TPU=y # CONFIG_DNOTIFY is not set CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index 690e89273230..0b4e9b5210d8 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig @@ -22,7 +22,6 @@ CONFIG_SOC_AT91SAM9X5=y CONFIG_SOC_AT91SAM9N12=y CONFIG_MACH_AT91RM9200_DT=y CONFIG_MACH_AT91SAM9_DT=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y CONFIG_AT91_TIMER_HZ=128 CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set diff --git a/arch/arm/configs/at91rm9200_defconfig b/arch/arm/configs/at91rm9200_defconfig index 75502c4d222c..bf057719dab0 100644 --- a/arch/arm/configs/at91rm9200_defconfig +++ b/arch/arm/configs/at91rm9200_defconfig @@ -31,7 +31,6 @@ CONFIG_MACH_YL9200=y CONFIG_MACH_CPUAT91=y CONFIG_MACH_ECO920=y CONFIG_MTD_AT91_DATAFLASH_CARD=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y CONFIG_AT91_TIMER_HZ=100 # CONFIG_ARM_THUMB is not set CONFIG_PCCARD=y diff --git a/arch/arm/configs/at91sam9260_9g20_defconfig b/arch/arm/configs/at91sam9260_9g20_defconfig index 69b6928d3d9d..2cd832918e9c 100644 --- a/arch/arm/configs/at91sam9260_9g20_defconfig +++ b/arch/arm/configs/at91sam9260_9g20_defconfig @@ -15,7 +15,6 @@ CONFIG_MACH_AT91SAM9260EK=y CONFIG_MACH_CAM60=y CONFIG_MACH_SAM9_L9260=y CONFIG_MACH_AFEB9260=y -CONFIG_MACH_QIL_A9260=y CONFIG_MACH_CPU9260=y CONFIG_MACH_FLEXIBITY=y CONFIG_MACH_AT91SAM9G20EK=y @@ -28,7 +27,6 @@ CONFIG_MACH_PCONTROL_G20=y CONFIG_MACH_GSIA18S=y CONFIG_MACH_SNAPPER_9260=y CONFIG_MACH_AT91SAM9_DT=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y CONFIG_AT91_SLOW_CLOCK=y # CONFIG_ARM_THUMB is not set CONFIG_AEABI=y diff --git a/arch/arm/configs/at91sam9261_9g10_defconfig b/arch/arm/configs/at91sam9261_9g10_defconfig index 9d35cd81c611..f80e993b04ce 100644 --- a/arch/arm/configs/at91sam9261_9g10_defconfig +++ b/arch/arm/configs/at91sam9261_9g10_defconfig @@ -18,7 +18,6 @@ CONFIG_ARCH_AT91=y CONFIG_ARCH_AT91SAM9261=y CONFIG_MACH_AT91SAM9261EK=y CONFIG_MACH_AT91SAM9G10EK=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # CONFIG_ARM_THUMB is not set CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set diff --git a/arch/arm/configs/at91sam9g45_defconfig b/arch/arm/configs/at91sam9g45_defconfig index 08166cd4e7d6..e181a50fd65a 100644 --- a/arch/arm/configs/at91sam9g45_defconfig +++ b/arch/arm/configs/at91sam9g45_defconfig @@ -18,7 +18,6 @@ CONFIG_ARCH_AT91=y CONFIG_ARCH_AT91SAM9G45=y CONFIG_MACH_AT91SAM9M10G45EK=y CONFIG_MACH_AT91SAM9_DT=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y CONFIG_AT91_SLOW_CLOCK=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set diff --git a/arch/arm/configs/at91sam9rl_defconfig b/arch/arm/configs/at91sam9rl_defconfig index 7cf87856d63c..7b6f131cecd6 100644 --- a/arch/arm/configs/at91sam9rl_defconfig +++ b/arch/arm/configs/at91sam9rl_defconfig @@ -13,7 +13,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_AT91=y CONFIG_ARCH_AT91SAM9RL=y CONFIG_MACH_AT91SAM9RLEK=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y # CONFIG_ARM_THUMB is not set CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 34e9780e63ba..f43392dc2dcf 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -44,17 +44,26 @@ CONFIG_VFP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_SUSPEND is not set CONFIG_NET=y +CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_NETWORK_SECMARK=y -# CONFIG_WIRELESS is not set +CONFIG_NETFILTER=y +CONFIG_CFG80211=y +CONFIG_MAC80211=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_NETDEVICES=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC95XX=y +CONFIG_ZD1211RW=y +CONFIG_INPUT_EVDEV=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_SERIAL_AMBA_PL011=y @@ -71,15 +80,13 @@ CONFIG_FB=y CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_USB_SUPPORT is not set +CONFIG_USB=y +CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_BCM2835=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y @@ -88,6 +95,8 @@ CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_TRANSIENT=y CONFIG_LEDS_TRIGGER_CAMERA=y +CONFIG_STAGING=y +CONFIG_USB_DWC2=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y @@ -109,20 +118,20 @@ CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_UTF8=y CONFIG_PRINTK_TIME=y +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_UNUSED_SYMBOLS=y -CONFIG_LOCKUP_DETECTOR=y -CONFIG_DEBUG_INFO=y CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_LOCKUP_DETECTOR=y CONFIG_SCHED_TRACER=y CONFIG_STACK_TRACER=y CONFIG_FUNCTION_PROFILER=y -CONFIG_DYNAMIC_DEBUG=y +CONFIG_TEST_KSTRTOX=y CONFIG_KGDB=y CONFIG_KGDB_KDB=y -CONFIG_TEST_KSTRTOX=y CONFIG_STRICT_DEVMEM=y CONFIG_DEBUG_LL=y CONFIG_EARLY_PRINTK=y diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index 287ac1d7aac7..2c38fdf1951d 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig @@ -29,11 +29,9 @@ CONFIG_ARCH_BCM_MOBILE=y CONFIG_ARM_THUMBEE=y CONFIG_PREEMPT=y CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set # CONFIG_COMPACTION is not set CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ARM_APPENDED_DTB=y CONFIG_CMDLINE="console=ttyS0,115200n8 mem=128M" CONFIG_CPU_IDLE=y CONFIG_VFP=y @@ -120,9 +118,11 @@ CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=110 CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y # CONFIG_FTRACE is not set +# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_CCITT=y CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y CONFIG_CRC7=y CONFIG_XZ_DEC=y CONFIG_AVERAGE=y +CONFIG_PINCTRL_CAPRI=y diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig index b38cd107f82d..80cff50beb34 100644 --- a/arch/arm/configs/bockw_defconfig +++ b/arch/arm/configs/bockw_defconfig @@ -8,7 +8,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_EMBEDDED=y CONFIG_SLAB=y # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A7778=y CONFIG_MACH_BOCKW=y CONFIG_MEMORY_START=0x60000000 @@ -27,12 +27,12 @@ CONFIG_HIGHMEM=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y -CONFIG_CMDLINE="console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp" -CONFIG_CMDLINE_FORCE=y +CONFIG_VFP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_SUSPEND is not set CONFIG_PM_RUNTIME=y CONFIG_NET=y +CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y @@ -44,8 +44,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -82,6 +80,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_I2C=y CONFIG_I2C_RCAR=y +CONFIG_REGULATOR=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y @@ -108,11 +107,12 @@ CONFIG_MMC_SDHI=y CONFIG_MMC_SH_MMCIF=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RX8581=y +CONFIG_DMADEVICES=y +CONFIG_RCAR_HPB_DMAE=y CONFIG_UIO=y CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_IOMMU_SUPPORT is not set # CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY_USER is not set CONFIG_TMPFS=y # CONFIG_MISC_FILESYSTEMS is not set CONFIG_NFS_FS=y diff --git a/arch/arm/configs/efm32_defconfig b/arch/arm/configs/efm32_defconfig new file mode 100644 index 000000000000..f59fffb3d0c6 --- /dev/null +++ b/arch/arm/configs/efm32_defconfig @@ -0,0 +1,102 @@ +CONFIG_HIGH_RES_TIMERS=y +CONFIG_LOG_BUF_SHIFT=12 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_UID16 is not set +# CONFIG_BASE_FULL is not set +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +# CONFIG_SIGNALFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_MMU is not set +CONFIG_ARCH_EFM32=y +# CONFIG_KUSER_HELPERS is not set +CONFIG_SET_MEM_PARAM=y +CONFIG_DRAM_BASE=0x88000000 +CONFIG_DRAM_SIZE=0x00400000 +CONFIG_FLASH_MEM_BASE=0x8c000000 +CONFIG_FLASH_SIZE=0x01000000 +CONFIG_PREEMPT=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_XIP_KERNEL=y +CONFIG_XIP_PHYS_ADDR=0x8c000000 +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_SHARED_FLAT=y +# CONFIG_COREDUMP is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_FW_LOADER is not set +CONFIG_MTD=y +CONFIG_MTD_BLOCK_RO=y +CONFIG_MTD_ROM=y +CONFIG_MTD_UCLINUX=y +CONFIG_PROC_DEVICETREE=y +# CONFIG_BLK_DEV is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +CONFIG_KS8851=y +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_UNIX98_PTYS is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_EFM32_UART=y +CONFIG_SERIAL_EFM32_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_SPI=y +CONFIG_SPI_EFM32=y +CONFIG_GPIO_SYSFS=y +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_SPI=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +# CONFIG_FILE_LOCKING is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY_USER is not set +CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_MTD=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_FTRACE is not set diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index ad7dfbbafa45..dbe1f1c47bb0 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -13,7 +13,7 @@ CONFIG_S3C24XX_PWM=y CONFIG_ARCH_EXYNOS5=y CONFIG_MACH_EXYNOS4_DT=y CONFIG_SMP=y -CONFIG_NR_CPUS=2 +CONFIG_NR_CPUS=8 CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_HIGHMEM=y @@ -79,6 +79,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_MAX8997=y CONFIG_REGULATOR_MAX77686=y +CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_TPS65090=y CONFIG_FB=y diff --git a/arch/arm/configs/genmai_defconfig b/arch/arm/configs/genmai_defconfig new file mode 100644 index 000000000000..aa0b704f48af --- /dev/null +++ b/arch/arm/configs/genmai_defconfig @@ -0,0 +1,116 @@ +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_ARCH_SHMOBILE_LEGACY=y +CONFIG_ARCH_R7S72100=y +CONFIG_MACH_GENMAI=y +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +CONFIG_ARM_ERRATA_430973=y +CONFIG_ARM_ERRATA_458693=y +CONFIG_ARM_ERRATA_460075=y +CONFIG_ARM_ERRATA_743622=y +CONFIG_ARM_ERRATA_754322=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ARM_APPENDED_DTB=y +CONFIG_KEXEC=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_PM_RUNTIME=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_NETDEVICES=y +# CONFIG_NET_CORE is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_SH_ETH=y +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=10 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C_SH_MOBILE=y +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_RCAR_THERMAL=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_DRM=y +CONFIG_DRM_RCAR_DU=y +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_SDHI=y +CONFIG_MMC_SH_MMCIF=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_RTC_CLASS=y +CONFIG_DMADEVICES=y +CONFIG_SH_DMAE=y +# CONFIG_IOMMU_SUPPORT is not set +# CONFIG_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ARM_UNWIND is not set +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set diff --git a/arch/arm/configs/hi3xxx_defconfig b/arch/arm/configs/hi3xxx_defconfig new file mode 100644 index 000000000000..f186bdfa2369 --- /dev/null +++ b/arch/arm/configs/hi3xxx_defconfig @@ -0,0 +1,56 @@ +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_LZMA=y +CONFIG_ARCH_HI3xxx=y +CONFIG_SMP=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_SPI=y +CONFIG_SPI_PL022=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_REGULATOR_GPIO=y +CONFIG_DRM=y +CONFIG_FB_SIMPLE=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MXC=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_MMC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_PL031=y +CONFIG_DMADEVICES=y +CONFIG_DW_DMAC=y +CONFIG_PL330_DMA=y +CONFIG_PWM=y +CONFIG_EXT4_FS=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +CONFIG_LOCKUP_DETECTOR=y diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index e958ebe79779..6309ee52ccfc 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -91,6 +91,7 @@ CONFIG_SMSC911X=y CONFIG_SMSC_PHY=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_IMX=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y @@ -118,6 +119,7 @@ CONFIG_IMX2_WDT=y CONFIG_MFD_MC13XXX_SPI=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y CONFIG_MEDIA_SUPPORT=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 8d0c5a018ed7..53e82c2523eb 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -28,11 +28,13 @@ CONFIG_MACH_QONG=y CONFIG_MACH_ARMADILLO5X0=y CONFIG_MACH_KZM_ARM11_01=y CONFIG_MACH_IMX31_DT=y +CONFIG_MACH_IMX35_DT=y CONFIG_MACH_PCM043=y CONFIG_MACH_MX35_3DS=y CONFIG_MACH_VPR200=y CONFIG_MACH_IMX51_DT=y CONFIG_MACH_EUKREA_CPUIMX51SD=y +CONFIG_SOC_IMX50=y CONFIG_SOC_IMX53=y CONFIG_SOC_IMX6Q=y CONFIG_SOC_IMX6SL=y @@ -41,7 +43,7 @@ CONFIG_SMP=y CONFIG_VMSPLIT_2G=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set +CONFIG_HIGHMEM=y CONFIG_CMDLINE="noinitrd console=ttymxc0,115200" CONFIG_VFP=y CONFIG_NEON=y @@ -89,7 +91,6 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_SRAM=y CONFIG_EEPROM_AT24=y CONFIG_EEPROM_AT25=y # CONFIG_SCSI_PROC_FS is not set @@ -118,6 +119,7 @@ CONFIG_SMC91X=y CONFIG_SMC911X=y CONFIG_SMSC911X=y # CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_AT803X_PHY=y CONFIG_BRCMFMAC=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y @@ -129,6 +131,8 @@ CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_EGALAX=y CONFIG_TOUCHSCREEN_MC13783=y +CONFIG_TOUCHSCREEN_TSC2007=y +CONFIG_TOUCHSCREEN_STMPE=y CONFIG_INPUT_MISC=y CONFIG_INPUT_MMA8450=y CONFIG_SERIO_SERPORT=m @@ -156,14 +160,19 @@ CONFIG_IMX2_WDT=y CONFIG_MFD_DA9052_I2C=y CONFIG_MFD_MC13XXX_SPI=y CONFIG_MFD_MC13XXX_I2C=y +CONFIG_MFD_STMPE=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_ANATOP=y CONFIG_REGULATOR_DA9052=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y +CONFIG_REGULATOR_PFUZE100=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_DEVICES=y +CONFIG_IR_GPIO_CIR=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_SOC_CAMERA=y CONFIG_VIDEO_MX3=y diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 9943e5da74f1..a0182447d133 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig @@ -115,6 +115,8 @@ CONFIG_MTD_UBI=y CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_EEPROM_AT24=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y @@ -129,10 +131,24 @@ CONFIG_SPI_DAVINCI=y CONFIG_SPI_SPIDEV=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y -# CONFIG_USB_SUPPORT is not set +CONFIG_USB=y +CONFIG_USB_DEBUG=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_MON=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_DEBUG=y +CONFIG_USB_DWC3_VERBOSE=y +CONFIG_KEYSTONE_USB_PHY=y CONFIG_DMADEVICES=y CONFIG_COMMON_CLK_DEBUG=y CONFIG_MEMORY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_NTFS_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_WBUF_VERIFY=y @@ -144,6 +160,8 @@ CONFIG_ROOT_NFS=y CONFIG_NFSD=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_SHIRQ=y CONFIG_DEBUG_INFO=y diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig index 0ae0eaebf6b2..2e762d94e94b 100644 --- a/arch/arm/configs/kirkwood_defconfig +++ b/arch/arm/configs/kirkwood_defconfig @@ -27,6 +27,7 @@ CONFIG_PCI_MVEBU=y CONFIG_PREEMPT=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set +CONFIG_HIGHMEM=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CPU_FREQ=y diff --git a/arch/arm/configs/koelsch_defconfig b/arch/arm/configs/koelsch_defconfig index 825c16dee8a0..e248f49d5549 100644 --- a/arch/arm/configs/koelsch_defconfig +++ b/arch/arm/configs/koelsch_defconfig @@ -9,7 +9,7 @@ CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y CONFIG_SLAB=y # CONFIG_BLOCK is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A7791=y CONFIG_MACH_KOELSCH=y # CONFIG_SWP_EMULATE is not set @@ -29,7 +29,29 @@ CONFIG_VFP=y CONFIG_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_PM_RUNTIME=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +CONFIG_SH_ETH=y +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_LEGACY_PTYS is not set @@ -45,10 +67,11 @@ CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y # CONFIG_IOMMU_SUPPORT is not set # CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY_USER is not set CONFIG_TMPFS=y CONFIG_CONFIGFS_FS=y # CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_ARM_UNWIND is not set diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig index 6c37f4a98eb8..e42ce3756af3 100644 --- a/arch/arm/configs/kzm9d_defconfig +++ b/arch/arm/configs/kzm9d_defconfig @@ -13,7 +13,7 @@ CONFIG_SLAB=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_EMEV2=y CONFIG_MACH_KZM9D=y CONFIG_MEMORY_START=0x40000000 @@ -32,6 +32,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y +CONFIG_AUTO_ZRELADDR=y CONFIG_VFP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_PM_RUNTIME=y diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig index 1ad028023a64..9934dbc23d64 100644 --- a/arch/arm/configs/kzm9g_defconfig +++ b/arch/arm/configs/kzm9g_defconfig @@ -22,7 +22,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_SH73A0=y CONFIG_MACH_KZM9G=y CONFIG_MEMORY_START=0x41000000 diff --git a/arch/arm/configs/lager_defconfig b/arch/arm/configs/lager_defconfig index 35bff5e0d57a..883443f8f4f3 100644 --- a/arch/arm/configs/lager_defconfig +++ b/arch/arm/configs/lager_defconfig @@ -12,7 +12,7 @@ CONFIG_SLAB=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A7790=y CONFIG_MACH_LAGER=y # CONFIG_SH_TIMER_TMU is not set @@ -80,7 +80,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y CONFIG_I2C_GPIO=y -CONFIG_I2C_SH_MOBILE=y +CONFIG_I2C_RCAR=y CONFIG_GPIO_SH_PFC=y CONFIG_GPIOLIB=y CONFIG_GPIO_RCAR=y @@ -89,6 +89,7 @@ CONFIG_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_GPIO=y CONFIG_DRM=y CONFIG_DRM_RCAR_DU=y # CONFIG_USB_SUPPORT is not set diff --git a/arch/arm/configs/mackerel_defconfig b/arch/arm/configs/mackerel_defconfig index 9fb11895b2e2..a61e1653fc5e 100644 --- a/arch/arm/configs/mackerel_defconfig +++ b/arch/arm/configs/mackerel_defconfig @@ -14,7 +14,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_SH7372=y CONFIG_MACH_MACKEREL=y CONFIG_MEMORY_SIZE=0x10000000 diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig index 5cc6360340b1..f21bd405cc2a 100644 --- a/arch/arm/configs/marzen_defconfig +++ b/arch/arm/configs/marzen_defconfig @@ -9,7 +9,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_EMBEDDED=y CONFIG_SLAB=y # CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_SHMOBILE=y +CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A7779=y CONFIG_MACH_MARZEN=y CONFIG_MEMORY_START=0x60000000 @@ -30,12 +30,12 @@ CONFIG_HIGHMEM=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y -CONFIG_CMDLINE="console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel root=/dev/nfs ip=on" -CONFIG_CMDLINE_FORCE=y +CONFIG_VFP=y CONFIG_KEXEC=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_PM_RUNTIME=y CONFIG_NET=y +CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y @@ -43,8 +43,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set @@ -61,7 +59,6 @@ CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set # CONFIG_NET_VENDOR_SEEQ is not set -CONFIG_SMC911X=y CONFIG_SMSC911X=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_WLAN is not set @@ -106,11 +103,12 @@ CONFIG_USB_STORAGE=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y +CONFIG_DMADEVICES=y +CONFIG_RCAR_HPB_DMAE=y CONFIG_UIO=y CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_IOMMU_SUPPORT is not set # CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY_USER is not set CONFIG_TMPFS=y # CONFIG_MISC_FILESYSTEMS is not set CONFIG_NFS_FS=y diff --git a/arch/arm/configs/moxart_defconfig b/arch/arm/configs/moxart_defconfig new file mode 100644 index 000000000000..a3cb76cfb828 --- /dev/null +++ b/arch/arm/configs/moxart_defconfig @@ -0,0 +1,149 @@ +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set +# CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set +# CONFIG_EVENTFD is not set +# CONFIG_AIO is not set +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +CONFIG_ARCH_MULTI_V4T=y +# CONFIG_ARCH_MULTI_V7 is not set +CONFIG_KEYBOARD_GPIO_POLLED=y +CONFIG_ARCH_MOXART=y +CONFIG_MACH_UC7112LX=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +# CONFIG_ATAGS is not set +CONFIG_ARM_APPENDED_DTB=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FW_LOADER is not set +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_PROC_DEVICETREE=y +CONFIG_NETDEVICES=y +CONFIG_NETCONSOLE=y +CONFIG_NETCONSOLE_DYNAMIC=y +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +CONFIG_ARM_MOXART_ETHER=y +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_REALTEK_PHY=y +CONFIG_MDIO_MOXART=y +# CONFIG_WLAN is not set +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_EVBUG=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=1 +CONFIG_SERIAL_8250_RUNTIME_UARTS=1 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_MOXART=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +# CONFIG_HWMON is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_MOXART_WDT=y +# CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_SDHCI_MOXART=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_MOXART=y +CONFIG_DMADEVICES=y +CONFIG_MOXART_DMA=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT3_FS=y +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +CONFIG_JFFS2_FS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_PROVE_LOCKING=y +CONFIG_DMA_API_DEBUG=y +CONFIG_KGDB=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_UART_8250=y +CONFIG_DEBUG_UART_PHYS=0x98200000 +CONFIG_DEBUG_UART_VIRT=0xf9820000 +CONFIG_EARLY_PRINTK=y +CONFIG_KEYS=y +CONFIG_CRC32_BIT=y diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig index 690b5f9c7462..0219c65cefd5 100644 --- a/arch/arm/configs/msm_defconfig +++ b/arch/arm/configs/msm_defconfig @@ -17,9 +17,10 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y -CONFIG_ARCH_MSM=y +CONFIG_ARCH_MSM_DT=y CONFIG_ARCH_MSM8X60=y CONFIG_ARCH_MSM8960=y +CONFIG_ARCH_MSM8974=y CONFIG_SMP=y CONFIG_PREEMPT=y CONFIG_AEABI=y @@ -29,7 +30,6 @@ CONFIG_CLEANCACHE=y CONFIG_CC_STACKPROTECTOR=y CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_AUTO_ZRELADDR=y CONFIG_VFP=y CONFIG_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set @@ -62,7 +62,6 @@ CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_NETDEVICES=y CONFIG_DUMMY=y -CONFIG_PHYLIB=y CONFIG_SLIP=y CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_MODE_SLIP6=y @@ -81,13 +80,15 @@ CONFIG_SERIO_LIBPS2=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_MSM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_SPI=y -CONFIG_SSBI=y CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_MSM=y CONFIG_THERMAL=y CONFIG_REGULATOR=y CONFIG_MEDIA_SUPPORT=y @@ -101,7 +102,6 @@ CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SOC=y CONFIG_HID_BATTERY_STRENGTH=y CONFIG_USB=y -CONFIG_USB_PHY=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y @@ -128,10 +128,10 @@ CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_CIFS=y CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOCKUP_DETECTOR=y # CONFIG_DETECT_HUNG_TASK is not set # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y -CONFIG_DEBUG_INFO=y -CONFIG_DYNAMIC_DEBUG=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index c1df4e9db140..687e4e811b2a 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -7,8 +7,12 @@ CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_XP=y CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM_MOBILE=y +CONFIG_ARCH_BERLIN=y +CONFIG_MACH_BERLIN_BG2=y +CONFIG_MACH_BERLIN_BG2CD=y CONFIG_GPIO_PCA953X=y CONFIG_ARCH_HIGHBANK=y +CONFIG_ARCH_HI3xxx=y CONFIG_ARCH_KEYSTONE=y CONFIG_ARCH_MXC=y CONFIG_MACH_IMX51_DT=y @@ -68,6 +72,7 @@ CONFIG_NET_CALXEDA_XGMAC=y CONFIG_KS8851=y CONFIG_SMSC911X=y CONFIG_STMMAC_ETH=y +CONFIG_ICPLUS_PHY=y CONFIG_MDIO_SUN4I=y CONFIG_TI_CPSW=y CONFIG_KEYBOARD_SPEAR=y @@ -91,6 +96,8 @@ CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_SERIAL_FSL_LPUART=y CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_ST_ASC=y +CONFIG_SERIAL_ST_ASC_CONSOLE=y CONFIG_I2C_DESIGNWARE_PLATFORM=y CONFIG_I2C_SIRF=y CONFIG_I2C_TEGRA=y diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index 594d706b641f..0f4511d2849f 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -55,6 +55,8 @@ CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_PXA3xx=y CONFIG_SERIAL_8250_DW=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -69,6 +71,7 @@ CONFIG_USB_XHCI_HCD=y CONFIG_MMC=y CONFIG_MMC_MVSDIO=y CONFIG_NEW_LEDS=y +CONFIG_LEDS_GPIO=y CONFIG_LEDS_CLASS=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index bfa80a11e8c7..3a0b53d225e7 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -208,6 +208,8 @@ CONFIG_SND_DEBUG=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_SOC=m CONFIG_SND_OMAP_SOC=m +CONFIG_SND_AM33XX_SOC_EVM=m +CONFIG_SND_DAVINCI_SOC=m CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m @@ -222,6 +224,7 @@ CONFIG_USB_TEST=y CONFIG_NOP_USB_XCEIV=y CONFIG_OMAP_USB2=y CONFIG_OMAP_USB3=y +CONFIG_AM335X_PHY_USB=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y CONFIG_USB_GADGET_DEBUG_FILES=y diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index f6e78f83c3c3..dc3881e07630 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig @@ -20,7 +20,6 @@ CONFIG_ARCH_AT91=y CONFIG_SOC_SAM_V7=y CONFIG_SOC_SAMA5D3=y CONFIG_MACH_SAMA5_DT=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set CONFIG_UACCESS_WITH_MEMCPY=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index 4934295bb4f0..5fdc9a09d339 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -33,11 +33,12 @@ CONFIG_PCI=y CONFIG_PCI_MSI=y CONFIG_PCI_TEGRA=y CONFIG_PCIEPORTBUS=y +CONFIG_TRUSTED_FOUNDATIONS=y CONFIG_SMP=y CONFIG_PREEMPT=y CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set CONFIG_HIGHMEM=y +CONFIG_CMA=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_KEXEC=y @@ -63,7 +64,6 @@ CONFIG_INET_ESP=y # CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set CONFIG_IPV6=y -CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_INET6_AH=y @@ -85,7 +85,6 @@ CONFIG_RFKILL_GPIO=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FIRMWARE_IN_KERNEL is not set -CONFIG_CMA=y CONFIG_DMA_CMA=y CONFIG_MTD=y CONFIG_MTD_M25P80=y @@ -114,6 +113,7 @@ CONFIG_RT2800USB=m CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_TEGRA=y +CONFIG_KEYBOARD_CROS_EC=y CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_INPUT_MISC=y CONFIG_INPUT_MPU3050=y @@ -132,6 +132,7 @@ CONFIG_SPI=y CONFIG_SPI_TEGRA114=y CONFIG_SPI_TEGRA20_SFLASH=y CONFIG_SPI_TEGRA20_SLINK=y +CONFIG_PINCTRL_AS3722=y CONFIG_PINCTRL_PALMAS=y CONFIG_GPIO_PCA953X_IRQ=y CONFIG_GPIO_PALMAS=y @@ -143,6 +144,9 @@ CONFIG_CHARGER_TPS65090=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_GPIO=y CONFIG_SENSORS_LM90=y +CONFIG_MFD_AS3722=y +CONFIG_MFD_CROS_EC=y +CONFIG_MFD_CROS_EC_SPI=y CONFIG_MFD_MAX8907=y CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65090=y @@ -151,6 +155,7 @@ CONFIG_MFD_TPS65910=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_REGULATOR_AS3722=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_MAX8907=y CONFIG_REGULATOR_PALMAS=y @@ -164,7 +169,8 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_DRM=y -CONFIG_TEGRA_HOST1X=y +CONFIG_DRM_PANEL=y +CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_TEGRA=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set @@ -187,6 +193,7 @@ CONFIG_SND_SOC_TEGRA_WM8753=y CONFIG_SND_SOC_TEGRA_WM8903=y CONFIG_SND_SOC_TEGRA_TRIMSLICE=y CONFIG_SND_SOC_TEGRA_ALC5632=y +CONFIG_SND_SOC_TEGRA_MAX98090=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y @@ -211,6 +218,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_TRANSIENT=y CONFIG_LEDS_TRIGGER_CAMERA=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AS3722=y CONFIG_RTC_DRV_MAX8907=y CONFIG_RTC_DRV_PALMAS=y CONFIG_RTC_DRV_TPS6586X=y @@ -256,16 +264,15 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_FS=y +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_VM=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y -CONFIG_DEBUG_SLAB=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_VM=y CONFIG_DEBUG_SG=y CONFIG_DEBUG_LL=y CONFIG_EARLY_PRINTK=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index c6ebc184bf68..65f77885c167 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -119,6 +119,7 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y +CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 2ba9e63d0f17..073541a50e23 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -1,5 +1,3 @@ -CONFIG_ARCH_VERSATILE=y -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 @@ -7,15 +5,16 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_VERSATILE=y CONFIG_MACH_VERSATILE_AB=y -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=1f03 mem=32M" CONFIG_FPE_NWFPE=y CONFIG_VFP=y -CONFIG_PM=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -26,9 +25,7 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -37,10 +34,10 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y CONFIG_EEPROM_LEGACY=m CONFIG_NETDEVICES=y -CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_AMBAKMI=y +CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=m CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y @@ -48,15 +45,14 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_LEGACY_PTY_COUNT=16 CONFIG_I2C=y CONFIG_I2C_CHARDEV=m +CONFIG_GPIOLIB=y +CONFIG_GPIO_PL061=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_FONT_ACORN_8x8=y CONFIG_SOUND=y CONFIG_SND=m CONFIG_SND_MIXER_OSS=m @@ -64,6 +60,9 @@ CONFIG_SND_PCM_OSS=m CONFIG_SND_ARMAACI=m CONFIG_MMC=y CONFIG_MMC_ARMMMCI=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y CONFIG_EXT2_FS=y CONFIG_VFAT_FS=m CONFIG_JFFS2_FS=y @@ -71,15 +70,14 @@ CONFIG_CRAMFS=y CONFIG_MINIX_FS=y CONFIG_ROMFS_FS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_NFSD=y CONFIG_NFSD_V3=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_850=m CONFIG_NLS_ISO8859_1=m CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_USER=y -CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y +CONFIG_FONTS=y +CONFIG_FONT_ACORN_8x8=y diff --git a/arch/arm/crypto/aesbs-core.S_shipped b/arch/arm/crypto/aesbs-core.S_shipped index 64205d453260..71e5fc7cfb18 100644 --- a/arch/arm/crypto/aesbs-core.S_shipped +++ b/arch/arm/crypto/aesbs-core.S_shipped @@ -58,7 +58,7 @@ # define VFP_ABI_FRAME 0 # define BSAES_ASM_EXTENDED_KEY # define XTS_CHAIN_TWEAK -# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_ARCH__ 7 #endif #ifdef __thumb__ diff --git a/arch/arm/crypto/bsaes-armv7.pl b/arch/arm/crypto/bsaes-armv7.pl index f3d96d932573..be068db960ee 100644 --- a/arch/arm/crypto/bsaes-armv7.pl +++ b/arch/arm/crypto/bsaes-armv7.pl @@ -701,7 +701,7 @@ $code.=<<___; # define VFP_ABI_FRAME 0 # define BSAES_ASM_EXTENDED_KEY # define XTS_CHAIN_TWEAK -# define __ARM_ARCH__ __LINUX_ARM_ARCH__ +# define __ARM_ARCH__ 7 #endif #ifdef __thumb__ diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig new file mode 100644 index 000000000000..bb00ccf00d66 --- /dev/null +++ b/arch/arm/firmware/Kconfig @@ -0,0 +1,28 @@ +config ARCH_SUPPORTS_FIRMWARE + bool + +config ARCH_SUPPORTS_TRUSTED_FOUNDATIONS + bool + select ARCH_SUPPORTS_FIRMWARE + +menu "Firmware options" + depends on ARCH_SUPPORTS_FIRMWARE + +config TRUSTED_FOUNDATIONS + bool "Trusted Foundations secure monitor support" + depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS + help + Some devices (including most Tegra-based consumer devices on the + market) are booted with the Trusted Foundations secure monitor + active, requiring some core operations to be performed by the secure + monitor instead of the kernel. + + This option allows the kernel to invoke the secure monitor whenever + required on devices using Trusted Foundations. See + arch/arm/include/asm/trusted_foundations.h or the + tl,trusted-foundations device tree binding documentation for details + on how to use it. + + Say n if you don't know what this is about. + +endmenu diff --git a/arch/arm/firmware/Makefile b/arch/arm/firmware/Makefile new file mode 100644 index 000000000000..a71f16536b6c --- /dev/null +++ b/arch/arm/firmware/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c new file mode 100644 index 000000000000..ef1e3d8f4af0 --- /dev/null +++ b/arch/arm/firmware/trusted_foundations.c @@ -0,0 +1,81 @@ +/* + * Trusted Foundations support for ARM CPUs + * + * Copyright (c) 2013, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include + +#define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200 + +static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2) +{ + asm volatile( + ".arch_extension sec\n\t" + "stmfd sp!, {r4 - r11, lr}\n\t" + __asmeq("%0", "r0") + __asmeq("%1", "r1") + __asmeq("%2", "r2") + "mov r3, #0\n\t" + "mov r4, #0\n\t" + "smc #0\n\t" + "ldmfd sp!, {r4 - r11, pc}" + : + : "r" (type), "r" (arg1), "r" (arg2) + : "memory"); +} + +static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr) +{ + tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, boot_addr, 0); + + return 0; +} + +static const struct firmware_ops trusted_foundations_ops = { + .set_cpu_boot_addr = tf_set_cpu_boot_addr, +}; + +void register_trusted_foundations(struct trusted_foundations_platform_data *pd) +{ + /* + * we are not using version information for now since currently + * supported SMCs are compatible with all TF releases + */ + register_firmware_ops(&trusted_foundations_ops); +} + +void of_register_trusted_foundations(void) +{ + struct device_node *node; + struct trusted_foundations_platform_data pdata; + int err; + + node = of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations"); + if (!node) + return; + + err = of_property_read_u32(node, "tlm,version-major", + &pdata.version_major); + if (err != 0) + panic("Trusted Foundation: missing version-major property\n"); + err = of_property_read_u32(node, "tlm,version-minor", + &pdata.version_minor); + if (err != 0) + panic("Trusted Foundation: missing version-minor property\n"); + register_trusted_foundations(&pdata); +} diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index c38b58c80202..3278afe2c3ab 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -34,3 +34,4 @@ generic-y += timex.h generic-y += trace_clock.h generic-y += unaligned.h generic-y += preempt.h +generic-y += hash.h diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h index 60f15e274e6d..2f59f7443396 100644 --- a/arch/arm/include/asm/barrier.h +++ b/arch/arm/include/asm/barrier.h @@ -59,6 +59,21 @@ #define smp_wmb() dmb(ishst) #endif +#define smp_store_release(p, v) \ +do { \ + compiletime_assert_atomic_type(*p); \ + smp_mb(); \ + ACCESS_ONCE(*p) = (v); \ +} while (0) + +#define smp_load_acquire(p) \ +({ \ + typeof(*p) ___p1 = ACCESS_ONCE(*p); \ + compiletime_assert_atomic_type(*p); \ + smp_mb(); \ + ___p1; \ +}) + #define read_barrier_depends() do { } while(0) #define smp_read_barrier_depends() do { } while(0) diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index e691ec91e4d3..b2e298a90d76 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -254,25 +254,59 @@ static inline int constant_fls(int x) } /* - * On ARMv5 and above those functions can be implemented around - * the clz instruction for much better code efficiency. + * On ARMv5 and above those functions can be implemented around the + * clz instruction for much better code efficiency. __clz returns + * the number of leading zeros, zero input will return 32, and + * 0x80000000 will return 0. */ - -static inline int fls(int x) +static inline unsigned int __clz(unsigned int x) { - int ret; - - if (__builtin_constant_p(x)) - return constant_fls(x); + unsigned int ret; asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); - ret = 32 - ret; + return ret; } -#define __fls(x) (fls(x) - 1) -#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) -#define __ffs(x) (ffs(x) - 1) +/* + * fls() returns zero if the input is zero, otherwise returns the bit + * position of the last set bit, where the LSB is 1 and MSB is 32. + */ +static inline int fls(int x) +{ + if (__builtin_constant_p(x)) + return constant_fls(x); + + return 32 - __clz(x); +} + +/* + * __fls() returns the bit position of the last bit set, where the + * LSB is 0 and MSB is 31. Zero input is undefined. + */ +static inline unsigned long __fls(unsigned long x) +{ + return fls(x) - 1; +} + +/* + * ffs() returns zero if the input was zero, otherwise returns the bit + * position of the first set bit, where the LSB is 1 and MSB is 32. + */ +static inline int ffs(int x) +{ + return fls(x & -x); +} + +/* + * __ffs() returns the bit position of the first bit set, where the + * LSB is 0 and MSB is 31. Zero input is undefined. + */ +static inline unsigned long __ffs(unsigned long x) +{ + return ffs(x) - 1; +} + #define ffz(x) __ffs( ~(x) ) #endif diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index ee753f1749cd..e9a49fe0284e 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -481,4 +481,9 @@ static inline void __sync_cache_range_r(volatile void *p, size_t size) : : : "r0","r1","r2","r3","r4","r5","r6","r7", \ "r9","r10","lr","memory" ) +int set_memory_ro(unsigned long addr, int numpages); +int set_memory_rw(unsigned long addr, int numpages); +int set_memory_x(unsigned long addr, int numpages); +int set_memory_nx(unsigned long addr, int numpages); + #endif diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index 6dcc16430868..523315115478 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h @@ -87,19 +87,33 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) { - __asm__( - "adds %0, %1, %2 @ csum_tcpudp_nofold \n\ - adcs %0, %0, %3 \n" + u32 lenprot = len | proto << 16; + if (__builtin_constant_p(sum) && sum == 0) { + __asm__( + "adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t" #ifdef __ARMEB__ - "adcs %0, %0, %4 \n" + "adcs %0, %0, %3 \n\t" #else - "adcs %0, %0, %4, lsl #8 \n" + "adcs %0, %0, %3, ror #8 \n\t" #endif - "adcs %0, %0, %5 \n\ - adc %0, %0, #0" - : "=&r"(sum) - : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) - : "cc"); + "adc %0, %0, #0" + : "=&r" (sum) + : "r" (daddr), "r" (saddr), "r" (lenprot) + : "cc"); + } else { + __asm__( + "adds %0, %1, %2 @ csum_tcpudp_nofold \n\t" + "adcs %0, %0, %3 \n\t" +#ifdef __ARMEB__ + "adcs %0, %0, %4 \n\t" +#else + "adcs %0, %0, %4, ror #8 \n\t" +#endif + "adc %0, %0, #0" + : "=&r"(sum) + : "r" (sum), "r" (daddr), "r" (saddr), "r" (lenprot) + : "cc"); + } return sum; } /* diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h index 80751c15c300..4e8a4b27d7c7 100644 --- a/arch/arm/include/asm/clkdev.h +++ b/arch/arm/include/asm/clkdev.h @@ -14,12 +14,14 @@ #include +#ifndef CONFIG_COMMON_CLK #ifdef CONFIG_HAVE_MACH_CLKDEV #include #else #define __clk_get(clk) ({ 1; }) #define __clk_put(clk) do { } while (0) #endif +#endif static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) { diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 58b8c6a0ab1f..99084431d6ae 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -8,8 +8,8 @@ #define MAX_DMA_ADDRESS 0xffffffffUL #else #define MAX_DMA_ADDRESS ({ \ - extern unsigned long arm_dma_zone_size; \ - arm_dma_zone_size ? \ + extern phys_addr_t arm_dma_zone_size; \ + arm_dma_zone_size && arm_dma_zone_size < (0x10000000 - PAGE_OFFSET) ? \ (PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; }) #endif diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 3b2c40b5bfa2..6795ff743b3d 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -131,6 +131,7 @@ struct l2x0_regs { unsigned long prefetch_ctrl; unsigned long pwr_ctrl; unsigned long ctrl; + unsigned long aux2_ctrl; }; extern struct l2x0_regs l2x0_saved_regs; diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 3c597c222ef2..fbeb39c869e9 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -329,7 +329,7 @@ extern void _memset_io(volatile void __iomem *, int, size_t); */ #define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) #define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE) -#define ioremap_cached(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED) +#define ioremap_cache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED) #define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC) #define iounmap __arm_iounmap diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 8a6f6db14ee4..098f7dd6d564 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -225,4 +225,7 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext) int kvm_perf_init(void); int kvm_perf_teardown(void); +u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid); +int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value); + #endif /* __ARM_KVM_HOST_H__ */ diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h index 77de4a41cc50..2d122adcdb22 100644 --- a/arch/arm/include/asm/kvm_mmu.h +++ b/arch/arm/include/asm/kvm_mmu.h @@ -140,6 +140,7 @@ static inline void coherent_icache_guest_page(struct kvm *kvm, hva_t hva, } #define kvm_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l)) +#define kvm_virt_to_phys(x) virt_to_idmap((unsigned long)(x)) #endif /* !__ASSEMBLY__ */ diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index 2fe141fcc8d6..f98c7f32c9c8 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h @@ -22,18 +22,21 @@ struct map_desc { }; /* types 0-3 are defined in asm/io.h */ -#define MT_UNCACHED 4 -#define MT_CACHECLEAN 5 -#define MT_MINICLEAN 6 -#define MT_LOW_VECTORS 7 -#define MT_HIGH_VECTORS 8 -#define MT_MEMORY 9 -#define MT_ROM 10 -#define MT_MEMORY_NONCACHED 11 -#define MT_MEMORY_DTCM 12 -#define MT_MEMORY_ITCM 13 -#define MT_MEMORY_SO 14 -#define MT_MEMORY_DMA_READY 15 +enum { + MT_UNCACHED = 4, + MT_CACHECLEAN, + MT_MINICLEAN, + MT_LOW_VECTORS, + MT_HIGH_VECTORS, + MT_MEMORY_RWX, + MT_MEMORY_RW, + MT_ROM, + MT_MEMORY_RWX_NONCACHED, + MT_MEMORY_RW_DTCM, + MT_MEMORY_RWX_ITCM, + MT_MEMORY_RW_SO, + MT_MEMORY_DMA_READY, +}; #ifdef CONFIG_MMU extern void iotable_init(struct map_desc *, int); diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 6976b03e5213..8756e4bcdba0 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -347,7 +347,8 @@ static inline __deprecated void *bus_to_virt(unsigned long x) #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) +#define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \ + && pfn_valid(__pa(kaddr) >> PAGE_SHIFT) ) #endif diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index a98a2e112fae..680a83e94467 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -57,12 +57,9 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); -/* - * Dummy implementation; always return 0. - */ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { - return 0; + return channel ? 15 : 14; } #endif /* __KERNEL__ */ diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index 86a659a19526..dfff709fda3c 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h @@ -160,6 +160,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) return (pmd_t *)pud; } +#define pmd_large(pmd) (pmd_val(pmd) & 2) #define pmd_bad(pmd) (pmd_val(pmd) & 2) #define copy_pmd(pmdpd,pmdps) \ diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 4f9503908dca..03243f7eeddf 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h @@ -142,6 +142,7 @@ PMD_TYPE_TABLE) #define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \ PMD_TYPE_SECT) +#define pmd_large(pmd) pmd_sect(pmd) #define pud_clear(pudp) \ do { \ diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 1571d126e9dd..7d59b524f2af 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -254,6 +254,8 @@ PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); +PTE_BIT_FUNC(mkexec, &= ~L_PTE_XN); +PTE_BIT_FUNC(mknexec, |= L_PTE_XN); static inline pte_t pte_mkspecial(pte_t pte) { return pte; } diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h new file mode 100644 index 000000000000..3bd36e2c5f2e --- /dev/null +++ b/arch/arm/include/asm/trusted_foundations.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +/* + * Support for the Trusted Foundations secure monitor. + * + * Trusted Foundation comes active on some ARM consumer devices (most + * Tegra-based devices sold on the market are concerned). Such devices can only + * perform some basic operations, like setting the CPU reset vector, through + * SMC calls to the secure monitor. The calls are completely specific to + * Trusted Foundations, and do *not* follow the SMC calling convention or the + * PSCI standard. + */ + +#ifndef __ASM_ARM_TRUSTED_FOUNDATIONS_H +#define __ASM_ARM_TRUSTED_FOUNDATIONS_H + +#include +#include +#include +#include + +struct trusted_foundations_platform_data { + unsigned int version_major; + unsigned int version_minor; +}; + +#if IS_ENABLED(CONFIG_TRUSTED_FOUNDATIONS) + +void register_trusted_foundations(struct trusted_foundations_platform_data *pd); +void of_register_trusted_foundations(void); + +#else /* CONFIG_TRUSTED_FOUNDATIONS */ + +static inline void register_trusted_foundations( + struct trusted_foundations_platform_data *pd) +{ + /* + * If we try to register TF, this means the system needs it to continue. + * Its absence if thus a fatal error. + */ + panic("No support for Trusted Foundations, stopping...\n"); +} + +static inline void of_register_trusted_foundations(void) +{ + /* + * If we find the target should enable TF but does not support it, + * fail as the system won't be able to do much anyway + */ + if (of_find_compatible_node(NULL, NULL, "tl,trusted-foundations")) + register_trusted_foundations(NULL); +} +#endif /* CONFIG_TRUSTED_FOUNDATIONS */ + +#endif diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 141baa3f9a72..acabef1a75df 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -15,7 +15,7 @@ #include -#define __NR_syscalls (380) +#define __NR_syscalls (384) #define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0) #define __ARCH_WANT_STAT64 diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h index 4d52f92967a6..a6d0a29861e7 100644 --- a/arch/arm/include/asm/word-at-a-time.h +++ b/arch/arm/include/asm/word-at-a-time.h @@ -48,10 +48,14 @@ static inline unsigned long find_zero(unsigned long mask) return ret; } -#ifdef CONFIG_DCACHE_WORD_ACCESS - #define zero_bytemask(mask) (mask) +#else /* __ARMEB__ */ +#include +#endif + +#ifdef CONFIG_DCACHE_WORD_ACCESS + /* * Load an unaligned word from kernel space. * @@ -73,7 +77,11 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) " bic %2, %2, #0x3\n" " ldr %0, [%2]\n" " lsl %1, %1, #0x3\n" +#ifndef __ARMEB__ " lsr %0, %0, %1\n" +#else + " lsl %0, %0, %1\n" +#endif " b 2b\n" " .popsection\n" " .pushsection __ex_table,\"a\"\n" @@ -86,11 +94,5 @@ static inline unsigned long load_unaligned_zeropad(const void *addr) return ret; } - #endif /* DCACHE_WORD_ACCESS */ - -#else /* __ARMEB__ */ -#include -#endif - #endif /* __ASM_ARM_WORD_AT_A_TIME_H */ diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h index 75579a9d6f76..e0965abacb7d 100644 --- a/arch/arm/include/asm/xen/page.h +++ b/arch/arm/include/asm/xen/page.h @@ -117,6 +117,7 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) return __set_phys_to_machine(pfn, mfn); } -#define xen_remap(cookie, size) ioremap_cached((cookie), (size)); +#define xen_remap(cookie, size) ioremap_cache((cookie), (size)) +#define xen_unmap(cookie) iounmap((cookie)) #endif /* _ASM_ARM_XEN_PAGE_H */ diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h index 29da84e183f4..42b823cd2d22 100644 --- a/arch/arm/include/debug/imx-uart.h +++ b/arch/arm/include/debug/imx-uart.h @@ -43,6 +43,14 @@ #define IMX35_UART_BASE_ADDR(n) IMX35_UART##n##_BASE_ADDR #define IMX35_UART_BASE(n) IMX35_UART_BASE_ADDR(n) +#define IMX50_UART1_BASE_ADDR 0x53fbc000 +#define IMX50_UART2_BASE_ADDR 0x53fc0000 +#define IMX50_UART3_BASE_ADDR 0x5000c000 +#define IMX50_UART4_BASE_ADDR 0x53ff0000 +#define IMX50_UART5_BASE_ADDR 0x63f90000 +#define IMX50_UART_BASE_ADDR(n) IMX50_UART##n##_BASE_ADDR +#define IMX50_UART_BASE(n) IMX50_UART_BASE_ADDR(n) + #define IMX51_UART1_BASE_ADDR 0x73fbc000 #define IMX51_UART2_BASE_ADDR 0x73fc0000 #define IMX51_UART3_BASE_ADDR 0x7000c000 @@ -85,6 +93,8 @@ #define UART_PADDR IMX_DEBUG_UART_BASE(IMX31) #elif defined(CONFIG_DEBUG_IMX35_UART) #define UART_PADDR IMX_DEBUG_UART_BASE(IMX35) +#elif defined(CONFIG_DEBUG_IMX50_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX50) #elif defined(CONFIG_DEBUG_IMX51_UART) #define UART_PADDR IMX_DEBUG_UART_BASE(IMX51) #elif defined(CONFIG_DEBUG_IMX53_UART) diff --git a/arch/arm/include/debug/tegra.S b/arch/arm/include/debug/tegra.S index be6a720dd183..f98763f0bc17 100644 --- a/arch/arm/include/debug/tegra.S +++ b/arch/arm/include/debug/tegra.S @@ -46,10 +46,10 @@ #define TEGRA_APB_MISC_GP_HIDREV (TEGRA_APB_MISC_BASE + 0x804) /* - * Must be 1MB-aligned since a 1MB mapping is used early on. + * Must be section-aligned since a section mapping is used early on. * Must not overlap with regions in mach-tegra/io.c:tegra_io_desc[]. */ -#define UART_VIRTUAL_BASE 0xfe100000 +#define UART_VIRTUAL_BASE 0xfe800000 #define checkuart(rp, rv, lhu, bit, uart) \ /* Load address of CLK_RST register */ \ @@ -156,28 +156,6 @@ 92: and \rv, \rp, #0xffffff @ offset within 1MB section add \rv, \rv, #UART_VIRTUAL_BASE str \rv, [\tmp, #8] @ Store in tegra_uart_virt - movw \rv, #TEGRA_APB_MISC_GP_HIDREV & 0xffff - movt \rv, #TEGRA_APB_MISC_GP_HIDREV >> 16 - ldr \rv, [\rv, #0] @ Load HIDREV - ubfx \rv, \rv, #8, #8 @ 15:8 are SoC version - cmp \rv, #0x20 @ Tegra20? - moveq \rv, #0x75 @ Tegra20 divisor - movne \rv, #0xdd @ Tegra30 divisor - str \rv, [\tmp, #12] @ Save divisor to scratch - /* uart[UART_LCR] = UART_LCR_WLEN8 | UART_LCR_DLAB; */ - mov \rv, #UART_LCR_WLEN8 | UART_LCR_DLAB - str \rv, [\rp, #UART_LCR << UART_SHIFT] - /* uart[UART_DLL] = div & 0xff; */ - ldr \rv, [\tmp, #12] - and \rv, \rv, #0xff - str \rv, [\rp, #UART_DLL << UART_SHIFT] - /* uart[UART_DLM] = div >> 8; */ - ldr \rv, [\tmp, #12] - lsr \rv, \rv, #8 - str \rv, [\rp, #UART_DLM << UART_SHIFT] - /* uart[UART_LCR] = UART_LCR_WLEN8; */ - mov \rv, #UART_LCR_WLEN8 - str \rv, [\rp, #UART_LCR << UART_SHIFT] b 100f .align @@ -205,8 +183,8 @@ cmp \rx, #0 beq 1002f 1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] - and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE - teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + and \rd, \rd, #UART_LSR_THRE + teq \rd, #UART_LSR_THRE bne 1001b 1002: .endm @@ -225,7 +203,7 @@ /* * Storage for the state maintained by the macros above. * - * In the kernel proper, this data is located in arch/arm/mach-tegra/common.c. + * In the kernel proper, this data is located in arch/arm/mach-tegra/tegra.c. * That's because this header is included from multiple files, and we only * want a single copy of the data. In particular, the UART probing code above * assumes it's running using physical addresses. This is true when this file @@ -247,6 +225,4 @@ tegra_uart_config: .word 0 /* Debug UART virtual address */ .word 0 - /* Scratch space for debug macro */ - .word 0 #endif diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index c498b60c0505..ef0c8785ba16 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -119,6 +119,26 @@ struct kvm_arch_memory_slot { #define KVM_REG_ARM_32_CRN_MASK 0x0000000000007800 #define KVM_REG_ARM_32_CRN_SHIFT 11 +#define ARM_CP15_REG_SHIFT_MASK(x,n) \ + (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK) + +#define __ARM_CP15_REG(op1,crn,crm,op2) \ + (KVM_REG_ARM | (15 << KVM_REG_ARM_COPROC_SHIFT) | \ + ARM_CP15_REG_SHIFT_MASK(op1, OPC1) | \ + ARM_CP15_REG_SHIFT_MASK(crn, 32_CRN) | \ + ARM_CP15_REG_SHIFT_MASK(crm, CRM) | \ + ARM_CP15_REG_SHIFT_MASK(op2, 32_OPC2)) + +#define ARM_CP15_REG32(...) (__ARM_CP15_REG(__VA_ARGS__) | KVM_REG_SIZE_U32) + +#define __ARM_CP15_REG64(op1,crm) \ + (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64) +#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__) + +#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1) +#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14) +#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14) + /* Normal registers are mapped as coprocessor 16. */ #define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT) #define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 4) @@ -143,6 +163,14 @@ struct kvm_arch_memory_slot { #define KVM_REG_ARM_VFP_FPINST 0x1009 #define KVM_REG_ARM_VFP_FPINST2 0x100A +/* Device Control API: ARM VGIC */ +#define KVM_DEV_ARM_VGIC_GRP_ADDR 0 +#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 +#define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2 +#define KVM_DEV_ARM_VGIC_CPUID_SHIFT 32 +#define KVM_DEV_ARM_VGIC_CPUID_MASK (0xffULL << KVM_DEV_ARM_VGIC_CPUID_SHIFT) +#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0 +#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index af33b44990ed..fb5584d0cc05 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -406,6 +406,8 @@ #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) #define __NR_kcmp (__NR_SYSCALL_BASE+378) #define __NR_finit_module (__NR_SYSCALL_BASE+379) +#define __NR_sched_setattr (__NR_SYSCALL_BASE+380) +#define __NR_sched_getattr (__NR_SYSCALL_BASE+381) /* * This may need to be greater than __NR_last_syscall+1 in order to diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 1f031ddd0667..85e664b6a5f1 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -35,6 +35,8 @@ extern void __ucmpdi2(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void __do_div64(void); +extern void __bswapsi2(void); +extern void __bswapdi2(void); extern void __aeabi_idiv(void); extern void __aeabi_idivmod(void); @@ -114,6 +116,8 @@ EXPORT_SYMBOL(__ucmpdi2); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(__do_div64); +EXPORT_SYMBOL(__bswapsi2); +EXPORT_SYMBOL(__bswapdi2); #ifdef CONFIG_AEABI EXPORT_SYMBOL(__aeabi_idiv); diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index c6ca7e376773..166e945de832 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -389,6 +389,8 @@ CALL(sys_process_vm_writev) CALL(sys_kcmp) CALL(sys_finit_module) +/* 380 */ CALL(sys_sched_setattr) + CALL(sys_sched_getattr) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index 739c3dfc1da2..f751714d52c1 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -33,7 +33,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) { - return alloc_bootmem_align(size, align); + return memblock_virt_alloc(size, align); } void __init arm_dt_memblock_reserve(void) @@ -171,7 +171,7 @@ void __init arm_dt_init_cpu_maps(void) bool arch_match_cpu_phys_id(int cpu, u64 phys_id) { - return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu); + return phys_id == cpu_logical_map(cpu); } static const void * __init arch_get_next_mach(const char *const **match) diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S index 52b26432c9a9..2260f1855820 100644 --- a/arch/arm/kernel/entry-v7m.S +++ b/arch/arm/kernel/entry-v7m.S @@ -14,8 +14,6 @@ #include #include -#include - #include "entry-header.S" #ifdef CONFIG_TRACE_IRQFLAGS diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 8ff0ecdc637f..131a6ab5f355 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -385,7 +385,6 @@ out: return ret; out_unmap: - amba_set_drvdata(dev, NULL); iounmap(t->etb_regs); out_release: @@ -398,8 +397,6 @@ static int etb_remove(struct amba_device *dev) { struct tracectx *t = amba_get_drvdata(dev); - amba_set_drvdata(dev, NULL); - iounmap(t->etb_regs); t->etb_regs = NULL; @@ -588,7 +585,6 @@ out: return ret; out_unmap: - amba_set_drvdata(dev, NULL); iounmap(t->etm_regs); out_release: @@ -601,8 +597,6 @@ static int etm_remove(struct amba_device *dev) { struct tracectx *t = amba_get_drvdata(dev); - amba_set_drvdata(dev, NULL); - iounmap(t->etm_regs); t->etm_regs = NULL; diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index bc3f2efa0d86..789d846a9184 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -99,10 +99,6 @@ int armpmu_event_set_period(struct perf_event *event) s64 period = hwc->sample_period; int ret = 0; - /* The period may have been changed by PERF_EVENT_IOC_PERIOD */ - if (unlikely(period != hwc->last_period)) - left = period - (hwc->last_period - left); - if (unlikely(left <= -period)) { left = period; local64_set(&hwc->period_left, left); diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c index d85055cd24ba..20d553c9f5e2 100644 --- a/arch/arm/kernel/perf_event_cpu.c +++ b/arch/arm/kernel/perf_event_cpu.c @@ -254,7 +254,7 @@ static int probe_current_pmu(struct arm_pmu *pmu) static int cpu_pmu_device_probe(struct platform_device *pdev) { const struct of_device_id *of_id; - int (*init_fn)(struct arm_pmu *); + const int (*init_fn)(struct arm_pmu *); struct device_node *node = pdev->dev.of_node; struct arm_pmu *pmu; int ret = -ENODEV; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 987a7f5bce5f..1e8b030dbefd 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -334,7 +334,7 @@ static void __init cacheid_init(void) cacheid = CACHEID_VIVT; } - printk("CPU: %s data cache, %s instruction cache\n", + pr_info("CPU: %s data cache, %s instruction cache\n", cache_is_vivt() ? "VIVT" : cache_is_vipt_aliasing() ? "VIPT aliasing" : cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown", @@ -416,7 +416,7 @@ void notrace cpu_init(void) struct stack *stk = &stacks[cpu]; if (cpu >= NR_CPUS) { - printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); + pr_crit("CPU%u: bad primary CPU number\n", cpu); BUG(); } @@ -484,7 +484,7 @@ void __init smp_setup_processor_id(void) */ set_my_cpu_offset(0); - printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr); + pr_info("Booting Linux on physical CPU 0x%x\n", mpidr); } struct mpidr_hash mpidr_hash; @@ -564,8 +564,8 @@ static void __init setup_processor(void) */ list = lookup_processor_type(read_cpuid_id()); if (!list) { - printk("CPU configuration botched (ID %08x), unable " - "to continue.\n", read_cpuid_id()); + pr_err("CPU configuration botched (ID %08x), unable to continue.\n", + read_cpuid_id()); while (1); } @@ -585,9 +585,9 @@ static void __init setup_processor(void) cpu_cache = *list->cache; #endif - printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", - cpu_name, read_cpuid_id(), read_cpuid_id() & 15, - proc_arch[cpu_architecture()], cr_alignment); + pr_info("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", + cpu_name, read_cpuid_id(), read_cpuid_id() & 15, + proc_arch[cpu_architecture()], cr_alignment); snprintf(init_utsname()->machine, __NEW_UTS_LEN + 1, "%s%c", list->arch_name, ENDIANNESS); @@ -629,8 +629,8 @@ int __init arm_add_memory(u64 start, u64 size) u64 aligned_start; if (meminfo.nr_banks >= NR_BANKS) { - printk(KERN_CRIT "NR_BANKS too low, " - "ignoring memory at 0x%08llx\n", (long long)start); + pr_crit("NR_BANKS too low, ignoring memory at 0x%08llx\n", + (long long)start); return -EINVAL; } @@ -643,14 +643,14 @@ int __init arm_add_memory(u64 start, u64 size) #ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT if (aligned_start > ULONG_MAX) { - printk(KERN_CRIT "Ignoring memory at 0x%08llx outside " - "32-bit physical address space\n", (long long)start); + pr_crit("Ignoring memory at 0x%08llx outside 32-bit physical address space\n", + (long long)start); return -EINVAL; } if (aligned_start + size > ULONG_MAX) { - printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " - "32-bit physical address space\n", (long long)start); + pr_crit("Truncating memory at 0x%08llx to fit in 32-bit physical address space\n", + (long long)start); /* * To ensure bank->start + bank->size is representable in * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. @@ -660,6 +660,20 @@ int __init arm_add_memory(u64 start, u64 size) } #endif + if (aligned_start < PHYS_OFFSET) { + if (aligned_start + size <= PHYS_OFFSET) { + pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n", + aligned_start, aligned_start + size); + return -EINVAL; + } + + pr_info("Ignoring memory below PHYS_OFFSET: 0x%08llx-0x%08llx\n", + aligned_start, (u64)PHYS_OFFSET); + + size -= PHYS_OFFSET - aligned_start; + aligned_start = PHYS_OFFSET; + } + bank->start = aligned_start; bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); @@ -717,7 +731,7 @@ static void __init request_standard_resources(const struct machine_desc *mdesc) kernel_data.end = virt_to_phys(_end - 1); for_each_memblock(memory, region) { - res = alloc_bootmem_low(sizeof(*res)); + res = memblock_virt_alloc(sizeof(*res), 0); res->name = "System RAM"; res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region)); res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1; @@ -817,18 +831,17 @@ static void __init reserve_crashkernel(void) if (ret) return; - ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE); + ret = memblock_reserve(crash_base, crash_size); if (ret < 0) { - printk(KERN_WARNING "crashkernel reservation failed - " - "memory is in use (0x%lx)\n", (unsigned long)crash_base); + pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n", + (unsigned long)crash_base); return; } - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(total_mem >> 20)); + pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n", + (unsigned long)(crash_size >> 20), + (unsigned long)(crash_base >> 20), + (unsigned long)(total_mem >> 20)); crashk_res.start = crash_base; crashk_res.end = crash_base + crash_size - 1; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index dc894ab3622b..b7b4c86e338b 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -105,8 +105,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) secondary_data.pgdir = get_arch_pgd(idmap_pgd); secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); #endif - __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); - outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); + sync_cache_w(&secondary_data); /* * Now bring the CPU into our world. @@ -294,6 +293,9 @@ void __ref cpu_die(void) if (smp_ops.cpu_die) smp_ops.cpu_die(cpu); + pr_warn("CPU%u: smp_ops.cpu_die() returned, trying to resuscitate\n", + cpu); + /* * Do not return to the idle loop - jump back to the secondary * cpu initialisation. There's some initialisation which needs diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index f50f19e5c138..7a3be1d4d0b1 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -52,7 +52,7 @@ static struct map_desc dtcm_iomap[] __initdata = { .virtual = DTCM_OFFSET, .pfn = __phys_to_pfn(DTCM_OFFSET), .length = 0, - .type = MT_MEMORY_DTCM + .type = MT_MEMORY_RW_DTCM } }; @@ -61,7 +61,7 @@ static struct map_desc itcm_iomap[] __initdata = { .virtual = ITCM_OFFSET, .pfn = __phys_to_pfn(ITCM_OFFSET), .length = 0, - .type = MT_MEMORY_ITCM + .type = MT_MEMORY_RWX_ITCM, } }; diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 85a87370f144..0bc94b1fd1ae 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -68,16 +68,16 @@ struct cpu_efficiency { * Processors that are not defined in the table, * use the default SCHED_POWER_SCALE value for cpu_scale. */ -struct cpu_efficiency table_efficiency[] = { +static const struct cpu_efficiency table_efficiency[] = { {"arm,cortex-a15", 3891}, {"arm,cortex-a7", 2048}, {NULL, }, }; -unsigned long *__cpu_capacity; +static unsigned long *__cpu_capacity; #define cpu_capacity(cpu) __cpu_capacity[cpu] -unsigned long middle_capacity = 1; +static unsigned long middle_capacity = 1; /* * Iterate all CPUs' descriptor in DT and compute the efficiency @@ -89,7 +89,7 @@ unsigned long middle_capacity = 1; */ static void __init parse_dt_topology(void) { - struct cpu_efficiency *cpu_eff; + const struct cpu_efficiency *cpu_eff; struct device_node *cn = NULL; unsigned long min_capacity = (unsigned long)(-1); unsigned long max_capacity = 0; @@ -158,7 +158,7 @@ static void __init parse_dt_topology(void) * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the * function returns directly for SMP system. */ -void update_cpu_power(unsigned int cpu) +static void update_cpu_power(unsigned int cpu) { if (!cpu_capacity(cpu)) return; @@ -185,7 +185,7 @@ const struct cpumask *cpu_coregroup_mask(int cpu) return &cpu_topology[cpu].core_sibling; } -void update_siblings_masks(unsigned int cpuid) +static void update_siblings_masks(unsigned int cpuid) { struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; int cpu; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 7940241f0576..172ee18ff124 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -36,7 +36,13 @@ #include #include -static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; +static const char *handler[]= { + "prefetch abort", + "data abort", + "address exception", + "interrupt", + "undefined instruction", +}; void *vectors_page; @@ -56,7 +62,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long); void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { #ifdef CONFIG_KALLSYMS - printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); + printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif @@ -425,9 +431,10 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) instr2 = __mem_to_opcode_thumb16(instr2); instr = __opcode_thumb32_compose(instr, instr2); } - } else if (get_user(instr, (u32 __user *)pc)) { + } else { + if (get_user(instr, (u32 __user *)pc)) + goto die_sig; instr = __mem_to_opcode_arm(instr); - goto die_sig; } if (call_undef_hook(regs, instr) == 0) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 2a700e00528d..1d8248ea5669 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -137,6 +138,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (ret) goto out_free_stage2_pgd; + kvm_timer_init(kvm); + /* Mark the initial VMID generation invalid */ kvm->arch.vmid_gen = 0; @@ -188,6 +191,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IRQCHIP: r = vgic_present; break; + case KVM_CAP_DEVICE_CTRL: case KVM_CAP_USER_MEMORY: case KVM_CAP_SYNC_MMU: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: @@ -339,6 +343,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + /* + * The arch-generic KVM code expects the cpu field of a vcpu to be -1 + * if the vcpu is no longer assigned to a cpu. This is used for the + * optimized make_all_cpus_request path. + */ + vcpu->cpu = -1; + kvm_arm_set_running_vcpu(NULL); } @@ -462,6 +473,8 @@ static void update_vttbr(struct kvm *kvm) static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) { + int ret; + if (likely(vcpu->arch.has_run_once)) return 0; @@ -471,22 +484,12 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) * Initialize the VGIC before running a vcpu the first time on * this VM. */ - if (irqchip_in_kernel(vcpu->kvm) && - unlikely(!vgic_initialized(vcpu->kvm))) { - int ret = kvm_vgic_init(vcpu->kvm); + if (unlikely(!vgic_initialized(vcpu->kvm))) { + ret = kvm_vgic_init(vcpu->kvm); if (ret) return ret; } - /* - * Handle the "start in power-off" case by calling into the - * PSCI code. - */ - if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) { - *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF; - kvm_psci_call(vcpu); - } - return 0; } @@ -700,6 +703,24 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level, return -EINVAL; } +static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, + struct kvm_vcpu_init *init) +{ + int ret; + + ret = kvm_vcpu_set_target(vcpu, init); + if (ret) + return ret; + + /* + * Handle the "start in power-off" case by marking the VCPU as paused. + */ + if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) + vcpu->arch.pause = true; + + return 0; +} + long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -713,8 +734,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, if (copy_from_user(&init, argp, sizeof(init))) return -EFAULT; - return kvm_vcpu_set_target(vcpu, &init); - + return kvm_arch_vcpu_ioctl_vcpu_init(vcpu, &init); } case KVM_SET_ONE_REG: case KVM_GET_ONE_REG: { @@ -772,7 +792,7 @@ static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm, case KVM_ARM_DEVICE_VGIC_V2: if (!vgic_present) return -ENXIO; - return kvm_vgic_set_addr(kvm, type, dev_addr->addr); + return kvm_vgic_addr(kvm, type, &dev_addr->addr, true); default: return -ENODEV; } @@ -853,6 +873,33 @@ static struct notifier_block hyp_init_cpu_nb = { .notifier_call = hyp_init_cpu_notify, }; +#ifdef CONFIG_CPU_PM +static int hyp_init_cpu_pm_notifier(struct notifier_block *self, + unsigned long cmd, + void *v) +{ + if (cmd == CPU_PM_EXIT) { + cpu_init_hyp_mode(NULL); + return NOTIFY_OK; + } + + return NOTIFY_DONE; +} + +static struct notifier_block hyp_init_cpu_pm_nb = { + .notifier_call = hyp_init_cpu_pm_notifier, +}; + +static void __init hyp_cpu_pm_init(void) +{ + cpu_pm_register_notifier(&hyp_init_cpu_pm_nb); +} +#else +static inline void hyp_cpu_pm_init(void) +{ +} +#endif + /** * Inits Hyp-mode on all online CPUs */ @@ -1013,6 +1060,8 @@ int kvm_arch_init(void *opaque) goto out_err; } + hyp_cpu_pm_init(); + kvm_coproc_table_init(); return 0; out_err: diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index 20f8d97904af..2786eae10c0d 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c @@ -109,6 +109,83 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) return -EINVAL; } +#ifndef CONFIG_KVM_ARM_TIMER + +#define NUM_TIMER_REGS 0 + +static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) +{ + return 0; +} + +static bool is_timer_reg(u64 index) +{ + return false; +} + +int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) +{ + return 0; +} + +u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) +{ + return 0; +} + +#else + +#define NUM_TIMER_REGS 3 + +static bool is_timer_reg(u64 index) +{ + switch (index) { + case KVM_REG_ARM_TIMER_CTL: + case KVM_REG_ARM_TIMER_CNT: + case KVM_REG_ARM_TIMER_CVAL: + return true; + } + return false; +} + +static int copy_timer_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) +{ + if (put_user(KVM_REG_ARM_TIMER_CTL, uindices)) + return -EFAULT; + uindices++; + if (put_user(KVM_REG_ARM_TIMER_CNT, uindices)) + return -EFAULT; + uindices++; + if (put_user(KVM_REG_ARM_TIMER_CVAL, uindices)) + return -EFAULT; + + return 0; +} + +#endif + +static int set_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) +{ + void __user *uaddr = (void __user *)(long)reg->addr; + u64 val; + int ret; + + ret = copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)); + if (ret != 0) + return ret; + + return kvm_arm_timer_set_reg(vcpu, reg->id, val); +} + +static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) +{ + void __user *uaddr = (void __user *)(long)reg->addr; + u64 val; + + val = kvm_arm_timer_get_reg(vcpu, reg->id); + return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); +} + static unsigned long num_core_regs(void) { return sizeof(struct kvm_regs) / sizeof(u32); @@ -121,7 +198,8 @@ static unsigned long num_core_regs(void) */ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) { - return num_core_regs() + kvm_arm_num_coproc_regs(vcpu); + return num_core_regs() + kvm_arm_num_coproc_regs(vcpu) + + NUM_TIMER_REGS; } /** @@ -133,6 +211,7 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) { unsigned int i; const u64 core_reg = KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE; + int ret; for (i = 0; i < sizeof(struct kvm_regs)/sizeof(u32); i++) { if (put_user(core_reg | i, uindices)) @@ -140,6 +219,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) uindices++; } + ret = copy_timer_indices(vcpu, uindices); + if (ret) + return ret; + uindices += NUM_TIMER_REGS; + return kvm_arm_copy_coproc_indices(vcpu, uindices); } @@ -153,6 +237,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) return get_core_reg(vcpu, reg); + if (is_timer_reg(reg->id)) + return get_timer_reg(vcpu, reg); + return kvm_arm_coproc_get_reg(vcpu, reg); } @@ -166,6 +253,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) return set_core_reg(vcpu, reg); + if (is_timer_reg(reg->id)) + return set_timer_reg(vcpu, reg); + return kvm_arm_coproc_set_reg(vcpu, reg); } diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c index a92079011a83..0de91fc6de0f 100644 --- a/arch/arm/kvm/handle_exit.c +++ b/arch/arm/kvm/handle_exit.c @@ -26,8 +26,6 @@ #include "trace.h" -#include "trace.h" - typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *); static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 580906989db1..7789857d1470 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -667,14 +667,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; } else { /* - * Pages belonging to VMAs not aligned to the PMD mapping - * granularity cannot be mapped using block descriptors even - * if the pages belong to a THP for the process, because the - * stage-2 block descriptor will cover more than a single THP - * and we loose atomicity for unmapping, updates, and splits - * of the THP or other pages in the stage-2 block range. + * Pages belonging to memslots that don't have the same + * alignment for userspace and IPA cannot be mapped using + * block descriptors even if the pages belong to a THP for + * the process, because the stage-2 block descriptor will + * cover more than a single THP and we loose atomicity for + * unmapping, updates, and splits of the THP or other pages + * in the stage-2 block range. */ - if (vma->vm_start & ~PMD_MASK) + if ((memslot->userspace_addr & ~PMD_MASK) != + ((memslot->base_gfn << PAGE_SHIFT) & ~PMD_MASK)) force_pte = true; } up_read(¤t->mm->mmap_sem); @@ -916,9 +918,9 @@ int kvm_mmu_init(void) { int err; - hyp_idmap_start = virt_to_phys(__hyp_idmap_text_start); - hyp_idmap_end = virt_to_phys(__hyp_idmap_text_end); - hyp_idmap_vector = virt_to_phys(__kvm_hyp_init); + hyp_idmap_start = kvm_virt_to_phys(__hyp_idmap_text_start); + hyp_idmap_end = kvm_virt_to_phys(__hyp_idmap_text_end); + hyp_idmap_vector = kvm_virt_to_phys(__kvm_hyp_init); if ((hyp_idmap_start ^ hyp_idmap_end) & PAGE_MASK) { /* @@ -945,7 +947,7 @@ int kvm_mmu_init(void) */ kvm_flush_dcache_to_poc(init_bounce_page, len); - phys_base = virt_to_phys(init_bounce_page); + phys_base = kvm_virt_to_phys(init_bounce_page); hyp_idmap_vector += phys_base - hyp_idmap_start; hyp_idmap_start = phys_base; hyp_idmap_end = phys_base + len; diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index 0881bf169fbc..448f60e8d23c 100644 --- a/arch/arm/kvm/psci.c +++ b/arch/arm/kvm/psci.c @@ -54,15 +54,15 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) } } - if (!vcpu) + /* + * Make sure the caller requested a valid CPU and that the CPU is + * turned off. + */ + if (!vcpu || !vcpu->arch.pause) return KVM_PSCI_RET_INVAL; target_pc = *vcpu_reg(source_vcpu, 2); - wq = kvm_arch_vcpu_wq(vcpu); - if (!waitqueue_active(wq)) - return KVM_PSCI_RET_INVAL; - kvm_reset_vcpu(vcpu); /* Gracefully handle Thumb2 entry point */ @@ -79,6 +79,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) vcpu->arch.pause = false; smp_mb(); /* Make sure the above is visible */ + wq = kvm_arch_vcpu_wq(vcpu); wake_up_interruptible(wq); return KVM_PSCI_RET_SUCCESS; diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 47d7338561de..0573faab96ad 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -13,7 +13,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ ucmpdi2.o lib1funcs.o div64.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \ - call_with_stack.o + call_with_stack.o bswapsdi2.o mmu-y := clear_user.o copy_page.o getuser.o putuser.o diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S index cd07b5814c23..4102be617fce 100644 --- a/arch/arm/lib/backtrace.S +++ b/arch/arm/lib/backtrace.S @@ -80,14 +80,14 @@ for_each_frame: tst frame, mask @ Check for address exceptions ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, ldr r3, .Ldsi+4 - teq r3, r1, lsr #10 + teq r3, r1, lsr #11 ldreq r0, [frame, #-8] @ get sp subeq r0, r0, #4 @ point at the last arg bleq .Ldumpstm @ dump saved registers 1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} ldr r3, .Ldsi @ instruction exists, - teq r3, r1, lsr #10 + teq r3, r1, lsr #11 subeq r0, frame, #16 bleq .Ldumpstm @ dump saved registers @@ -128,11 +128,11 @@ ENDPROC(c_backtrace) beq 2f add r7, r7, #1 teq r7, #6 - moveq r7, #1 - moveq r1, #'\n' - movne r1, #' ' - ldr r3, [stack], #-4 - mov r2, reg + moveq r7, #0 + adr r3, .Lcr + addne r3, r3, #1 @ skip newline + ldr r2, [stack], #-4 + mov r1, reg adr r0, .Lfp bl printk 2: subs reg, reg, #1 @@ -142,11 +142,11 @@ ENDPROC(c_backtrace) blne printk ldmfd sp!, {instr, reg, stack, r7, pc} -.Lfp: .asciz "%cr%d:%08x" +.Lfp: .asciz " r%d:%08x%s" .Lcr: .asciz "\n" .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" .align -.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc} - .word 0xe92d0000 >> 10 @ stmfd sp!, {} +.Ldsi: .word 0xe92dd800 >> 11 @ stmfd sp!, {... fp, ip, lr, pc} + .word 0xe92d0000 >> 11 @ stmfd sp!, {} #endif diff --git a/arch/arm/lib/bswapsdi2.S b/arch/arm/lib/bswapsdi2.S new file mode 100644 index 000000000000..9fcdd154eff9 --- /dev/null +++ b/arch/arm/lib/bswapsdi2.S @@ -0,0 +1,36 @@ +#include + +#if __LINUX_ARM_ARCH__ >= 6 +ENTRY(__bswapsi2) + rev r0, r0 + bx lr +ENDPROC(__bswapsi2) + +ENTRY(__bswapdi2) + rev r3, r0 + rev r0, r1 + mov r1, r3 + bx lr +ENDPROC(__bswapdi2) +#else +ENTRY(__bswapsi2) + eor r3, r0, r0, ror #16 + mov r3, r3, lsr #8 + bic r3, r3, #0xff00 + eor r0, r3, r0, ror #8 + mov pc, lr +ENDPROC(__bswapsi2) + +ENTRY(__bswapdi2) + mov ip, r1 + eor r3, ip, ip, ror #16 + eor r1, r0, r0, ror #16 + mov r1, r1, lsr #8 + mov r3, r3, lsr #8 + bic r3, r3, #0xff00 + bic r1, r1, #0xff00 + eor r1, r1, r0, ror #8 + eor r0, r3, ip, ror #8 + mov pc, lr +ENDPROC(__bswapdi2) +#endif diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 699b71e7f7ec..4f0e800e7e71 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -1,15 +1,33 @@ if ARCH_AT91 +config HAVE_AT91_UTMI + bool + +config HAVE_AT91_USB_CLK + bool + config HAVE_AT91_DBGU0 bool config HAVE_AT91_DBGU1 bool +config AT91_USE_OLD_CLK + bool + config AT91_PMC_UNIT bool default !ARCH_AT91X40 +config COMMON_CLK_AT91 + bool + default AT91_PMC_UNIT && USE_OF && !AT91_USE_OLD_CLK + select COMMON_CLK + +config OLD_CLK_AT91 + bool + default AT91_PMC_UNIT && AT91_USE_OLD_CLK + config AT91_SAM9_ALT_RESET bool default !ARCH_AT91X40 @@ -21,6 +39,9 @@ config AT91_SAM9G45_RESET config AT91_SAM9_TIME bool +config HAVE_AT91_SMD + bool + config SOC_AT91SAM9 bool select AT91_SAM9_TIME @@ -61,13 +82,15 @@ comment "Atmel AT91 Processor" if SOC_SAM_V7 config SOC_SAMA5D3 bool "SAMA5D3 family" - depends on SOC_SAM_V7 select SOC_SAMA5 select HAVE_FB_ATMEL select HAVE_AT91_DBGU1 + select HAVE_AT91_UTMI + select HAVE_AT91_SMD + select HAVE_AT91_USB_CLK help Select this if you are using one of Atmel's SAMA5D3 family SoC. - This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35. + This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36. endif if SOC_SAM_V4_V5 @@ -78,11 +101,15 @@ config SOC_AT91RM9200 select HAVE_AT91_DBGU0 select MULTI_IRQ_HANDLER select SPARSE_IRQ + select AT91_USE_OLD_CLK + select HAVE_AT91_USB_CLK config SOC_AT91SAM9260 bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20" select HAVE_AT91_DBGU0 select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_USB_CLK help Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE or AT91SAM9G20 SoC. @@ -92,6 +119,8 @@ config SOC_AT91SAM9261 select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_USB_CLK help Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC. @@ -100,18 +129,25 @@ config SOC_AT91SAM9263 select HAVE_AT91_DBGU1 select HAVE_FB_ATMEL select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_USB_CLK config SOC_AT91SAM9RL bool "AT91SAM9RL" select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_UTMI config SOC_AT91SAM9G45 bool "AT91SAM9G45 or AT91SAM9M10 families" select HAVE_AT91_DBGU1 select HAVE_FB_ATMEL select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_UTMI + select HAVE_AT91_USB_CLK help Select this if you are using one of Atmel's AT91SAM9G45 family SoC. This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11. @@ -121,6 +157,10 @@ config SOC_AT91SAM9X5 select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_UTMI + select HAVE_AT91_SMD + select HAVE_AT91_USB_CLK help Select this if you are using one of Atmel's AT91SAM9x5 family SoC. This means that your SAM9 name finishes with a '5' (except if it is @@ -133,6 +173,8 @@ config SOC_AT91SAM9N12 select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL select SOC_AT91SAM9 + select AT91_USE_OLD_CLK + select HAVE_AT91_USB_CLK help Select this if you are using Atmel's AT91SAM9N12 SoC. @@ -172,12 +214,6 @@ config MACH_SAMA5_DT comment "AT91 Feature Selections" -config AT91_PROGRAMMABLE_CLOCKS - bool "Programmable Clocks" - help - Select this if you need to program one or more of the PCK0..PCK3 - programmable clock outputs. - config AT91_SLOW_CLOCK bool "Suspend-to-RAM disables main oscillator" depends on SUSPEND diff --git a/arch/arm/mach-at91/Kconfig.non_dt b/arch/arm/mach-at91/Kconfig.non_dt index ca900be144ce..1f73e9b527da 100644 --- a/arch/arm/mach-at91/Kconfig.non_dt +++ b/arch/arm/mach-at91/Kconfig.non_dt @@ -12,26 +12,32 @@ config ARCH_AT91_NONE config ARCH_AT91RM9200 bool "AT91RM9200" select SOC_AT91RM9200 + select AT91_USE_OLD_CLK config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20" select SOC_AT91SAM9260 + select AT91_USE_OLD_CLK config ARCH_AT91SAM9261 bool "AT91SAM9261 or AT91SAM9G10" select SOC_AT91SAM9261 + select AT91_USE_OLD_CLK config ARCH_AT91SAM9263 bool "AT91SAM9263" select SOC_AT91SAM9263 + select AT91_USE_OLD_CLK config ARCH_AT91SAM9RL bool "AT91SAM9RL" select SOC_AT91SAM9RL + select AT91_USE_OLD_CLK config ARCH_AT91SAM9G45 bool "AT91SAM9G45" select SOC_AT91SAM9G45 + select AT91_USE_OLD_CLK config ARCH_AT91X40 bool "AT91x40" @@ -176,12 +182,6 @@ config MACH_AFEB9260 -config MACH_QIL_A9260 - bool "CALAO QIL-A9260 board" - help - Select this if you are using a Calao Systems QIL-A9260 Board. - - config MACH_CPU9260 bool "Eukrea CPU9260 board" help @@ -241,7 +241,7 @@ config MACH_PCONTROL_G20 bool "PControl G20 CPU module" help Select this if you are using taskit's Stamp9G20 CPU module on this - carrier board, beeing the decentralized unit of a building automation + carrier board, being the decentralized unit of a building automation system; featuring nvram, eth-switch, iso-rs485, display, io config MACH_GSIA18S diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 90aab2d5a07f..78e9cec282f4 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -7,7 +7,7 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_AT91_PMC_UNIT) += clock.o +obj-$(CONFIG_OLD_CLK_AT91) += clock.o obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o obj-$(CONFIG_AT91_SAM9_TIME) += at91sam926x_time.o @@ -52,7 +52,6 @@ obj-$(CONFIG_MACH_RSI_EWS) += board-rsi-ews.o obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o obj-$(CONFIG_MACH_CAM60) += board-cam60.o obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o -obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o obj-$(CONFIG_MACH_FLEXIBITY) += board-flexibity.o diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index 25805f2f6010..e47f5fd232f5 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -12,13 +12,13 @@ #include #include +#include #include #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index d6a1fa85371d..6c821e562159 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -20,7 +21,6 @@ #include #include #include -#include #include "at91_aic.h" #include "at91_rstc.h" diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 23ba1d8a1531..6276b4c1acfe 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include #include "at91_aic.h" #include "at91_rstc.h" diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 7eccb0fc57bc..37b90f4b990c 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #include "at91_aic.h" #include "at91_rstc.h" diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index bb392320a0dd..0f04ffe9c5a8 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -39,6 +39,7 @@ static u32 pit_cycle; /* write-once */ static u32 pit_cnt; /* access only w/system irq blocked */ static void __iomem *pit_base_addr __read_mostly; +static struct clk *mck; static inline unsigned int pit_read(unsigned int reg_offset) { @@ -195,10 +196,14 @@ static int __init of_at91sam926x_pit_init(void) if (!pit_base_addr) goto node_err; + mck = of_clk_get(np, 0); + /* Get the interrupts property */ ret = irq_of_parse_and_map(np, 0); if (!ret) { pr_crit("AT91: PIT: Unable to get IRQ from DT\n"); + if (!IS_ERR(mck)) + clk_put(mck); goto ioremap_err; } at91sam926x_pit_irq.irq = ret; @@ -230,6 +235,8 @@ void __init at91sam926x_pit_init(void) unsigned bits; int ret; + mck = ERR_PTR(-ENOENT); + /* For device tree enabled device: initialize here */ of_at91sam926x_pit_init(); @@ -237,7 +244,12 @@ void __init at91sam926x_pit_init(void) * Use our actual MCK to figure out how many MCK/16 ticks per * 1/HZ period (instead of a compile-time constant LATCH). */ - pit_rate = clk_get_rate(clk_get(NULL, "mck")) / 16; + if (IS_ERR(mck)) + mck = clk_get(NULL, "mck"); + + if (IS_ERR(mck)) + panic("AT91: PIT: Unable to get mck clk\n"); + pit_rate = clk_get_rate(mck) / 16; pit_cycle = (pit_rate + HZ/2) / HZ; WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0); diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 9405aa08b104..2f455ce35268 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -12,13 +12,13 @@ #include #include +#include #include #include #include #include #include -#include #include #include "at91_aic.h" diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 388ec3aec4b9..4ef088c62eab 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -8,12 +8,12 @@ #include #include +#include #include #include #include #include -#include #include #include "board.h" diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 0750ffb7e6b1..3651517abedf 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -10,6 +10,7 @@ */ #include +#include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include #include "at91_aic.h" #include "at91_rstc.h" diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index e8a2e075a1b8..3e8ec26e39dc 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -8,12 +8,12 @@ #include #include +#include #include #include #include #include -#include #include #include "board.h" diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c index bf00d15d954d..075ec0576ada 100644 --- a/arch/arm/mach-at91/board-dt-sama5.c +++ b/arch/arm/mach-at91/board-dt-sama5.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,13 @@ #include "at91_aic.h" #include "generic.h" +static void __init sama5_dt_timer_init(void) +{ +#if defined(CONFIG_COMMON_CLK) + of_clk_init(NULL); +#endif + at91sam926x_pit_init(); +} static const struct of_device_id irq_of_match[] __initconst = { @@ -72,7 +80,7 @@ static const char *sama5_dt_board_compat[] __initdata = { DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") /* Maintainer: Atmel */ - .init_time = at91sam926x_pit_init, + .init_time = sama5_dt_timer_init, .map_io = at91_map_io, .handle_irq = at91_aic5_handle_irq, .init_early = at91_dt_initialize, diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c deleted file mode 100644 index aa3bc9b0f150..000000000000 --- a/arch/arm/mach-at91/board-qil-a9260.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * linux/arch/arm/mach-at91/board-qil-a9260.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2006 Atmel - * Copyright (C) 2007 Calao-systems - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "at91_aic.h" -#include "at91_shdwc.h" -#include "board.h" -#include "sam9_smc.h" -#include "generic.h" - - -static void __init ek_init_early(void) -{ - /* Initialize processor: 12.000 MHz crystal */ - at91_initialize(12000000); -} - -/* - * USB Host port - */ -static struct at91_usbh_data __initdata ek_usbh_data = { - .ports = 2, - .vbus_pin = {-EINVAL, -EINVAL}, - .overcurrent_pin= {-EINVAL, -EINVAL}, -}; - -/* - * USB Device port - */ -static struct at91_udc_data __initdata ek_udc_data = { - .vbus_pin = AT91_PIN_PC5, - .pullup_pin = -EINVAL, /* pull-up driven by UDC */ -}; - -/* - * SPI devices. - */ -static struct spi_board_info ek_spi_devices[] = { -#if defined(CONFIG_RTC_DRV_M41T94) - { /* M41T94 RTC */ - .modalias = "m41t94", - .chip_select = 0, - .max_speed_hz = 1 * 1000 * 1000, - .bus_num = 0, - } -#endif -}; - -/* - * MACB Ethernet device - */ -static struct macb_platform_data __initdata ek_macb_data = { - .phy_irq_pin = AT91_PIN_PA31, - .is_rmii = 1, -}; - -/* - * NAND flash - */ -static struct mtd_partition __initdata ek_nand_partition[] = { - { - .name = "Uboot & Kernel", - .offset = 0, - .size = SZ_16M, - }, - { - .name = "Root FS", - .offset = MTDPART_OFS_NXTBLK, - .size = 120 * SZ_1M, - }, - { - .name = "FS", - .offset = MTDPART_OFS_NXTBLK, - .size = 120 * SZ_1M, - }, -}; - -static struct atmel_nand_data __initdata ek_nand_data = { - .ale = 21, - .cle = 22, - .det_pin = -EINVAL, - .rdy_pin = AT91_PIN_PC13, - .enable_pin = AT91_PIN_PC14, - .ecc_mode = NAND_ECC_SOFT, - .on_flash_bbt = 1, - .parts = ek_nand_partition, - .num_parts = ARRAY_SIZE(ek_nand_partition), -}; - -static struct sam9_smc_config __initdata ek_nand_smc_config = { - .ncs_read_setup = 0, - .nrd_setup = 1, - .ncs_write_setup = 0, - .nwe_setup = 1, - - .ncs_read_pulse = 3, - .nrd_pulse = 3, - .ncs_write_pulse = 3, - .nwe_pulse = 3, - - .read_cycle = 5, - .write_cycle = 5, - - .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, - .tdf_cycles = 2, -}; - -static void __init ek_add_device_nand(void) -{ - /* configure chip-select 3 (NAND) */ - sam9_smc_configure(0, 3, &ek_nand_smc_config); - - at91_add_device_nand(&ek_nand_data); -} - -/* - * MCI (SD/MMC) - */ -static struct mci_platform_data __initdata ek_mci0_data = { - .slot[0] = { - .bus_width = 4, - .detect_pin = -EINVAL, - .wp_pin = -EINVAL, - }, -}; - -/* - * GPIO Buttons - */ -#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) -static struct gpio_keys_button ek_buttons[] = { - { /* USER PUSH BUTTON */ - .code = KEY_ENTER, - .gpio = AT91_PIN_PB10, - .active_low = 1, - .desc = "user_pb", - .wakeup = 1, - } -}; - -static struct gpio_keys_platform_data ek_button_data = { - .buttons = ek_buttons, - .nbuttons = ARRAY_SIZE(ek_buttons), -}; - -static struct platform_device ek_button_device = { - .name = "gpio-keys", - .id = -1, - .num_resources = 0, - .dev = { - .platform_data = &ek_button_data, - } -}; - -static void __init ek_add_device_buttons(void) -{ - at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */ - at91_set_deglitch(AT91_PIN_PB10, 1); - - platform_device_register(&ek_button_device); -} -#else -static void __init ek_add_device_buttons(void) {} -#endif - -/* - * LEDs - */ -static struct gpio_led ek_leds[] = { - { /* user_led (green) */ - .name = "user_led", - .gpio = AT91_PIN_PB21, - .active_low = 0, - .default_trigger = "heartbeat", - } -}; - -static void __init ek_board_init(void) -{ - /* Serial */ - /* DBGU on ttyS0. (Rx & Tx only) */ - at91_register_uart(0, 0, 0); - - /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ - at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS - | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD - | ATMEL_UART_RI); - - /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS); - - /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */ - at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS); - at91_add_device_serial(); - /* USB Host */ - at91_add_device_usbh(&ek_usbh_data); - /* USB Device */ - at91_add_device_udc(&ek_udc_data); - /* SPI */ - at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* NAND */ - ek_add_device_nand(); - /* I2C */ - at91_add_device_i2c(NULL, 0); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); - /* MMC */ - at91_add_device_mci(0, &ek_mci0_data); - /* Push Buttons */ - ek_add_device_buttons(); - /* LEDs */ - at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); - /* shutdown controller, wakeup button (5 msec low) */ - at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW - | AT91_SHDW_RTTWKEN); -} - -MACHINE_START(QIL_A9260, "CALAO QIL_A9260") - /* Maintainer: calao-systems */ - .init_time = at91sam926x_pit_init, - .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, - .init_early = ek_init_early, - .init_irq = at91_init_irq_default, - .init_machine = ek_board_init, -MACHINE_END diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 6b2630a92f71..034529d801b2 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -24,9 +24,9 @@ #include #include #include +#include #include -#include #include #include @@ -330,8 +330,6 @@ EXPORT_SYMBOL(clk_get_rate); /*------------------------------------------------------------------------*/ -#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS - /* * For now, only the programmable clocks support reparenting (MCK could * do this too, with care) or rate changing (the PLLs could do this too, @@ -459,8 +457,6 @@ static void __init init_programmable_clock(struct clk *clk) clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr); } -#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ - /*------------------------------------------------------------------------*/ #ifdef CONFIG_DEBUG_FS @@ -577,12 +573,10 @@ int __init clk_register(struct clk *clk) clk->parent = &mck; clk->mode = pmc_sys_mode; } -#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS else if (clk_is_programmable(clk)) { clk->mode = pmc_sys_mode; init_programmable_clock(clk); } -#endif at91_clk_add(clk); @@ -884,6 +878,11 @@ static int __init at91_pmc_init(unsigned long main_clock) #if defined(CONFIG_OF) static struct of_device_id pmc_ids[] = { { .compatible = "atmel,at91rm9200-pmc" }, + { .compatible = "atmel,at91sam9260-pmc" }, + { .compatible = "atmel,at91sam9g45-pmc" }, + { .compatible = "atmel,at91sam9n12-pmc" }, + { .compatible = "atmel,at91sam9x5-pmc" }, + { .compatible = "atmel,sama5d3-pmc" }, { /*sentinel*/ } }; diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index 26dee3ce9397..631fa3b8c16d 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -46,11 +46,12 @@ extern void at91sam926x_pit_init(void); extern void at91x40_timer_init(void); /* Clocks */ -#ifdef CONFIG_AT91_PMC_UNIT +#ifdef CONFIG_OLD_CLK_AT91 extern int __init at91_clock_init(unsigned long main_clock); extern int __init at91_dt_clock_init(void); #else static int inline at91_clock_init(unsigned long main_clock) { return 0; } +static int inline at91_dt_clock_init(void) { return 0; } #endif struct device; diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index d3d7b993846b..86c71debab5b 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -53,6 +53,7 @@ #define ARCH_EXID_SAMA5D33 0x00414300 #define ARCH_EXID_SAMA5D34 0x00414301 #define ARCH_EXID_SAMA5D35 0x00584300 +#define ARCH_EXID_SAMA5D36 0x00004301 #define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91SAM9 0x01900000 @@ -105,7 +106,7 @@ enum at91_soc_subtype { /* SAMA5D3 */ AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, - AT91_SOC_SAMA5D35, + AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36, /* No subtype for this SoC */ AT91_SOC_SUBTYPE_NONE, diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 9986542e8060..590b52dea9f7 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -19,13 +19,13 @@ #include #include #include +#include #include #include #include #include -#include #include #include "at91_aic.h" @@ -155,9 +155,6 @@ static int at91_pm_verify_clocks(void) } } - if (!IS_ENABLED(CONFIG_AT91_PROGRAMMABLE_CLOCKS)) - return 1; - /* PCK0..PCK3 must be disabled, or configured to use clk32k */ for (i = 0; i < 4; i++) { u32 css; diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S index 098c28ddf025..20018779bae7 100644 --- a/arch/arm/mach-at91/pm_slowclock.S +++ b/arch/arm/mach-at91/pm_slowclock.S @@ -13,8 +13,8 @@ */ #include +#include #include -#include #include diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c index 99a0a1d2b7dc..b26156bf15db 100644 --- a/arch/arm/mach-at91/sam9_smc.c +++ b/arch/arm/mach-at91/sam9_smc.c @@ -101,7 +101,7 @@ static void sam9_smc_cs_read(void __iomem *base, /* Pulse register */ val = __raw_readl(base + AT91_SMC_PULSE); - config->nwe_setup = val & AT91_SMC_NWEPULSE; + config->nwe_pulse = val & AT91_SMC_NWEPULSE; config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8; config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16; config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24; diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c index a28873fe3049..3d775d08de08 100644 --- a/arch/arm/mach-at91/sama5d3.c +++ b/arch/arm/mach-at91/sama5d3.c @@ -9,359 +9,18 @@ #include #include +#include #include #include #include #include -#include #include #include "soc.h" #include "generic.h" -#include "clock.h" #include "sam9_smc.h" -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ - -static struct clk pioA_clk = { - .name = "pioA_clk", - .pid = SAMA5D3_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pid = SAMA5D3_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pid = SAMA5D3_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioD_clk = { - .name = "pioD_clk", - .pid = SAMA5D3_ID_PIOD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioE_clk = { - .name = "pioE_clk", - .pid = SAMA5D3_ID_PIOE, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pid = SAMA5D3_ID_USART0, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pid = SAMA5D3_ID_USART1, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pid = SAMA5D3_ID_USART2, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pid = SAMA5D3_ID_USART3, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk uart0_clk = { - .name = "uart0_clk", - .pid = SAMA5D3_ID_UART0, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk uart1_clk = { - .name = "uart1_clk", - .pid = SAMA5D3_ID_UART1, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk twi0_clk = { - .name = "twi0_clk", - .pid = SAMA5D3_ID_TWI0, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV8, -}; -static struct clk twi1_clk = { - .name = "twi1_clk", - .pid = SAMA5D3_ID_TWI1, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV8, -}; -static struct clk twi2_clk = { - .name = "twi2_clk", - .pid = SAMA5D3_ID_TWI2, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV8, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pid = SAMA5D3_ID_HSMCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pid = SAMA5D3_ID_HSMCI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc2_clk = { - .name = "mci2_clk", - .pid = SAMA5D3_ID_HSMCI2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pid = SAMA5D3_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pid = SAMA5D3_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb0_clk = { - .name = "tcb0_clk", - .pid = SAMA5D3_ID_TC0, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk tcb1_clk = { - .name = "tcb1_clk", - .pid = SAMA5D3_ID_TC1, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pid = SAMA5D3_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk adc_op_clk = { - .name = "adc_op_clk", - .type = CLK_TYPE_PERIPHERAL, - .rate_hz = 5000000, -}; -static struct clk dma0_clk = { - .name = "dma0_clk", - .pid = SAMA5D3_ID_DMA0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma1_clk = { - .name = "dma1_clk", - .pid = SAMA5D3_ID_DMA1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk uhphs_clk = { - .name = "uhphs", - .pid = SAMA5D3_ID_UHPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pid = SAMA5D3_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -/* gmac only for sama5d33, sama5d34, sama5d35 */ -static struct clk macb0_clk = { - .name = "macb0_clk", - .pid = SAMA5D3_ID_GMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -/* emac only for sama5d31, sama5d35 */ -static struct clk macb1_clk = { - .name = "macb1_clk", - .pid = SAMA5D3_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -/* lcd only for sama5d31, sama5d33, sama5d34 */ -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pid = SAMA5D3_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -/* isi only for sama5d33, sama5d35 */ -static struct clk isi_clk = { - .name = "isi_clk", - .pid = SAMA5D3_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk can0_clk = { - .name = "can0_clk", - .pid = SAMA5D3_ID_CAN0, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk can1_clk = { - .name = "can1_clk", - .pid = SAMA5D3_ID_CAN1, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pid = SAMA5D3_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pid = SAMA5D3_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV2, -}; -static struct clk sha_clk = { - .name = "sha_clk", - .pid = SAMA5D3_ID_SHA, - .type = CLK_TYPE_PERIPHERAL, - .div = AT91_PMC_PCR_DIV8, -}; -static struct clk aes_clk = { - .name = "aes_clk", - .pid = SAMA5D3_ID_AES, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tdes_clk = { - .name = "tdes_clk", - .pid = SAMA5D3_ID_TDES, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &pioD_clk, - &pioE_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &uart0_clk, - &uart1_clk, - &twi0_clk, - &twi1_clk, - &twi2_clk, - &mmc0_clk, - &mmc1_clk, - &mmc2_clk, - &spi0_clk, - &spi1_clk, - &tcb0_clk, - &tcb1_clk, - &adc_clk, - &adc_op_clk, - &dma0_clk, - &dma1_clk, - &uhphs_clk, - &udphs_clk, - &macb0_clk, - &macb1_clk, - &lcdc_clk, - &isi_clk, - &can0_clk, - &can1_clk, - &ssc0_clk, - &ssc1_clk, - &sha_clk, - &aes_clk, - &tdes_clk, -}; - -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; - -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; - -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* lookup table for DT entries */ - CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck), - CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk), - CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioD_clk), - CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioE_clk), - CLKDEV_CON_DEV_ID("usart", "f001c000.serial", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "f0020000.serial", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart2_clk), - CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart3_clk), - CLKDEV_CON_DEV_ID(NULL, "f0014000.i2c", &twi0_clk), - CLKDEV_CON_DEV_ID(NULL, "f0018000.i2c", &twi1_clk), - CLKDEV_CON_DEV_ID(NULL, "f801c000.i2c", &twi2_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f0000000.mmc", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f8000000.mmc", &mmc1_clk), - CLKDEV_CON_DEV_ID("mci_clk", "f8004000.mmc", &mmc2_clk), - CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "f8008000.spi", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "f0010000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("t0_clk", "f8014000.timer", &tcb1_clk), - CLKDEV_CON_DEV_ID("tsc_clk", "f8018000.tsadcc", &adc_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffe600.dma-controller", &dma0_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffe800.dma-controller", &dma1_clk), - CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk), - CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk), - CLKDEV_CON_DEV_ID("pclk", "500000.gadget", &udphs_clk), - CLKDEV_CON_DEV_ID("hclk", "500000.gadget", &utmi_clk), - CLKDEV_CON_DEV_ID("hclk", "f0028000.ethernet", &macb0_clk), - CLKDEV_CON_DEV_ID("pclk", "f0028000.ethernet", &macb0_clk), - CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb1_clk), - CLKDEV_CON_DEV_ID("pclk", "f802c000.ethernet", &macb1_clk), - CLKDEV_CON_DEV_ID("pclk", "f0008000.ssc", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "f000c000.ssc", &ssc1_clk), - CLKDEV_CON_DEV_ID("can_clk", "f000c000.can", &can0_clk), - CLKDEV_CON_DEV_ID("can_clk", "f8010000.can", &can1_clk), - CLKDEV_CON_DEV_ID("sha_clk", "f8034000.sha", &sha_clk), - CLKDEV_CON_DEV_ID("aes_clk", "f8038000.aes", &aes_clk), - CLKDEV_CON_DEV_ID("tdes_clk", "f803c000.tdes", &tdes_clk), -}; - -static void __init sama5d3_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); -} - /* -------------------------------------------------------------------- * AT91SAM9x5 processor initialization * -------------------------------------------------------------------- */ @@ -378,6 +37,5 @@ static void __init sama5d3_initialize(void) AT91_SOC_START(sama5d3) .map_io = sama5d3_map_io, - .register_clocks = sama5d3_register_clocks, .init = sama5d3_initialize, AT91_SOC_END diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 094b3459c288..f7ca97b7291e 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include #include "at91_shdwc.h" #include "soc.h" @@ -81,7 +81,7 @@ void __init at91_init_sram(int bank, unsigned long base, unsigned int length) desc->pfn = __phys_to_pfn(base); desc->length = length; - desc->type = MT_MEMORY_NONCACHED; + desc->type = MT_MEMORY_RWX_NONCACHED; pr_info("AT91: sram at 0x%lx of 0x%x mapped at 0x%lx\n", base, length, desc->virtual); @@ -233,6 +233,9 @@ static void __init soc_detect(u32 dbgu_base) case ARCH_EXID_SAMA5D35: at91_soc_initdata.subtype = AT91_SOC_SAMA5D35; break; + case ARCH_EXID_SAMA5D36: + at91_soc_initdata.subtype = AT91_SOC_SAMA5D36; + break; } } } @@ -275,6 +278,7 @@ static const char *soc_subtype_name[] = { [AT91_SOC_SAMA5D33] = "sama5d33", [AT91_SOC_SAMA5D34] = "sama5d34", [AT91_SOC_SAMA5D35] = "sama5d35", + [AT91_SOC_SAMA5D36] = "sama5d36", [AT91_SOC_SUBTYPE_NONE] = "None", [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown", }; @@ -491,7 +495,8 @@ void __init at91rm9200_dt_initialize(void) at91_dt_clock_init(); /* Register the processor-specific clocks */ - at91_boot_soc.register_clocks(); + if (at91_boot_soc.register_clocks) + at91_boot_soc.register_clocks(); at91_boot_soc.init(); } @@ -506,7 +511,8 @@ void __init at91_dt_initialize(void) at91_dt_clock_init(); /* Register the processor-specific clocks */ - at91_boot_soc.register_clocks(); + if (at91_boot_soc.register_clocks) + at91_boot_soc.register_clocks(); if (at91_boot_soc.init) at91_boot_soc.init(); diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 9fe6d88737ed..b1aa6a9b3bd1 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -25,6 +25,7 @@ config ARCH_BCM_MOBILE select TICK_ONESHOT select CACHE_L2X0 select HAVE_ARM_ARCH_TIMER + select PINCTRL help This enables support for systems based on Broadcom mobile SoCs. It currently supports the 'BCM281XX' family, which includes diff --git a/arch/arm/mach-bcm2835/Kconfig b/arch/arm/mach-bcm2835/Kconfig index 560045cafc34..d1f9612f8c15 100644 --- a/arch/arm/mach-bcm2835/Kconfig +++ b/arch/arm/mach-bcm2835/Kconfig @@ -12,4 +12,4 @@ config ARCH_BCM2835 select PINCTRL_BCM2835 help This enables support for the Broadcom BCM2835 SoC. This SoC is - use in the Raspberry Pi, and Roku 2 devices. + used in the Raspberry Pi and Roku 2 devices. diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig new file mode 100644 index 000000000000..7a02d222c378 --- /dev/null +++ b/arch/arm/mach-berlin/Kconfig @@ -0,0 +1,29 @@ +config ARCH_BERLIN + bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 + select ARM_GIC + select GENERIC_CLOCKEVENTS + select GENERIC_IRQ_CHIP + select COMMON_CLK + select DW_APB_ICTL + select DW_APB_TIMER_OF + +if ARCH_BERLIN + +menu "Marvell Berlin SoC variants" + +config MACH_BERLIN_BG2 + bool "Marvell Armada 1500 (BG2)" + select CACHE_L2X0 + select CPU_PJ4B + select HAVE_ARM_TWD if SMP + select HAVE_SMP + +config MACH_BERLIN_BG2CD + bool "Marvell Armada 1500-mini (BG2CD)" + select CACHE_L2X0 + select CPU_V7 + select HAVE_ARM_TWD if SMP + +endmenu + +endif diff --git a/arch/arm/mach-berlin/Makefile b/arch/arm/mach-berlin/Makefile new file mode 100644 index 000000000000..ab69fe956f49 --- /dev/null +++ b/arch/arm/mach-berlin/Makefile @@ -0,0 +1 @@ +obj-y += berlin.o diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c new file mode 100644 index 000000000000..025bcb5473eb --- /dev/null +++ b/arch/arm/mach-berlin/berlin.c @@ -0,0 +1,39 @@ +/* + * Device Tree support for Marvell Berlin SoCs. + * + * Sebastian Hesselbarth + * + * based on GPL'ed 2.6 kernel sources + * (c) Marvell International Ltd. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include + +static void __init berlin_init_machine(void) +{ + /* + * with DT probing for L2CCs, berlin_init_machine can be removed. + * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc + */ + l2x0_of_init(0x70c00000, 0xfeffffff); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const berlin_dt_compat[] = { + "marvell,berlin", + NULL, +}; + +DT_MACHINE_START(BERLIN_DT, "Marvell Berlin") + .dt_compat = berlin_dt_compat, + .init_machine = berlin_init_machine, +MACHINE_END diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c index 134641d688bb..a1935911e4f1 100644 --- a/arch/arm/mach-clps711x/common.c +++ b/arch/arm/mach-clps711x/common.c @@ -259,7 +259,7 @@ asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs) } while (1); } -static u32 notrace clps711x_sched_clock_read(void) +static u64 notrace clps711x_sched_clock_read(void) { return ~readw_relaxed(CLPS711X_VIRT_BASE + TC1D); } @@ -366,7 +366,7 @@ void __init clps711x_timer_init(void) tmp = clps_readl(SYSCON1) & ~(SYSCON1_TC1S | SYSCON1_TC1M); clps_writel(tmp, SYSCON1); - setup_sched_clock(clps711x_sched_clock_read, 16, timl); + sched_clock_register(clps711x_sched_clock_read, 16, timl); clocksource_mmio_init(CLPS711X_VIRT_BASE + TC1D, "clps711x_clocksource", timl, 300, 16, diff --git a/arch/arm/mach-clps711x/devices.c b/arch/arm/mach-clps711x/devices.c index fb77d1448fec..2001488a5ef2 100644 --- a/arch/arm/mach-clps711x/devices.c +++ b/arch/arm/mach-clps711x/devices.c @@ -61,8 +61,29 @@ static void __init clps711x_add_syscon(void) &clps711x_syscon_res[i], 1); } +static const struct resource clps711x_uart1_res[] __initconst = { + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + UARTDR1, SZ_128), + DEFINE_RES_IRQ(IRQ_UTXINT1), + DEFINE_RES_IRQ(IRQ_URXINT1), +}; + +static const struct resource clps711x_uart2_res[] __initconst = { + DEFINE_RES_MEM(CLPS711X_PHYS_BASE + UARTDR2, SZ_128), + DEFINE_RES_IRQ(IRQ_UTXINT2), + DEFINE_RES_IRQ(IRQ_URXINT2), +}; + +static void __init clps711x_add_uart(void) +{ + platform_device_register_simple("clps711x-uart", 0, clps711x_uart1_res, + ARRAY_SIZE(clps711x_uart1_res)); + platform_device_register_simple("clps711x-uart", 1, clps711x_uart2_res, + ARRAY_SIZE(clps711x_uart2_res)); +}; + void __init clps711x_devices_init(void) { clps711x_add_gpio(); clps711x_add_syscon(); + clps711x_add_uart(); } diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index dc9a470ff9c5..985e5fd00fb2 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -133,7 +133,7 @@ EXPORT_SYMBOL(clk_get_rate); long clk_round_rate(struct clk *clk, unsigned long rate) { if (clk == NULL || IS_ERR(clk)) - return -EINVAL; + return 0; if (clk->round_rate) return clk->round_rate(clk, rate); diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 0813b5167e05..115d5736da80 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -385,7 +385,7 @@ static struct clk_lookup da830_clks[] = { CLK(NULL, "pll0_sysclk7", &pll0_sysclk7), CLK("i2c_davinci.1", NULL, &i2c0_clk), CLK(NULL, "timer0", &timerp64_0_clk), - CLK("watchdog", NULL, &timerp64_1_clk), + CLK("davinci-wdt", NULL, &timerp64_1_clk), CLK(NULL, "arm_rom", &arm_rom_clk), CLK(NULL, "scr0_ss", &scr0_ss_clk), CLK(NULL, "scr1_ss", &scr1_ss_clk), @@ -1153,7 +1153,6 @@ static struct davinci_id da830_ids[] = { static struct davinci_gpio_platform_data da830_gpio_platform_data = { .ngpio = 128, - .intc_irq_num = DA830_N_CP_INTC_IRQ, }; int __init da830_register_gpio(void) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 352984e1528a..2ab00434b2eb 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -443,7 +443,7 @@ static struct clk_lookup da850_clks[] = { CLK(NULL, "pll1_sysclk3", &pll1_sysclk3), CLK("i2c_davinci.1", NULL, &i2c0_clk), CLK(NULL, "timer0", &timerp64_0_clk), - CLK("watchdog", NULL, &timerp64_1_clk), + CLK("davinci-wdt", NULL, &timerp64_1_clk), CLK(NULL, "arm_rom", &arm_rom_clk), CLK(NULL, "tpcc0", &tpcc0_clk), CLK(NULL, "tptc0", &tptc0_clk), @@ -1283,7 +1283,6 @@ int __init da850_register_vpif_capture(struct vpif_capture_config static struct davinci_gpio_platform_data da850_gpio_platform_data = { .ngpio = 144, - .intc_irq_num = DA850_N_CP_INTC_IRQ, }; int __init da850_register_gpio(void) diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c index d2bc574ae172..ed1928740b5f 100644 --- a/arch/arm/mach-davinci/da8xx-dt.c +++ b/arch/arm/mach-davinci/da8xx-dt.c @@ -32,7 +32,7 @@ static void __init da8xx_init_irq(void) static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL), - OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "watchdog", NULL), + OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL), OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL), OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL), OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL), diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 78829c513fdc..0486cdf28c8d 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -389,7 +389,7 @@ static struct resource da8xx_watchdog_resources[] = { }; static struct platform_device da8xx_wdt_device = { - .name = "watchdog", + .name = "davinci-wdt", .id = -1, .num_resources = ARRAY_SIZE(da8xx_watchdog_resources), .resource = da8xx_watchdog_resources, @@ -399,7 +399,7 @@ void da8xx_restart(enum reboot_mode mode, const char *cmd) { struct device *dev; - dev = bus_find_device_by_name(&platform_bus_type, NULL, "watchdog"); + dev = bus_find_device_by_name(&platform_bus_type, NULL, "davinci-wdt"); if (!dev) { pr_err("%s: failed to find watchdog device\n", __func__); return; diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 3996e98f52fb..5cf9a027dcc6 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -302,7 +302,7 @@ static struct resource wdt_resources[] = { }; struct platform_device davinci_wdt_device = { - .name = "watchdog", + .name = "davinci-wdt", .id = -1, .num_resources = ARRAY_SIZE(wdt_resources), .resource = wdt_resources, diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 6117fc644188..4668c0e19767 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -375,7 +375,7 @@ static struct clk_lookup dm355_clks[] = { CLK(NULL, "pwm3", &pwm3_clk), CLK(NULL, "timer0", &timer0_clk), CLK(NULL, "timer1", &timer1_clk), - CLK("watchdog", NULL, &timer2_clk), + CLK("davinci-wdt", NULL, &timer2_clk), CLK(NULL, "timer3", &timer3_clk), CLK(NULL, "rto", &rto_clk), CLK(NULL, "usb", &usb_clk), @@ -901,7 +901,6 @@ static struct resource dm355_gpio_resources[] = { static struct davinci_gpio_platform_data dm355_gpio_platform_data = { .ngpio = 104, - .intc_irq_num = DAVINCI_N_AINTC_IRQ, }; int __init dm355_gpio_register(void) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index d7c6f85d3fc9..b44b49e2801a 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -473,7 +473,7 @@ static struct clk_lookup dm365_clks[] = { CLK(NULL, "pwm3", &pwm3_clk), CLK(NULL, "timer0", &timer0_clk), CLK(NULL, "timer1", &timer1_clk), - CLK("watchdog", NULL, &timer2_clk), + CLK("davinci-wdt", NULL, &timer2_clk), CLK(NULL, "timer3", &timer3_clk), CLK(NULL, "usb", &usb_clk), CLK("davinci_emac.1", NULL, &emac_clk), @@ -713,7 +713,6 @@ static struct resource dm365_gpio_resources[] = { static struct davinci_gpio_platform_data dm365_gpio_platform_data = { .ngpio = 104, - .intc_irq_num = DAVINCI_N_AINTC_IRQ, .gpio_unbanked = 8, }; diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 3ce47997bb46..5c3e0be95ef3 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -322,7 +322,7 @@ static struct clk_lookup dm644x_clks[] = { CLK(NULL, "pwm2", &pwm2_clk), CLK(NULL, "timer0", &timer0_clk), CLK(NULL, "timer1", &timer1_clk), - CLK("watchdog", NULL, &timer2_clk), + CLK("davinci-wdt", NULL, &timer2_clk), CLK(NULL, NULL, NULL), }; @@ -787,7 +787,6 @@ static struct resource dm644_gpio_resources[] = { static struct davinci_gpio_platform_data dm644_gpio_platform_data = { .ngpio = 71, - .intc_irq_num = DAVINCI_N_AINTC_IRQ, }; int __init dm644x_gpio_register(void) diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 0e81fea65e7f..81768dd47096 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -356,7 +356,7 @@ static struct clk_lookup dm646x_clks[] = { CLK(NULL, "pwm1", &pwm1_clk), CLK(NULL, "timer0", &timer0_clk), CLK(NULL, "timer1", &timer1_clk), - CLK("watchdog", NULL, &timer2_clk), + CLK("davinci-wdt", NULL, &timer2_clk), CLK("palm_bk3710", NULL, &ide_clk), CLK(NULL, "vpif0", &vpif0_clk), CLK(NULL, "vpif1", &vpif1_clk), @@ -763,7 +763,6 @@ static struct resource dm646x_gpio_resources[] = { static struct davinci_gpio_platform_data dm646x_gpio_platform_data = { .ngpio = 43, - .intc_irq_num = DAVINCI_N_AINTC_IRQ, }; int __init dm646x_gpio_register(void) diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 56c6eb5266ad..24ad30f32ae3 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -285,7 +285,7 @@ static struct clocksource clocksource_davinci = { /* * Overwrite weak default sched_clock with something more precise */ -static u32 notrace davinci_read_sched_clock(void) +static u64 notrace davinci_read_sched_clock(void) { return timer32_read(&timers[TID_CLOCKSOURCE]); } @@ -391,7 +391,7 @@ void __init davinci_timer_init(void) davinci_clock_tick_rate)) printk(err, clocksource_davinci.name); - setup_sched_clock(davinci_read_sched_clock, 32, + sched_clock_register(davinci_read_sched_clock, 32, davinci_clock_tick_rate); /* setup clockevent */ diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index c122bcff9f7c..0d1a89298ece 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -162,7 +162,7 @@ void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) /***************************************************************************** * SoC RTC ****************************************************************************/ -void __init dove_rtc_init(void) +static void __init dove_rtc_init(void) { orion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC); } @@ -256,19 +256,10 @@ void __init dove_timer_init(void) IRQ_DOVE_BRIDGE, dove_tclk); } -/***************************************************************************** - * Cryptographic Engines and Security Accelerator (CESA) - ****************************************************************************/ -void __init dove_crypto_init(void) -{ - orion_crypto_init(DOVE_CRYPT_PHYS_BASE, DOVE_CESA_PHYS_BASE, - DOVE_CESA_SIZE, IRQ_DOVE_CRYPTO); -} - /***************************************************************************** * XOR 0 ****************************************************************************/ -void __init dove_xor0_init(void) +static void __init dove_xor0_init(void) { orion_xor0_init(DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE, IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01); @@ -277,7 +268,7 @@ void __init dove_xor0_init(void) /***************************************************************************** * XOR 1 ****************************************************************************/ -void __init dove_xor1_init(void) +static void __init dove_xor1_init(void) { orion_xor1_init(DOVE_XOR1_PHYS_BASE, DOVE_XOR1_HIGH_PHYS_BASE, IRQ_DOVE_XOR_10, IRQ_DOVE_XOR_11); diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile new file mode 100644 index 000000000000..3a74af7413e8 --- /dev/null +++ b/arch/arm/mach-efm32/Makefile @@ -0,0 +1 @@ +obj-y += dtmachine.o diff --git a/arch/arm/mach-efm32/Makefile.boot b/arch/arm/mach-efm32/Makefile.boot new file mode 100644 index 000000000000..eacfc3f5c33e --- /dev/null +++ b/arch/arm/mach-efm32/Makefile.boot @@ -0,0 +1,3 @@ +# Empty file waiting for deletion once Makefile.boot isn't needed any more. +# Patch waits for application at +# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . diff --git a/arch/arm/mach-efm32/dtmachine.c b/arch/arm/mach-efm32/dtmachine.c new file mode 100644 index 000000000000..2367495193c1 --- /dev/null +++ b/arch/arm/mach-efm32/dtmachine.c @@ -0,0 +1,15 @@ +#include + +#include + +#include + +static const char *const efm32gg_compat[] __initconst = { + "efm32,dk3750", + NULL +}; + +DT_MACHINE_START(EFM32DT, "EFM32 (Device Tree Support)") + .dt_compat = efm32gg_compat, + .restart = armv7m_restart, +MACHINE_END diff --git a/arch/arm/mach-efm32/include/mach/entry-macro.S b/arch/arm/mach-efm32/include/mach/entry-macro.S new file mode 100644 index 000000000000..322159d5ed91 --- /dev/null +++ b/arch/arm/mach-efm32/include/mach/entry-macro.S @@ -0,0 +1,4 @@ +/* + * Empty file waiting for deletion once isn't needed any + * more. Patch "ARM: v7-M: drop using mach/entry-macro.S" sitting in next. + */ diff --git a/arch/arm/mach-efm32/include/mach/timex.h b/arch/arm/mach-efm32/include/mach/timex.h new file mode 100644 index 000000000000..7a8b26da6599 --- /dev/null +++ b/arch/arm/mach-efm32/include/mach/timex.h @@ -0,0 +1,3 @@ +/* + * Empty file waiting for deletion once isn't needed any more. + */ diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index 93e54fd4e3d5..bec570ae6494 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -5,6 +5,7 @@ menu "Cirrus EP93xx Implementation Options" config EP93XX_SOC_COMMON bool default y + select SOC_BUS select LEDS_GPIO_REGISTER config CRUNCH diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index d95ee28a616a..157ba88433c9 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include +#include #include #include @@ -137,7 +139,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) static struct irqaction ep93xx_timer_irq = { .name = "ep93xx timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_TIMER | IRQF_IRQPOLL, .handler = ep93xx_timer_interrupt, }; @@ -925,8 +927,108 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev) } EXPORT_SYMBOL(ep93xx_ide_release_gpio); -void __init ep93xx_init_devices(void) +/************************************************************************* + * EP93xx Security peripheral + *************************************************************************/ + +/* + * The Maverick Key is 256 bits of micro fuses blown at the factory during + * manufacturing to uniquely identify a part. + * + * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key + */ +#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x)) +#define EP93XX_SECURITY_SECFLG EP93XX_SECURITY_REG(0x2400) +#define EP93XX_SECURITY_FUSEFLG EP93XX_SECURITY_REG(0x2410) +#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440) +#define EP93XX_SECURITY_UNIQCHK EP93XX_SECURITY_REG(0x2450) +#define EP93XX_SECURITY_UNIQVAL EP93XX_SECURITY_REG(0x2460) +#define EP93XX_SECURITY_SECID1 EP93XX_SECURITY_REG(0x2500) +#define EP93XX_SECURITY_SECID2 EP93XX_SECURITY_REG(0x2504) +#define EP93XX_SECURITY_SECCHK1 EP93XX_SECURITY_REG(0x2520) +#define EP93XX_SECURITY_SECCHK2 EP93XX_SECURITY_REG(0x2524) +#define EP93XX_SECURITY_UNIQID2 EP93XX_SECURITY_REG(0x2700) +#define EP93XX_SECURITY_UNIQID3 EP93XX_SECURITY_REG(0x2704) +#define EP93XX_SECURITY_UNIQID4 EP93XX_SECURITY_REG(0x2708) +#define EP93XX_SECURITY_UNIQID5 EP93XX_SECURITY_REG(0x270c) + +static char ep93xx_soc_id[33]; + +static const char __init *ep93xx_get_soc_id(void) { + unsigned int id, id2, id3, id4, id5; + + if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1) + return "bad Hamming code"; + + id = __raw_readl(EP93XX_SECURITY_UNIQID); + id2 = __raw_readl(EP93XX_SECURITY_UNIQID2); + id3 = __raw_readl(EP93XX_SECURITY_UNIQID3); + id4 = __raw_readl(EP93XX_SECURITY_UNIQID4); + id5 = __raw_readl(EP93XX_SECURITY_UNIQID5); + + if (id != id2) + return "invalid"; + + snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id), + "%08x%08x%08x%08x", id2, id3, id4, id5); + + return ep93xx_soc_id; +} + +static const char __init *ep93xx_get_soc_rev(void) +{ + int rev = ep93xx_chip_revision(); + + switch (rev) { + case EP93XX_CHIP_REV_D0: + return "D0"; + case EP93XX_CHIP_REV_D1: + return "D1"; + case EP93XX_CHIP_REV_E0: + return "E0"; + case EP93XX_CHIP_REV_E1: + return "E1"; + case EP93XX_CHIP_REV_E2: + return "E2"; + default: + return "unknown"; + } +} + +static const char __init *ep93xx_get_machine_name(void) +{ + return kasprintf(GFP_KERNEL,"%s", machine_desc->name); +} + +static struct device __init *ep93xx_init_soc(void) +{ + struct soc_device_attribute *soc_dev_attr; + struct soc_device *soc_dev; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return NULL; + + soc_dev_attr->machine = ep93xx_get_machine_name(); + soc_dev_attr->family = "Cirrus Logic EP93xx"; + soc_dev_attr->revision = ep93xx_get_soc_rev(); + soc_dev_attr->soc_id = ep93xx_get_soc_id(); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->machine); + kfree(soc_dev_attr); + return NULL; + } + + return soc_device_to_device(soc_dev); +} + +struct device __init *ep93xx_init_devices(void) +{ + struct device *parent; + /* Disallow access to MaverickCrunch initially */ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); @@ -937,6 +1039,8 @@ void __init ep93xx_init_devices(void) EP93XX_SYSCON_DEVCFG_GONIDE | EP93XX_SYSCON_DEVCFG_HONIDE); + parent = ep93xx_init_soc(); + /* Get the GPIO working early, other devices need it */ platform_device_register(&ep93xx_gpio_device); @@ -949,6 +1053,8 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_wdt_device); gpio_led_register_device(-1, &ep93xx_led_data); + + return parent; } void ep93xx_restart(enum reboot_mode mode, const char *cmd) diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index e256e0baec2e..4c0bbd97f741 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -6,6 +6,7 @@ #include +struct device; struct i2c_gpio_platform_data; struct i2c_board_info; struct spi_board_info; @@ -54,7 +55,7 @@ void ep93xx_register_ide(void); int ep93xx_ide_acquire_gpio(struct platform_device *pdev); void ep93xx_ide_release_gpio(struct platform_device *pdev); -void ep93xx_init_devices(void); +struct device *ep93xx_init_devices(void); extern void ep93xx_timer_init(void); void ep93xx_restart(enum reboot_mode, const char *); diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index f9d67a0acb2a..4c414af75ef0 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -24,6 +24,7 @@ config ARCH_EXYNOS4 select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select PINCTRL + select PM_GENERIC_DOMAINS if PM select S5P_DEV_MFC help Samsung EXYNOS4 SoCs based systems @@ -48,7 +49,6 @@ config CPU_EXYNOS4210 select ARCH_HAS_BANDGAP select ARM_CPU_SUSPEND if PM select PINCTRL_EXYNOS - select PM_GENERIC_DOMAINS if PM select S5P_PM if PM select S5P_SLEEP if PM select SAMSUNG_DMADEV @@ -61,7 +61,6 @@ config SOC_EXYNOS4212 depends on ARCH_EXYNOS4 select ARCH_HAS_BANDGAP select PINCTRL_EXYNOS - select PM_GENERIC_DOMAINS if PM select S5P_PM if PM select S5P_SLEEP if PM select SAMSUNG_DMADEV @@ -74,7 +73,6 @@ config SOC_EXYNOS4412 depends on ARCH_EXYNOS4 select ARCH_HAS_BANDGAP select PINCTRL_EXYNOS - select PM_GENERIC_DOMAINS if PM select SAMSUNG_DMADEV help Enable EXYNOS4412 SoC support diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index 61d2906ccefb..f18be40e5b21 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -37,14 +38,13 @@ #include #include -#include -#include - #include #include #include #include "common.h" +#include "regs-pmu.h" + #define L2_AUX_VAL 0x7C470001 #define L2_AUX_MASK 0xC200ffff @@ -303,13 +303,18 @@ void __init exynos_cpuidle_init(void) platform_device_register(&exynos_cpuidle); } +void __init exynos_cpufreq_init(void) +{ + platform_device_register_simple("exynos-cpufreq", -1, NULL, 0); +} + void __init exynos_init_late(void) { if (of_machine_is_compatible("samsung,exynos5440")) /* to be supported later */ return; - exynos_pm_late_initcall(); + pm_genpd_poweroff_unused(); } static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname, diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index ff9b6a9419b0..f76967b1c551 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -22,16 +22,11 @@ void exynos_init_io(void); void exynos4_restart(enum reboot_mode mode, const char *cmd); void exynos5_restart(enum reboot_mode mode, const char *cmd); void exynos_cpuidle_init(void); +void exynos_cpufreq_init(void); void exynos_init_late(void); void exynos_firmware_init(void); -#ifdef CONFIG_PM_GENERIC_DOMAINS -int exynos_pm_late_initcall(void); -#else -static inline int exynos_pm_late_initcall(void) { return 0; } -#endif - extern struct smp_operations exynos_smp_ops; extern void exynos_cpu_die(unsigned int cpu); diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index ddbfe8709fe7..f57cb91f02aa 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -22,13 +22,15 @@ #include #include #include -#include -#include #include #include +#include +#include + #include "common.h" +#include "regs-pmu.h" #define REG_DIRECTGO_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \ S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \ @@ -39,6 +41,25 @@ #define S5P_CHECK_AFTR 0xFCBA0D10 +#define EXYNOS5_PWR_CTRL1 (S5P_VA_CMU + 0x01020) +#define EXYNOS5_PWR_CTRL2 (S5P_VA_CMU + 0x01024) + +#define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) +#define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) +#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9) +#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8) +#define PWR_CTRL1_USE_CORE1_WFE (1 << 5) +#define PWR_CTRL1_USE_CORE0_WFE (1 << 4) +#define PWR_CTRL1_USE_CORE1_WFI (1 << 1) +#define PWR_CTRL1_USE_CORE0_WFI (1 << 0) + +#define PWR_CTRL2_DIV2_UP_EN (1 << 25) +#define PWR_CTRL2_DIV1_UP_EN (1 << 24) +#define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16) +#define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8) +#define PWR_CTRL2_CORE2_UP_RATIO (1 << 4) +#define PWR_CTRL2_CORE1_UP_RATIO (1 << 0) + static int exynos4_enter_lowpower(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); @@ -151,8 +172,8 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev, { int new_index = index; - /* This mode only can be entered when other core's are offline */ - if (num_online_cpus() > 1) + /* AFTR can only be entered when cores other than CPU0 are offline */ + if (num_online_cpus() > 1 || dev->cpu != 0) new_index = drv->safe_state_index; if (new_index == 0) @@ -214,10 +235,6 @@ static int exynos_cpuidle_probe(struct platform_device *pdev) device = &per_cpu(exynos4_cpuidle_device, cpu_id); device->cpu = cpu_id; - /* Support IDLE only */ - if (cpu_id != 0) - device->state_count = 1; - ret = cpuidle_register_device(device); if (ret) { dev_err(&pdev->dev, "failed to register cpuidle device\n"); diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c index af90cfa2f826..5eead530c6f8 100644 --- a/arch/arm/mach-exynos/hotplug.c +++ b/arch/arm/mach-exynos/hotplug.c @@ -19,10 +19,10 @@ #include #include -#include #include #include "common.h" +#include "regs-pmu.h" static inline void cpu_enter_lowpower_a9(void) { diff --git a/arch/arm/mach-exynos/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h index 2b00833b6641..dc0697c2fa92 100644 --- a/arch/arm/mach-exynos/include/mach/pm-core.h +++ b/arch/arm/mach-exynos/include/mach/pm-core.h @@ -19,7 +19,10 @@ #define __ASM_ARCH_PM_CORE_H __FILE__ #include -#include +#include + +#define S5P_EINT_WAKEUP_MASK (S5P_VA_PMU + 0x0604) +#define S5P_WAKEUP_MASK (S5P_VA_PMU + 0x0608) #ifdef CONFIG_PINCTRL_EXYNOS extern u32 exynos_get_eint_wake_mask(void); diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h deleted file mode 100644 index d36ad76ad6a4..000000000000 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ /dev/null @@ -1,372 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/regs-clock.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - Clock register definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_REGS_CLOCK_H -#define __ASM_ARCH_REGS_CLOCK_H __FILE__ - -#include -#include - -#define EXYNOS_CLKREG(x) (S5P_VA_CMU + (x)) - -#define EXYNOS4_CLKDIV_LEFTBUS EXYNOS_CLKREG(0x04500) -#define EXYNOS4_CLKDIV_STAT_LEFTBUS EXYNOS_CLKREG(0x04600) -#define EXYNOS4_CLKGATE_IP_LEFTBUS EXYNOS_CLKREG(0x04800) - -#define EXYNOS4_CLKDIV_RIGHTBUS EXYNOS_CLKREG(0x08500) -#define EXYNOS4_CLKDIV_STAT_RIGHTBUS EXYNOS_CLKREG(0x08600) -#define EXYNOS4_CLKGATE_IP_RIGHTBUS EXYNOS_CLKREG(0x08800) - -#define EXYNOS4_EPLL_LOCK EXYNOS_CLKREG(0x0C010) -#define EXYNOS4_VPLL_LOCK EXYNOS_CLKREG(0x0C020) - -#define EXYNOS4_EPLL_CON0 EXYNOS_CLKREG(0x0C110) -#define EXYNOS4_EPLL_CON1 EXYNOS_CLKREG(0x0C114) -#define EXYNOS4_VPLL_CON0 EXYNOS_CLKREG(0x0C120) -#define EXYNOS4_VPLL_CON1 EXYNOS_CLKREG(0x0C124) - -#define EXYNOS4_CLKSRC_TOP0 EXYNOS_CLKREG(0x0C210) -#define EXYNOS4_CLKSRC_TOP1 EXYNOS_CLKREG(0x0C214) -#define EXYNOS4_CLKSRC_CAM EXYNOS_CLKREG(0x0C220) -#define EXYNOS4_CLKSRC_TV EXYNOS_CLKREG(0x0C224) -#define EXYNOS4_CLKSRC_MFC EXYNOS_CLKREG(0x0C228) -#define EXYNOS4_CLKSRC_G3D EXYNOS_CLKREG(0x0C22C) -#define EXYNOS4_CLKSRC_IMAGE EXYNOS_CLKREG(0x0C230) -#define EXYNOS4_CLKSRC_LCD0 EXYNOS_CLKREG(0x0C234) -#define EXYNOS4_CLKSRC_MAUDIO EXYNOS_CLKREG(0x0C23C) -#define EXYNOS4_CLKSRC_FSYS EXYNOS_CLKREG(0x0C240) -#define EXYNOS4_CLKSRC_PERIL0 EXYNOS_CLKREG(0x0C250) -#define EXYNOS4_CLKSRC_PERIL1 EXYNOS_CLKREG(0x0C254) - -#define EXYNOS4_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x0C310) -#define EXYNOS4_CLKSRC_MASK_CAM EXYNOS_CLKREG(0x0C320) -#define EXYNOS4_CLKSRC_MASK_TV EXYNOS_CLKREG(0x0C324) -#define EXYNOS4_CLKSRC_MASK_LCD0 EXYNOS_CLKREG(0x0C334) -#define EXYNOS4_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x0C33C) -#define EXYNOS4_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x0C340) -#define EXYNOS4_CLKSRC_MASK_PERIL0 EXYNOS_CLKREG(0x0C350) -#define EXYNOS4_CLKSRC_MASK_PERIL1 EXYNOS_CLKREG(0x0C354) - -#define EXYNOS4_CLKDIV_TOP EXYNOS_CLKREG(0x0C510) -#define EXYNOS4_CLKDIV_CAM EXYNOS_CLKREG(0x0C520) -#define EXYNOS4_CLKDIV_TV EXYNOS_CLKREG(0x0C524) -#define EXYNOS4_CLKDIV_MFC EXYNOS_CLKREG(0x0C528) -#define EXYNOS4_CLKDIV_G3D EXYNOS_CLKREG(0x0C52C) -#define EXYNOS4_CLKDIV_IMAGE EXYNOS_CLKREG(0x0C530) -#define EXYNOS4_CLKDIV_LCD0 EXYNOS_CLKREG(0x0C534) -#define EXYNOS4_CLKDIV_MAUDIO EXYNOS_CLKREG(0x0C53C) -#define EXYNOS4_CLKDIV_FSYS0 EXYNOS_CLKREG(0x0C540) -#define EXYNOS4_CLKDIV_FSYS1 EXYNOS_CLKREG(0x0C544) -#define EXYNOS4_CLKDIV_FSYS2 EXYNOS_CLKREG(0x0C548) -#define EXYNOS4_CLKDIV_FSYS3 EXYNOS_CLKREG(0x0C54C) -#define EXYNOS4_CLKDIV_PERIL0 EXYNOS_CLKREG(0x0C550) -#define EXYNOS4_CLKDIV_PERIL1 EXYNOS_CLKREG(0x0C554) -#define EXYNOS4_CLKDIV_PERIL2 EXYNOS_CLKREG(0x0C558) -#define EXYNOS4_CLKDIV_PERIL3 EXYNOS_CLKREG(0x0C55C) -#define EXYNOS4_CLKDIV_PERIL4 EXYNOS_CLKREG(0x0C560) -#define EXYNOS4_CLKDIV_PERIL5 EXYNOS_CLKREG(0x0C564) -#define EXYNOS4_CLKDIV2_RATIO EXYNOS_CLKREG(0x0C580) - -#define EXYNOS4_CLKDIV_STAT_TOP EXYNOS_CLKREG(0x0C610) -#define EXYNOS4_CLKDIV_STAT_MFC EXYNOS_CLKREG(0x0C628) - -#define EXYNOS4_CLKGATE_SCLKCAM EXYNOS_CLKREG(0x0C820) -#define EXYNOS4_CLKGATE_IP_CAM EXYNOS_CLKREG(0x0C920) -#define EXYNOS4_CLKGATE_IP_TV EXYNOS_CLKREG(0x0C924) -#define EXYNOS4_CLKGATE_IP_MFC EXYNOS_CLKREG(0x0C928) -#define EXYNOS4_CLKGATE_IP_G3D EXYNOS_CLKREG(0x0C92C) -#define EXYNOS4_CLKGATE_IP_IMAGE (soc_is_exynos4210() ? \ - EXYNOS_CLKREG(0x0C930) : \ - EXYNOS_CLKREG(0x04930)) -#define EXYNOS4210_CLKGATE_IP_IMAGE EXYNOS_CLKREG(0x0C930) -#define EXYNOS4212_CLKGATE_IP_IMAGE EXYNOS_CLKREG(0x04930) -#define EXYNOS4_CLKGATE_IP_LCD0 EXYNOS_CLKREG(0x0C934) -#define EXYNOS4_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x0C940) -#define EXYNOS4_CLKGATE_IP_GPS EXYNOS_CLKREG(0x0C94C) -#define EXYNOS4_CLKGATE_IP_PERIL EXYNOS_CLKREG(0x0C950) -#define EXYNOS4_CLKGATE_IP_PERIR (soc_is_exynos4210() ? \ - EXYNOS_CLKREG(0x0C960) : \ - EXYNOS_CLKREG(0x08960)) -#define EXYNOS4210_CLKGATE_IP_PERIR EXYNOS_CLKREG(0x0C960) -#define EXYNOS4212_CLKGATE_IP_PERIR EXYNOS_CLKREG(0x08960) -#define EXYNOS4_CLKGATE_BLOCK EXYNOS_CLKREG(0x0C970) - -#define EXYNOS4_CLKSRC_MASK_DMC EXYNOS_CLKREG(0x10300) -#define EXYNOS4_CLKSRC_DMC EXYNOS_CLKREG(0x10200) -#define EXYNOS4_CLKDIV_DMC0 EXYNOS_CLKREG(0x10500) -#define EXYNOS4_CLKDIV_DMC1 EXYNOS_CLKREG(0x10504) -#define EXYNOS4_CLKDIV_STAT_DMC0 EXYNOS_CLKREG(0x10600) -#define EXYNOS4_CLKDIV_STAT_DMC1 EXYNOS_CLKREG(0x10604) -#define EXYNOS4_CLKGATE_IP_DMC EXYNOS_CLKREG(0x10900) - -#define EXYNOS4_DMC_PAUSE_CTRL EXYNOS_CLKREG(0x11094) -#define EXYNOS4_DMC_PAUSE_ENABLE (1 << 0) - -#define EXYNOS4_APLL_LOCK EXYNOS_CLKREG(0x14000) -#define EXYNOS4_MPLL_LOCK (soc_is_exynos4210() ? \ - EXYNOS_CLKREG(0x14004) : \ - EXYNOS_CLKREG(0x10008)) -#define EXYNOS4_APLL_CON0 EXYNOS_CLKREG(0x14100) -#define EXYNOS4_APLL_CON1 EXYNOS_CLKREG(0x14104) -#define EXYNOS4_MPLL_CON0 (soc_is_exynos4210() ? \ - EXYNOS_CLKREG(0x14108) : \ - EXYNOS_CLKREG(0x10108)) -#define EXYNOS4_MPLL_CON1 (soc_is_exynos4210() ? \ - EXYNOS_CLKREG(0x1410C) : \ - EXYNOS_CLKREG(0x1010C)) - -#define EXYNOS4_CLKSRC_CPU EXYNOS_CLKREG(0x14200) -#define EXYNOS4_CLKMUX_STATCPU EXYNOS_CLKREG(0x14400) - -#define EXYNOS4_CLKDIV_CPU EXYNOS_CLKREG(0x14500) -#define EXYNOS4_CLKDIV_CPU1 EXYNOS_CLKREG(0x14504) -#define EXYNOS4_CLKDIV_STATCPU EXYNOS_CLKREG(0x14600) -#define EXYNOS4_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x14604) - -#define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800) -#define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900) - -#define EXYNOS4_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x18800) -#define EXYNOS4_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x18804) - -#define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */ - -#define EXYNOS4_APLLCON0_ENABLE_SHIFT (31) -#define EXYNOS4_APLLCON0_LOCKED_SHIFT (29) -#define EXYNOS4_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) -#define EXYNOS4_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1) - -#define EXYNOS4_EPLLCON0_ENABLE_SHIFT (31) -#define EXYNOS4_EPLLCON0_LOCKED_SHIFT (29) - -#define EXYNOS4_VPLLCON0_ENABLE_SHIFT (31) -#define EXYNOS4_VPLLCON0_LOCKED_SHIFT (29) - -#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT (16) -#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT) - -#define EXYNOS4_CLKDIV_CPU0_CORE_SHIFT (0) -#define EXYNOS4_CLKDIV_CPU0_CORE_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT (4) -#define EXYNOS4_CLKDIV_CPU0_COREM0_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT (8) -#define EXYNOS4_CLKDIV_CPU0_COREM1_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT (12) -#define EXYNOS4_CLKDIV_CPU0_PERIPH_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_ATB_SHIFT (16) -#define EXYNOS4_CLKDIV_CPU0_ATB_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT (20) -#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_APLL_SHIFT (24) -#define EXYNOS4_CLKDIV_CPU0_APLL_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) -#define EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT 28 -#define EXYNOS4_CLKDIV_CPU0_CORE2_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT) - -#define EXYNOS4_CLKDIV_CPU1_COPY_SHIFT 0 -#define EXYNOS4_CLKDIV_CPU1_COPY_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) -#define EXYNOS4_CLKDIV_CPU1_HPM_SHIFT 4 -#define EXYNOS4_CLKDIV_CPU1_HPM_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) -#define EXYNOS4_CLKDIV_CPU1_CORES_SHIFT 8 -#define EXYNOS4_CLKDIV_CPU1_CORES_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT) - -#define EXYNOS4_CLKDIV_DMC0_ACP_SHIFT (0) -#define EXYNOS4_CLKDIV_DMC0_ACP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT (4) -#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT (8) -#define EXYNOS4_CLKDIV_DMC0_DPHY_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_DMC_SHIFT (12) -#define EXYNOS4_CLKDIV_DMC0_DMC_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT (16) -#define EXYNOS4_CLKDIV_DMC0_DMCD_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT (20) -#define EXYNOS4_CLKDIV_DMC0_DMCP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT (24) -#define EXYNOS4_CLKDIV_DMC0_COPY2_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) -#define EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT (28) -#define EXYNOS4_CLKDIV_DMC0_CORETI_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT) - -#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT (0) -#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK (0xf << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) -#define EXYNOS4_CLKDIV_DMC1_C2C_SHIFT (4) -#define EXYNOS4_CLKDIV_DMC1_C2C_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) -#define EXYNOS4_CLKDIV_DMC1_PWI_SHIFT (8) -#define EXYNOS4_CLKDIV_DMC1_PWI_MASK (0xf << EXYNOS4_CLKDIV_DMC1_PWI_SHIFT) -#define EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT (12) -#define EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT) -#define EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT (16) -#define EXYNOS4_CLKDIV_DMC1_DVSEM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT) -#define EXYNOS4_CLKDIV_DMC1_DPM_SHIFT (24) -#define EXYNOS4_CLKDIV_DMC1_DPM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DPM_SHIFT) - -#define EXYNOS4_CLKDIV_MFC_SHIFT (0) -#define EXYNOS4_CLKDIV_MFC_MASK (0x7 << EXYNOS4_CLKDIV_MFC_SHIFT) - -#define EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT (0) -#define EXYNOS4_CLKDIV_TOP_ACLK200_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) -#define EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT (4) -#define EXYNOS4_CLKDIV_TOP_ACLK100_MASK (0xF << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) -#define EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT (8) -#define EXYNOS4_CLKDIV_TOP_ACLK160_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) -#define EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT (12) -#define EXYNOS4_CLKDIV_TOP_ACLK133_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) -#define EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT (16) -#define EXYNOS4_CLKDIV_TOP_ONENAND_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT) -#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT (20) -#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) -#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT (24) -#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT) - -#define EXYNOS4_CLKDIV_BUS_GDLR_SHIFT (0) -#define EXYNOS4_CLKDIV_BUS_GDLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) -#define EXYNOS4_CLKDIV_BUS_GPLR_SHIFT (4) -#define EXYNOS4_CLKDIV_BUS_GPLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT) - -#define EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT (0) -#define EXYNOS4_CLKDIV_CAM_FIMC0_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) -#define EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT (4) -#define EXYNOS4_CLKDIV_CAM_FIMC1_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) -#define EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT (8) -#define EXYNOS4_CLKDIV_CAM_FIMC2_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) -#define EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT (12) -#define EXYNOS4_CLKDIV_CAM_FIMC3_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT) - -/* Only for EXYNOS4210 */ - -#define EXYNOS4210_CLKSRC_LCD1 EXYNOS_CLKREG(0x0C238) -#define EXYNOS4210_CLKSRC_MASK_LCD1 EXYNOS_CLKREG(0x0C338) -#define EXYNOS4210_CLKDIV_LCD1 EXYNOS_CLKREG(0x0C538) -#define EXYNOS4210_CLKGATE_IP_LCD1 EXYNOS_CLKREG(0x0C938) - -/* Only for EXYNOS4212 */ - -#define EXYNOS4_CLKDIV_CAM1 EXYNOS_CLKREG(0x0C568) - -#define EXYNOS4_CLKDIV_STAT_CAM1 EXYNOS_CLKREG(0x0C668) - -#define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT (0) -#define EXYNOS4_CLKDIV_CAM1_JPEG_MASK (0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT) - -/* For EXYNOS5250 */ - -#define EXYNOS5_APLL_LOCK EXYNOS_CLKREG(0x00000) -#define EXYNOS5_APLL_CON0 EXYNOS_CLKREG(0x00100) -#define EXYNOS5_CLKSRC_CPU EXYNOS_CLKREG(0x00200) -#define EXYNOS5_CLKMUX_STATCPU EXYNOS_CLKREG(0x00400) -#define EXYNOS5_CLKDIV_CPU0 EXYNOS_CLKREG(0x00500) -#define EXYNOS5_CLKDIV_CPU1 EXYNOS_CLKREG(0x00504) -#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) -#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) - -#define EXYNOS5_PWR_CTRL1 EXYNOS_CLKREG(0x01020) -#define EXYNOS5_PWR_CTRL2 EXYNOS_CLKREG(0x01024) - -#define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) -#define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) - -#define EXYNOS5_CLKGATE_IP_CORE EXYNOS_CLKREG(0x04900) - -#define EXYNOS5_CLKDIV_ACP EXYNOS_CLKREG(0x08500) - -#define EXYNOS5_EPLL_CON0 EXYNOS_CLKREG(0x10130) -#define EXYNOS5_EPLL_CON1 EXYNOS_CLKREG(0x10134) -#define EXYNOS5_EPLL_CON2 EXYNOS_CLKREG(0x10138) -#define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140) -#define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144) -#define EXYNOS5_VPLL_CON2 EXYNOS_CLKREG(0x10148) -#define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120) - -#define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210) -#define EXYNOS5_CLKSRC_TOP1 EXYNOS_CLKREG(0x10214) -#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218) -#define EXYNOS5_CLKSRC_TOP3 EXYNOS_CLKREG(0x1021C) -#define EXYNOS5_CLKSRC_GSCL EXYNOS_CLKREG(0x10220) -#define EXYNOS5_CLKSRC_DISP1_0 EXYNOS_CLKREG(0x1022C) -#define EXYNOS5_CLKSRC_MAUDIO EXYNOS_CLKREG(0x10240) -#define EXYNOS5_CLKSRC_FSYS EXYNOS_CLKREG(0x10244) -#define EXYNOS5_CLKSRC_PERIC0 EXYNOS_CLKREG(0x10250) -#define EXYNOS5_CLKSRC_PERIC1 EXYNOS_CLKREG(0x10254) -#define EXYNOS5_SCLK_SRC_ISP EXYNOS_CLKREG(0x10270) - -#define EXYNOS5_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x10310) -#define EXYNOS5_CLKSRC_MASK_GSCL EXYNOS_CLKREG(0x10320) -#define EXYNOS5_CLKSRC_MASK_DISP1_0 EXYNOS_CLKREG(0x1032C) -#define EXYNOS5_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x10334) -#define EXYNOS5_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x10340) -#define EXYNOS5_CLKSRC_MASK_PERIC0 EXYNOS_CLKREG(0x10350) -#define EXYNOS5_CLKSRC_MASK_PERIC1 EXYNOS_CLKREG(0x10354) - -#define EXYNOS5_CLKDIV_TOP0 EXYNOS_CLKREG(0x10510) -#define EXYNOS5_CLKDIV_TOP1 EXYNOS_CLKREG(0x10514) -#define EXYNOS5_CLKDIV_GSCL EXYNOS_CLKREG(0x10520) -#define EXYNOS5_CLKDIV_DISP1_0 EXYNOS_CLKREG(0x1052C) -#define EXYNOS5_CLKDIV_GEN EXYNOS_CLKREG(0x1053C) -#define EXYNOS5_CLKDIV_MAUDIO EXYNOS_CLKREG(0x10544) -#define EXYNOS5_CLKDIV_FSYS0 EXYNOS_CLKREG(0x10548) -#define EXYNOS5_CLKDIV_FSYS1 EXYNOS_CLKREG(0x1054C) -#define EXYNOS5_CLKDIV_FSYS2 EXYNOS_CLKREG(0x10550) -#define EXYNOS5_CLKDIV_FSYS3 EXYNOS_CLKREG(0x10554) -#define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558) -#define EXYNOS5_CLKDIV_PERIC1 EXYNOS_CLKREG(0x1055C) -#define EXYNOS5_CLKDIV_PERIC2 EXYNOS_CLKREG(0x10560) -#define EXYNOS5_CLKDIV_PERIC3 EXYNOS_CLKREG(0x10564) -#define EXYNOS5_CLKDIV_PERIC4 EXYNOS_CLKREG(0x10568) -#define EXYNOS5_CLKDIV_PERIC5 EXYNOS_CLKREG(0x1056C) -#define EXYNOS5_SCLK_DIV_ISP EXYNOS_CLKREG(0x10580) - -#define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800) -#define EXYNOS5_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x0C800) -#define EXYNOS5_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x0C804) -#define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920) -#define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928) -#define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C) -#define EXYNOS5_CLKGATE_IP_G3D EXYNOS_CLKREG(0x10930) -#define EXYNOS5_CLKGATE_IP_GEN EXYNOS_CLKREG(0x10934) -#define EXYNOS5_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x10944) -#define EXYNOS5_CLKGATE_IP_GPS EXYNOS_CLKREG(0x1094C) -#define EXYNOS5_CLKGATE_IP_PERIC EXYNOS_CLKREG(0x10950) -#define EXYNOS5_CLKGATE_IP_PERIS EXYNOS_CLKREG(0x10960) -#define EXYNOS5_CLKGATE_BLOCK EXYNOS_CLKREG(0x10980) - -#define EXYNOS5_BPLL_CON0 EXYNOS_CLKREG(0x20110) -#define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200) -#define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500) - -#define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24) - -#define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030) - -#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) - -#define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) -#define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) -#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9) -#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8) -#define PWR_CTRL1_USE_CORE1_WFE (1 << 5) -#define PWR_CTRL1_USE_CORE0_WFE (1 << 4) -#define PWR_CTRL1_USE_CORE1_WFI (1 << 1) -#define PWR_CTRL1_USE_CORE0_WFI (1 << 0) - -#define PWR_CTRL2_DIV2_UP_EN (1 << 25) -#define PWR_CTRL2_DIV1_UP_EN (1 << 24) -#define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16) -#define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8) -#define PWR_CTRL2_CORE2_UP_RATIO (1 << 4) -#define PWR_CTRL2_CORE1_UP_RATIO (1 << 0) - -/* Compatibility defines and inclusion */ - -#include - -#define S5P_EPLL_CON EXYNOS4_EPLL_CON0 - -#endif /* __ASM_ARCH_REGS_CLOCK_H */ diff --git a/arch/arm/mach-exynos/include/mach/regs-irq.h b/arch/arm/mach-exynos/include/mach/regs-irq.h deleted file mode 100644 index f2b50506b9f6..000000000000 --- a/arch/arm/mach-exynos/include/mach/regs-irq.h +++ /dev/null @@ -1,19 +0,0 @@ -/* linux/arch/arm/mach-exynos4/include/mach/regs-irq.h - * - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - IRQ register definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_REGS_IRQ_H -#define __ASM_ARCH_REGS_IRQ_H __FILE__ - -#include -#include - -#endif /* __ASM_ARCH_REGS_IRQ_H */ diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c index 4603e6bd424b..d3e54b7644d7 100644 --- a/arch/arm/mach-exynos/mach-exynos4-dt.c +++ b/arch/arm/mach-exynos/mach-exynos4-dt.c @@ -22,6 +22,7 @@ static void __init exynos4_dt_machine_init(void) { exynos_cpuidle_init(); + exynos_cpufreq_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 1fe075a70c1e..37ea261f0f6c 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -14,10 +14,10 @@ #include #include -#include #include #include "common.h" +#include "regs-pmu.h" static void __init exynos5_dt_machine_init(void) { @@ -44,6 +44,7 @@ static void __init exynos5_dt_machine_init(void) } exynos_cpuidle_init(); + exynos_cpufreq_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 58b43e6f9262..8ea02f63fed9 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -27,12 +27,11 @@ #include #include -#include -#include #include #include "common.h" +#include "regs-pmu.h" extern void exynos4_secondary_startup(void); @@ -64,8 +63,7 @@ static void write_pen_release(int val) { pen_release = val; smp_wmb(); - __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); - outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); + sync_cache_w(&pen_release); } static void __iomem *scu_base_addr(void) diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index c679db577269..e00025bbbe89 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -29,14 +29,37 @@ #include #include -#include -#include -#include +#include #include #include "common.h" +#include "regs-pmu.h" -static struct sleep_save exynos4_set_clksrc[] = { +#define EXYNOS4_EPLL_LOCK (S5P_VA_CMU + 0x0C010) +#define EXYNOS4_VPLL_LOCK (S5P_VA_CMU + 0x0C020) + +#define EXYNOS4_EPLL_CON0 (S5P_VA_CMU + 0x0C110) +#define EXYNOS4_EPLL_CON1 (S5P_VA_CMU + 0x0C114) +#define EXYNOS4_VPLL_CON0 (S5P_VA_CMU + 0x0C120) +#define EXYNOS4_VPLL_CON1 (S5P_VA_CMU + 0x0C124) + +#define EXYNOS4_CLKSRC_MASK_TOP (S5P_VA_CMU + 0x0C310) +#define EXYNOS4_CLKSRC_MASK_CAM (S5P_VA_CMU + 0x0C320) +#define EXYNOS4_CLKSRC_MASK_TV (S5P_VA_CMU + 0x0C324) +#define EXYNOS4_CLKSRC_MASK_LCD0 (S5P_VA_CMU + 0x0C334) +#define EXYNOS4_CLKSRC_MASK_MAUDIO (S5P_VA_CMU + 0x0C33C) +#define EXYNOS4_CLKSRC_MASK_FSYS (S5P_VA_CMU + 0x0C340) +#define EXYNOS4_CLKSRC_MASK_PERIL0 (S5P_VA_CMU + 0x0C350) +#define EXYNOS4_CLKSRC_MASK_PERIL1 (S5P_VA_CMU + 0x0C354) + +#define EXYNOS4_CLKSRC_MASK_DMC (S5P_VA_CMU + 0x10300) + +#define EXYNOS4_EPLLCON0_LOCKED_SHIFT (29) +#define EXYNOS4_VPLLCON0_LOCKED_SHIFT (29) + +#define EXYNOS4210_CLKSRC_MASK_LCD1 (S5P_VA_CMU + 0x0C338) + +static const struct sleep_save exynos4_set_clksrc[] = { { .reg = EXYNOS4_CLKSRC_MASK_TOP , .val = 0x00000001, }, { .reg = EXYNOS4_CLKSRC_MASK_CAM , .val = 0x11111111, }, { .reg = EXYNOS4_CLKSRC_MASK_TV , .val = 0x00000111, }, @@ -48,7 +71,7 @@ static struct sleep_save exynos4_set_clksrc[] = { { .reg = EXYNOS4_CLKSRC_MASK_DMC , .val = 0x00010000, }, }; -static struct sleep_save exynos4210_set_clksrc[] = { +static const struct sleep_save exynos4210_set_clksrc[] = { { .reg = EXYNOS4210_CLKSRC_MASK_LCD1 , .val = 0x00001111, }, }; diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 1703593e366c..8fd24882f0b1 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c @@ -22,9 +22,10 @@ #include #include -#include #include +#include "regs-pmu.h" + /* * Exynos specific wrapper around the generic power domain */ @@ -183,9 +184,3 @@ static __init int exynos4_pm_init_power_domain(void) return 0; } arch_initcall(exynos4_pm_init_power_domain); - -int __init exynos_pm_late_initcall(void) -{ - pm_genpd_poweroff_unused(); - return 0; -} diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c index 97d688526258..05c7ce15322a 100644 --- a/arch/arm/mach-exynos/pmu.c +++ b/arch/arm/mach-exynos/pmu.c @@ -13,13 +13,14 @@ #include #include -#include +#include #include "common.h" +#include "regs-pmu.h" -static struct exynos_pmu_conf *exynos_pmu_config; +static const struct exynos_pmu_conf *exynos_pmu_config; -static struct exynos_pmu_conf exynos4210_pmu_config[] = { +static const struct exynos_pmu_conf exynos4210_pmu_config[] = { /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, @@ -95,7 +96,7 @@ static struct exynos_pmu_conf exynos4210_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos_pmu_conf exynos4x12_pmu_config[] = { +static const struct exynos_pmu_conf exynos4x12_pmu_config[] = { { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, @@ -203,7 +204,7 @@ static struct exynos_pmu_conf exynos4x12_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos_pmu_conf exynos4412_pmu_config[] = { +static const struct exynos_pmu_conf exynos4412_pmu_config[] = { { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } }, { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } }, { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } }, @@ -213,7 +214,7 @@ static struct exynos_pmu_conf exynos4412_pmu_config[] = { { PMU_TABLE_END,}, }; -static struct exynos_pmu_conf exynos5250_pmu_config[] = { +static const struct exynos_pmu_conf exynos5250_pmu_config[] = { /* { .reg = address, .val = { AFTR, LPA, SLEEP } */ { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, @@ -317,7 +318,7 @@ static struct exynos_pmu_conf exynos5250_pmu_config[] = { { PMU_TABLE_END,}, }; -static void __iomem *exynos5_list_both_cnt_feed[] = { +static void __iomem * const exynos5_list_both_cnt_feed[] = { EXYNOS5_ARM_CORE0_OPTION, EXYNOS5_ARM_CORE1_OPTION, EXYNOS5_ARM_COMMON_OPTION, @@ -331,7 +332,7 @@ static void __iomem *exynos5_list_both_cnt_feed[] = { EXYNOS5_TOP_PWR_SYSMEM_OPTION, }; -static void __iomem *exynos5_list_diable_wfi_wfe[] = { +static void __iomem * const exynos5_list_diable_wfi_wfe[] = { EXYNOS5_ARM_CORE1_OPTION, EXYNOS5_FSYS_ARM_OPTION, EXYNOS5_ISP_ARM_OPTION, diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h similarity index 88% rename from arch/arm/mach-exynos/include/mach/regs-pmu.h rename to arch/arm/mach-exynos/regs-pmu.h index 2cdb63e8ce5c..7c029ce27711 100644 --- a/arch/arm/mach-exynos/include/mach/regs-pmu.h +++ b/arch/arm/mach-exynos/regs-pmu.h @@ -24,31 +24,16 @@ #define S5P_CENTRAL_SEQ_OPTION S5P_PMUREG(0x0208) #define S5P_USE_STANDBY_WFI0 (1 << 16) -#define S5P_USE_STANDBY_WFI1 (1 << 17) -#define S5P_USE_STANDBYWFI_ISP_ARM (1 << 18) #define S5P_USE_STANDBY_WFE0 (1 << 24) -#define S5P_USE_STANDBY_WFE1 (1 << 25) -#define S5P_USE_STANDBYWFE_ISP_ARM (1 << 26) #define S5P_SWRESET S5P_PMUREG(0x0400) #define EXYNOS_SWRESET S5P_PMUREG(0x0400) #define EXYNOS5440_SWRESET S5P_PMUREG(0x00C4) #define S5P_WAKEUP_STAT S5P_PMUREG(0x0600) -#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) -#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) - -#define S5P_HDMI_PHY_CONTROL S5P_PMUREG(0x0700) -#define S5P_HDMI_PHY_ENABLE (1 << 0) - -#define S5P_DAC_PHY_CONTROL S5P_PMUREG(0x070C) -#define S5P_DAC_PHY_ENABLE (1 << 0) #define S5P_INFORM0 S5P_PMUREG(0x0800) #define S5P_INFORM1 S5P_PMUREG(0x0804) -#define S5P_INFORM2 S5P_PMUREG(0x0808) -#define S5P_INFORM3 S5P_PMUREG(0x080C) -#define S5P_INFORM4 S5P_PMUREG(0x0810) #define S5P_INFORM5 S5P_PMUREG(0x0814) #define S5P_INFORM6 S5P_PMUREG(0x0818) #define S5P_INFORM7 S5P_PMUREG(0x081C) @@ -119,23 +104,8 @@ #define S5P_GPS_LOWPWR S5P_PMUREG(0x139C) #define S5P_GPS_ALIVE_LOWPWR S5P_PMUREG(0x13A0) -#define S5P_ARM_CORE0_CONFIGURATION S5P_PMUREG(0x2000) -#define S5P_ARM_CORE0_OPTION S5P_PMUREG(0x2008) #define S5P_ARM_CORE1_CONFIGURATION S5P_PMUREG(0x2080) #define S5P_ARM_CORE1_STATUS S5P_PMUREG(0x2084) -#define S5P_ARM_CORE1_OPTION S5P_PMUREG(0x2088) - -#define S5P_ARM_COMMON_OPTION S5P_PMUREG(0x2408) -#define S5P_TOP_PWR_OPTION S5P_PMUREG(0x2C48) -#define S5P_CAM_OPTION S5P_PMUREG(0x3C08) -#define S5P_TV_OPTION S5P_PMUREG(0x3C28) -#define S5P_MFC_OPTION S5P_PMUREG(0x3C48) -#define S5P_G3D_OPTION S5P_PMUREG(0x3C68) -#define S5P_LCD0_OPTION S5P_PMUREG(0x3C88) -#define S5P_LCD1_OPTION S5P_PMUREG(0x3CA8) -#define S5P_MAUDIO_OPTION S5P_PMUREG(0x3CC8) -#define S5P_GPS_OPTION S5P_PMUREG(0x3CE8) -#define S5P_GPS_ALIVE_OPTION S5P_PMUREG(0x3D08) #define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028) #define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108) @@ -145,28 +115,12 @@ #define S5P_PAD_RET_EBIA_OPTION S5P_PMUREG(0x3188) #define S5P_PAD_RET_EBIB_OPTION S5P_PMUREG(0x31A8) -#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00) -#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20) -#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40) -#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60) -#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80) -#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0) - -#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1 #define S5P_CORE_LOCAL_PWR_EN 0x3 #define S5P_INT_LOCAL_PWR_EN 0x7 #define S5P_CHECK_SLEEP 0x00000BAD /* Only for EXYNOS4210 */ -#define S5P_USBDEVICE_PHY_CONTROL S5P_PMUREG(0x0704) -#define S5P_USBDEVICE_PHY_ENABLE (1 << 0) - -#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708) -#define S5P_USBHOST_PHY_ENABLE (1 << 0) - -#define S5P_PMU_SATA_PHY_CONTROL S5P_PMUREG(0x0720) - #define S5P_CMU_CLKSTOP_LCD1_LOWPWR S5P_PMUREG(0x1154) #define S5P_CMU_RESET_LCD1_LOWPWR S5P_PMUREG(0x1174) #define S5P_MODIMIF_MEM_LOWPWR S5P_PMUREG(0x11C4) @@ -174,8 +128,6 @@ #define S5P_SATA_MEM_LOWPWR S5P_PMUREG(0x11E4) #define S5P_LCD1_LOWPWR S5P_PMUREG(0x1394) -#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0) - /* Only for EXYNOS4x12 */ #define S5P_ISP_ARM_LOWPWR S5P_PMUREG(0x1050) #define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR S5P_PMUREG(0x1054) @@ -343,13 +295,9 @@ #define EXYNOS5_TOP_PWR_OPTION S5P_PMUREG(0x2C48) #define EXYNOS5_TOP_PWR_SYSMEM_OPTION S5P_PMUREG(0x2CC8) #define EXYNOS5_JPEG_MEM_OPTION S5P_PMUREG(0x2F48) -#define EXYNOS5_GSCL_STATUS S5P_PMUREG(0x4004) -#define EXYNOS5_ISP_STATUS S5P_PMUREG(0x4024) #define EXYNOS5_GSCL_OPTION S5P_PMUREG(0x4008) #define EXYNOS5_ISP_OPTION S5P_PMUREG(0x4028) #define EXYNOS5_MFC_OPTION S5P_PMUREG(0x4048) -#define EXYNOS5_G3D_CONFIGURATION S5P_PMUREG(0x4060) -#define EXYNOS5_G3D_STATUS S5P_PMUREG(0x4064) #define EXYNOS5_G3D_OPTION S5P_PMUREG(0x4068) #define EXYNOS5_DISP1_OPTION S5P_PMUREG(0x40A8) #define EXYNOS5_MAU_OPTION S5P_PMUREG(0x40C8) @@ -357,7 +305,6 @@ #define EXYNOS5_USE_SC_FEEDBACK (1 << 1) #define EXYNOS5_USE_SC_COUNTER (1 << 0) -#define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL (1 << 2) #define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7) #define EXYNOS5_OPTION_USE_STANDBYWFE (1 << 24) diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index 0f2111a11315..fba55fb9f47d 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig @@ -85,6 +85,7 @@ config FOOTBRIDGE # Footbridge in host mode config FOOTBRIDGE_HOST bool + select ARCH_MIGHT_HAVE_PC_SERIO # Footbridge in addin mode config FOOTBRIDGE_ADDIN diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index e0091685fd48..9e8220e38398 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -143,11 +143,6 @@ static struct map_desc fb_common_io_desc[] __initdata = { .pfn = __phys_to_pfn(DC21285_ARMCSR_BASE), .length = ARMCSR_SIZE, .type = MT_DEVICE, - }, { - .virtual = XBUS_BASE, - .pfn = __phys_to_pfn(0x40000000), - .length = XBUS_SIZE, - .type = MT_DEVICE, } }; diff --git a/arch/arm/mach-footbridge/common.h b/arch/arm/mach-footbridge/common.h index 56607b3a773e..b911e5587ecf 100644 --- a/arch/arm/mach-footbridge/common.h +++ b/arch/arm/mach-footbridge/common.h @@ -10,3 +10,5 @@ extern void footbridge_init_irq(void); extern void isa_init_irq(unsigned int irq); extern void footbridge_restart(enum reboot_mode, const char *); + +extern void footbridge_sched_clock(void); diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 9ee78f7b4990..3971104d32d4 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -46,6 +47,16 @@ static struct clocksource cksrc_dc21285 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static int ckevt_dc21285_set_next_event(unsigned long delta, + struct clock_event_device *c) +{ + *CSR_TIMER1_CLR = 0; + *CSR_TIMER1_LOAD = delta; + *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16; + + return 0; +} + static void ckevt_dc21285_set_mode(enum clock_event_mode mode, struct clock_event_device *c) { @@ -58,7 +69,9 @@ static void ckevt_dc21285_set_mode(enum clock_event_mode mode, TIMER_CNTL_DIV16; break; - default: + case CLOCK_EVT_MODE_ONESHOT: + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: *CSR_TIMER1_CNTL = 0; break; } @@ -66,9 +79,11 @@ static void ckevt_dc21285_set_mode(enum clock_event_mode mode, static struct clock_event_device ckevt_dc21285 = { .name = "dc21285_timer1", - .features = CLOCK_EVT_FEAT_PERIODIC, + .features = CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_ONESHOT, .rating = 200, .irq = IRQ_TIMER1, + .set_next_event = ckevt_dc21285_set_next_event, .set_mode = ckevt_dc21285_set_mode, }; @@ -78,6 +93,10 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) *CSR_TIMER1_CLR = 0; + /* Stop the timer if in one-shot mode */ + if (ce->mode == CLOCK_EVT_MODE_ONESHOT) + *CSR_TIMER1_CNTL = 0; + ce->event_handler(ce); return IRQ_HANDLED; @@ -96,11 +115,28 @@ static struct irqaction footbridge_timer_irq = { void __init footbridge_timer_init(void) { struct clock_event_device *ce = &ckevt_dc21285; + unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16); - clocksource_register_hz(&cksrc_dc21285, (mem_fclk_21285 + 8) / 16); + clocksource_register_hz(&cksrc_dc21285, rate); setup_irq(ce->irq, &footbridge_timer_irq); ce->cpumask = cpumask_of(smp_processor_id()); - clockevents_config_and_register(ce, mem_fclk_21285, 0x4, 0xffffff); + clockevents_config_and_register(ce, rate, 0x4, 0xffffff); +} + +static u32 notrace footbridge_read_sched_clock(void) +{ + return ~*CSR_TIMER3_VALUE; +} + +void __init footbridge_sched_clock(void) +{ + unsigned rate = DIV_ROUND_CLOSEST(mem_fclk_21285, 16); + + *CSR_TIMER3_LOAD = 0; + *CSR_TIMER3_CLR = 0; + *CSR_TIMER3_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16; + + setup_sched_clock(footbridge_read_sched_clock, 24, rate); } diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index 1a7235fb52ac..aee8300f3490 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -4,6 +4,7 @@ * EBSA285 machine fixup */ #include +#include #include #include #include @@ -17,6 +18,11 @@ /* LEDs */ #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS) +#define XBUS_AMBER_L BIT(0) +#define XBUS_GREEN_L BIT(1) +#define XBUS_RED_L BIT(2) +#define XBUS_TOGGLE BIT(7) + struct ebsa285_led { struct led_classdev cdev; u8 mask; @@ -36,6 +42,7 @@ static const struct { }; static unsigned char hw_led_state; +static void __iomem *xbus; static void ebsa285_led_set(struct led_classdev *cdev, enum led_brightness b) @@ -47,7 +54,7 @@ static void ebsa285_led_set(struct led_classdev *cdev, hw_led_state |= led->mask; else hw_led_state &= ~led->mask; - *XBUS_LEDS = hw_led_state; + writeb(hw_led_state, xbus); } static enum led_brightness ebsa285_led_get(struct led_classdev *cdev) @@ -65,9 +72,13 @@ static int __init ebsa285_leds_init(void) if (!machine_is_ebsa285()) return -ENODEV; + xbus = ioremap(XBUS_CS2, SZ_4K); + if (!xbus) + return -ENOMEM; + /* 3 LEDS all off */ - hw_led_state = XBUS_LED_AMBER | XBUS_LED_GREEN | XBUS_LED_RED; - *XBUS_LEDS = hw_led_state; + hw_led_state = XBUS_AMBER_L | XBUS_GREEN_L | XBUS_RED_L; + writeb(hw_led_state, xbus); for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) { struct ebsa285_led *led; @@ -104,6 +115,7 @@ MACHINE_START(EBSA285, "EBSA285") .video_start = 0x000a0000, .video_end = 0x000bffff, .map_io = footbridge_map_io, + .init_early = footbridge_sched_clock, .init_irq = footbridge_init_irq, .init_time = footbridge_timer_init, .restart = footbridge_restart, diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h index e3d6ccac2162..02f6d7a706b1 100644 --- a/arch/arm/mach-footbridge/include/mach/hardware.h +++ b/arch/arm/mach-footbridge/include/mach/hardware.h @@ -51,11 +51,7 @@ #define PCIMEM_SIZE 0x01000000 #define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000) -#define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) -#define XBUS_LED_AMBER (1 << 0) -#define XBUS_LED_GREEN (1 << 1) -#define XBUS_LED_RED (1 << 2) -#define XBUS_LED_TOGGLE (1 << 8) +#define XBUS_CS2 0x40012000 #define XBUS_SWITCH ((volatile unsigned char *)(XBUS_BASE + 0x12000)) #define XBUS_SWITCH_SWITCH ((*XBUS_SWITCH) & 15) diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index bd3bf66ce344..c7de89b263dd 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -53,6 +53,7 @@ static void __init highbank_scu_map_io(void) static void highbank_l2x0_disable(void) { + outer_flush_all(); /* Disable PL310 L2 Cache controller */ highbank_smc1(0x102, 0x0); } diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig new file mode 100644 index 000000000000..018ad67f1b38 --- /dev/null +++ b/arch/arm/mach-hisi/Kconfig @@ -0,0 +1,17 @@ +config ARCH_HI3xxx + bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7 + select ARM_AMBA + select ARM_GIC + select ARM_TIMER_SP804 + select ARCH_WANT_OPTIONAL_GPIOLIB + select CACHE_L2X0 + select CLKSRC_OF + select GENERIC_CLOCKEVENTS + select HAVE_ARM_SCU + select HAVE_ARM_TWD + select HAVE_SMP + select PINCTRL + select PINCTRL_SINGLE + select SMP + help + Support for Hisilicon Hi36xx/Hi37xx processor family diff --git a/arch/arm/mach-hisi/Makefile b/arch/arm/mach-hisi/Makefile new file mode 100644 index 000000000000..6870058d0a48 --- /dev/null +++ b/arch/arm/mach-hisi/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for Hisilicon processors family +# + +obj-y += hisilicon.o +obj-$(CONFIG_SMP) += platsmp.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h new file mode 100644 index 000000000000..af23ec204538 --- /dev/null +++ b/arch/arm/mach-hisi/core.h @@ -0,0 +1,15 @@ +#ifndef __HISILICON_CORE_H +#define __HISILICON_CORE_H + +#include + +extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr); +extern int hi3xxx_get_cpu_jump(int cpu); +extern void secondary_startup(void); +extern struct smp_operations hi3xxx_smp_ops; + +extern void hi3xxx_cpu_die(unsigned int cpu); +extern int hi3xxx_cpu_kill(unsigned int cpu); +extern void hi3xxx_set_cpu(int cpu, bool enable); + +#endif diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c new file mode 100644 index 000000000000..741faf3e7100 --- /dev/null +++ b/arch/arm/mach-hisi/hisilicon.c @@ -0,0 +1,90 @@ +/* + * (Hisilicon's SoC based) flattened device tree enabled machine + * + * Copyright (c) 2012-2013 Hisilicon Ltd. + * Copyright (c) 2012-2013 Linaro Ltd. + * + * Author: Haojian Zhuang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "core.h" + +#define HI3620_SYSCTRL_PHYS_BASE 0xfc802000 +#define HI3620_SYSCTRL_VIRT_BASE 0xfe802000 + +/* + * This table is only for optimization. Since ioremap() could always share + * the same mapping if it's defined as static IO mapping. + * + * Without this table, system could also work. The cost is some virtual address + * spaces wasted since ioremap() may be called multi times for the same + * IO space. + */ +static struct map_desc hi3620_io_desc[] __initdata = { + { + /* sysctrl */ + .pfn = __phys_to_pfn(HI3620_SYSCTRL_PHYS_BASE), + .virtual = HI3620_SYSCTRL_VIRT_BASE, + .length = 0x1000, + .type = MT_DEVICE, + }, +}; + +static void __init hi3620_map_io(void) +{ + debug_ll_io_init(); + iotable_init(hi3620_io_desc, ARRAY_SIZE(hi3620_io_desc)); +} + +static void hi3xxx_restart(enum reboot_mode mode, const char *cmd) +{ + struct device_node *np; + void __iomem *base; + int offset; + + np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); + if (!np) { + pr_err("failed to find hisilicon,sysctrl node\n"); + return; + } + base = of_iomap(np, 0); + if (!base) { + pr_err("failed to map address in hisilicon,sysctrl node\n"); + return; + } + if (of_property_read_u32(np, "reboot-offset", &offset) < 0) { + pr_err("failed to find reboot-offset property\n"); + return; + } + writel_relaxed(0xdeadbeef, base + offset); + + while (1) + cpu_do_idle(); +} + +static const char *hi3xxx_compat[] __initconst = { + "hisilicon,hi3620-hi4511", + NULL, +}; + +DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)") + .map_io = hi3620_map_io, + .dt_compat = hi3xxx_compat, + .smp = smp_ops(hi3xxx_smp_ops), + .restart = hi3xxx_restart, +MACHINE_END diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c new file mode 100644 index 000000000000..b909854eee7f --- /dev/null +++ b/arch/arm/mach-hisi/hotplug.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "core.h" + +/* Sysctrl registers in Hi3620 SoC */ +#define SCISOEN 0xc0 +#define SCISODIS 0xc4 +#define SCPERPWREN 0xd0 +#define SCPERPWRDIS 0xd4 +#define SCCPUCOREEN 0xf4 +#define SCCPUCOREDIS 0xf8 +#define SCPERCTRL0 0x200 +#define SCCPURSTEN 0x410 +#define SCCPURSTDIS 0x414 + +/* + * bit definition in SCISOEN/SCPERPWREN/... + * + * CPU2_ISO_CTRL (1 << 5) + * CPU3_ISO_CTRL (1 << 6) + * ... + */ +#define CPU2_ISO_CTRL (1 << 5) + +/* + * bit definition in SCPERCTRL0 + * + * CPU0_WFI_MASK_CFG (1 << 28) + * CPU1_WFI_MASK_CFG (1 << 29) + * ... + */ +#define CPU0_WFI_MASK_CFG (1 << 28) + +/* + * bit definition in SCCPURSTEN/... + * + * CPU0_SRST_REQ_EN (1 << 0) + * CPU1_SRST_REQ_EN (1 << 1) + * ... + */ +#define CPU0_HPM_SRST_REQ_EN (1 << 22) +#define CPU0_DBG_SRST_REQ_EN (1 << 12) +#define CPU0_NEON_SRST_REQ_EN (1 << 4) +#define CPU0_SRST_REQ_EN (1 << 0) + +enum { + HI3620_CTRL, + ERROR_CTRL, +}; + +static void __iomem *ctrl_base; +static int id; + +static void set_cpu_hi3620(int cpu, bool enable) +{ + u32 val = 0; + + if (enable) { + /* MTCMOS set */ + if ((cpu == 2) || (cpu == 3)) + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCPERPWREN); + udelay(100); + + /* Enable core */ + writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREEN); + + /* unreset */ + val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN + | CPU0_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS); + /* reset */ + val |= CPU0_HPM_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN); + + /* ISO disable */ + if ((cpu == 2) || (cpu == 3)) + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCISODIS); + udelay(1); + + /* WFI Mask */ + val = readl_relaxed(ctrl_base + SCPERCTRL0); + val &= ~(CPU0_WFI_MASK_CFG << cpu); + writel_relaxed(val, ctrl_base + SCPERCTRL0); + + /* Unreset */ + val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN + | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTDIS); + } else { + /* wfi mask */ + val = readl_relaxed(ctrl_base + SCPERCTRL0); + val |= (CPU0_WFI_MASK_CFG << cpu); + writel_relaxed(val, ctrl_base + SCPERCTRL0); + + /* disable core*/ + writel_relaxed(0x01 << cpu, ctrl_base + SCCPUCOREDIS); + + if ((cpu == 2) || (cpu == 3)) { + /* iso enable */ + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCISOEN); + udelay(1); + } + + /* reset */ + val = CPU0_DBG_SRST_REQ_EN | CPU0_NEON_SRST_REQ_EN + | CPU0_SRST_REQ_EN | CPU0_HPM_SRST_REQ_EN; + writel_relaxed(val << cpu, ctrl_base + SCCPURSTEN); + + if ((cpu == 2) || (cpu == 3)) { + /* MTCMOS unset */ + writel_relaxed(CPU2_ISO_CTRL << (cpu - 2), + ctrl_base + SCPERPWRDIS); + udelay(100); + } + } +} + +static int hi3xxx_hotplug_init(void) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); + if (node) { + ctrl_base = of_iomap(node, 0); + id = HI3620_CTRL; + return 0; + } + id = ERROR_CTRL; + return -ENOENT; +} + +void hi3xxx_set_cpu(int cpu, bool enable) +{ + if (!ctrl_base) { + if (hi3xxx_hotplug_init() < 0) + return; + } + + if (id == HI3620_CTRL) + set_cpu_hi3620(cpu, enable); +} + +static inline void cpu_enter_lowpower(void) +{ + unsigned int v; + + flush_cache_all(); + + /* + * Turn off coherency and L1 D-cache + */ + asm volatile( + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, #0x40\n" + " mcr p15, 0, %0, c1, c0, 1\n" + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, #0x04\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "r" (0) + : "cc"); +} + +void hi3xxx_cpu_die(unsigned int cpu) +{ + cpu_enter_lowpower(); + hi3xxx_set_cpu_jump(cpu, phys_to_virt(0)); + cpu_do_idle(); + + /* We should have never returned from idle */ + panic("cpu %d unexpectedly exit from shutdown\n", cpu); +} + +int hi3xxx_cpu_kill(unsigned int cpu) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(50); + + while (hi3xxx_get_cpu_jump(cpu)) + if (time_after(jiffies, timeout)) + return 0; + hi3xxx_set_cpu(cpu, false); + return 1; +} diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c new file mode 100644 index 000000000000..471f1ee3be2b --- /dev/null +++ b/arch/arm/mach-hisi/platsmp.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * Based on arch/arm/mach-vexpress/platsmp.c, Copyright (C) 2002 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ +#include +#include +#include + +#include +#include +#include + +#include "core.h" + +static void __iomem *ctrl_base; + +void hi3xxx_set_cpu_jump(int cpu, void *jump_addr) +{ + cpu = cpu_logical_map(cpu); + if (!cpu || !ctrl_base) + return; + writel_relaxed(virt_to_phys(jump_addr), ctrl_base + ((cpu - 1) << 2)); +} + +int hi3xxx_get_cpu_jump(int cpu) +{ + cpu = cpu_logical_map(cpu); + if (!cpu || !ctrl_base) + return 0; + return readl_relaxed(ctrl_base + ((cpu - 1) << 2)); +} + +static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *np = NULL; + unsigned long base = 0; + u32 offset = 0; + void __iomem *scu_base = NULL; + + if (scu_a9_has_base()) { + base = scu_a9_get_base(); + scu_base = ioremap(base, SZ_4K); + if (!scu_base) { + pr_err("ioremap(scu_base) failed\n"); + return; + } + scu_enable(scu_base); + iounmap(scu_base); + } + if (!ctrl_base) { + np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); + if (!np) { + pr_err("failed to find hisilicon,sysctrl node\n"); + return; + } + ctrl_base = of_iomap(np, 0); + if (!ctrl_base) { + pr_err("failed to map address\n"); + return; + } + if (of_property_read_u32(np, "smp-offset", &offset) < 0) { + pr_err("failed to find smp-offset property\n"); + return; + } + ctrl_base += offset; + } +} + +static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + hi3xxx_set_cpu(cpu, true); + hi3xxx_set_cpu_jump(cpu, secondary_startup); + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); + return 0; +} + +struct smp_operations hi3xxx_smp_ops __initdata = { + .smp_prepare_cpus = hi3xxx_smp_prepare_cpus, + .smp_boot_secondary = hi3xxx_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = hi3xxx_cpu_die, + .cpu_kill = hi3xxx_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 7a6e6f710068..33567aa5880f 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -3,7 +3,6 @@ config ARCH_MXC select ARCH_REQUIRE_GPIOLIB select ARM_CPU_SUSPEND if PM select ARM_PATCH_PHYS_VIRT - select AUTO_ZRELADDR if !ZBOOT_ROM select CLKSRC_MMIO select COMMON_CLK select GENERIC_ALLOCATOR @@ -11,6 +10,7 @@ config ARCH_MXC select GENERIC_IRQ_CHIP select MIGHT_HAVE_CACHE_L2X0 if ARCH_MULTI_V6_V7 select MULTI_IRQ_HANDLER + select PINCTRL select SOC_BUS select SPARSE_IRQ select USE_OF @@ -20,16 +20,6 @@ config ARCH_MXC menu "Freescale i.MX support" depends on ARCH_MXC -config MXC_IRQ_PRIOR - bool "Use IRQ priority" - help - Select this if you want to use prioritized IRQ handling. - This feature prevents higher priority ISR to be interrupted - by lower priority IRQ. - This may be useful in embedded applications, where are strong - requirements for timing. - Say N here, unless you have a specialized requirement. - config MXC_TZIC bool @@ -109,6 +99,7 @@ config SOC_IMX25 select ARCH_MXC_IOMUX_V3 select CPU_ARM926T select MXC_AVIC + select PINCTRL_IMX25 config SOC_IMX27 bool @@ -118,6 +109,7 @@ config SOC_IMX27 select IMX_HAVE_IOMUX_V1 select MACH_MX27 select MXC_AVIC + select PINCTRL_IMX27 config SOC_IMX31 bool @@ -133,6 +125,7 @@ config SOC_IMX35 select HAVE_EPIT select MXC_AVIC select SMP_ON_UP if SMP + select PINCTRL config SOC_IMX5 bool @@ -145,7 +138,6 @@ config SOC_IMX5 config SOC_IMX51 bool select HAVE_IMX_SRC - select PINCTRL select PINCTRL_IMX51 select SOC_IMX5 @@ -619,6 +611,13 @@ config MACH_IMX31_DT comment "MX35 platforms:" +config MACH_IMX35_DT + bool "Support i.MX35 platforms from device tree" + select SOC_IMX35 + help + Include support for Freescale i.MX35 based platforms + using the device tree for discovery. + config MACH_PCM043 bool "Support Phytec pcm043 (i.MX35) platforms" select IMX_HAVE_PLATFORM_FLEXCAN @@ -766,11 +765,19 @@ endchoice comment "Device tree only" +config SOC_IMX50 + bool "i.MX50 support" + select HAVE_IMX_SRC + select PINCTRL_IMX50 + select SOC_IMX5 + + help + This enables support for Freescale i.MX50 processor. + config SOC_IMX53 bool "i.MX53 support" select HAVE_IMX_SRC select IMX_HAVE_PLATFORM_IMX2_WDT - select PINCTRL select PINCTRL_IMX53 select SOC_IMX5 @@ -796,7 +803,6 @@ config SOC_IMX6Q select MFD_SYSCON select MIGHT_HAVE_PCI select PCI_DOMAINS if PCI - select PINCTRL select PINCTRL_IMX6Q select PL310_ERRATA_588369 if CACHE_PL310 select PL310_ERRATA_727915 if CACHE_PL310 @@ -817,7 +823,6 @@ config SOC_IMX6SL select HAVE_IMX_MMDC select HAVE_IMX_SRC select MFD_SYSCON - select PINCTRL select PINCTRL_IMX6SL select PL310_ERRATA_588369 if CACHE_PL310 select PL310_ERRATA_727915 if CACHE_PL310 @@ -831,7 +836,6 @@ config SOC_VF610 select CPU_V7 select ARM_GIC select CLKSRC_OF - select PINCTRL select PINCTRL_VF610 select VF_PIT_TIMER select PL310_ERRATA_588369 if CACHE_PL310 diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 1789e2b31903..befcaf5d0574 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -89,6 +89,7 @@ obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o +obj-$(CONFIG_MACH_IMX35_DT) += imx35-dt.o obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o @@ -112,6 +113,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += mach-cpuimx51sd.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd51-baseboard.o obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o +obj-$(CONFIG_SOC_IMX50) += mach-imx50.o obj-$(CONFIG_SOC_IMX53) += mach-imx53.o obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index e163ec7a8441..8d1df2e4b7ac 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -54,28 +54,6 @@ static void __iomem *avic_base; static struct irq_domain *domain; -#ifdef CONFIG_MXC_IRQ_PRIOR -static int avic_irq_set_priority(unsigned char irq, unsigned char prio) -{ - struct irq_data *d = irq_get_irq_data(irq); - unsigned int temp; - unsigned int mask = 0x0F << irq % 8 * 4; - - irq = d->hwirq; - - if (irq >= AVIC_NUM_IRQS) - return -EINVAL; - - temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8)); - temp &= ~mask; - temp |= prio & mask; - - __raw_writel(temp, avic_base + AVIC_NIPRIORITY(irq / 8)); - - return 0; -} -#endif - #ifdef CONFIG_FIQ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) { @@ -102,9 +80,6 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) static struct mxc_extra_irq avic_extra_irq = { -#ifdef CONFIG_MXC_IRQ_PRIOR - .set_priority = avic_irq_set_priority, -#endif #ifdef CONFIG_FIQ .set_irq_fiq = avic_set_irq_fiq, #endif diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index a63e415609a8..a2ecc006b322 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -72,7 +72,7 @@ static int clk_gate2_is_enabled(struct clk_hw *hw) reg = readl(gate->reg); - if (((reg >> gate->bit_idx) & 3) == 3) + if (((reg >> gate->bit_idx) & 1) == 1) return 1; return 0; diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index 2193c834f55c..a4d5e425cd82 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -45,6 +45,8 @@ static struct arm_ahb_div clk_consumer[] = { static char hsp_div_532[] = { 4, 8, 3, 0 }; static char hsp_div_400[] = { 3, 6, 3, 0 }; +static struct clk_onecell_data clk_data; + static const char *std_sel[] = {"ppll", "arm"}; static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"}; @@ -286,3 +288,15 @@ int __init mx35_clocks_init(void) return 0; } + +static int __init mx35_clocks_init_dt(struct device_node *ccm_node) +{ + clk_data.clks = clk; + clk_data.clk_num = ARRAY_SIZE(clk); + of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); + + mx35_clocks_init(); + + return 0; +} +CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index ce37af26ff8c..19fca1fdc6fe 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -12,11 +12,11 @@ #include #include #include -#include #include #include #include #include +#include #include "crm-regs-imx5.h" #include "clk.h" @@ -83,50 +83,7 @@ static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_ static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", }; static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; - -enum imx5_clks { - dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, - uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s, - emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred, - usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused, - tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate, - uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate, - gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate, - gpt_hf_gate, fec_gate, usboh3_per_gate, esdhc1_ipg_gate, esdhc2_ipg_gate, - esdhc3_ipg_gate, esdhc4_ipg_gate, ssi1_ipg_gate, ssi2_ipg_gate, - ssi3_ipg_gate, ecspi1_ipg_gate, ecspi1_per_gate, ecspi2_ipg_gate, - ecspi2_per_gate, cspi_ipg_gate, sdma_gate, emi_slow_gate, ipu_s, - ipu_gate, nfc_gate, ipu_di1_gate, vpu_s, vpu_gate, - vpu_reference_gate, uart4_ipg_gate, uart4_per_gate, uart5_ipg_gate, - uart5_per_gate, tve_gate, tve_pred, esdhc1_per_gate, esdhc2_per_gate, - esdhc3_per_gate, esdhc4_per_gate, usb_phy_gate, hsi2c_gate, - mipi_hsc1_gate, mipi_hsc2_gate, mipi_esc_gate, mipi_hsp_gate, - ldb_di1_div_3_5, ldb_di1_div, ldb_di0_div_3_5, ldb_di0_div, - ldb_di1_gate, can2_serial_gate, can2_ipg_gate, i2c3_gate, lp_apm, - periph_apm, main_bus, ahb_max, aips_tz1, aips_tz2, tmax1, tmax2, - tmax3, spba, uart_sel, esdhc_a_sel, esdhc_b_sel, esdhc_a_podf, - esdhc_b_podf, ecspi_sel, usboh3_sel, usb_phy_sel, iim_gate, - usboh3_gate, emi_fast_gate, ipu_di0_gate,gpc_dvfs, pll1_sw, pll2_sw, - pll3_sw, ipu_di0_sel, ipu_di1_sel, tve_ext_sel, mx51_mipi, pll4_sw, - ldb_di1_sel, di_pll4_podf, ldb_di0_sel, ldb_di0_gate, usb_phy1_gate, - usb_phy2_gate, per_lp_apm, per_pred1, per_pred2, per_podf, per_root, - ssi_apm, ssi1_root_sel, ssi2_root_sel, ssi3_root_sel, ssi_ext1_sel, - ssi_ext2_sel, ssi_ext1_com_sel, ssi_ext2_com_sel, ssi1_root_pred, - ssi1_root_podf, ssi2_root_pred, ssi2_root_podf, ssi_ext1_pred, - ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate, - ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, - epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, - can_sel, can1_serial_gate, can1_ipg_gate, - owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, - cko1_sel, cko1_podf, cko1, - cko2_sel, cko2_podf, cko2, - srtc_gate, pata_gate, sata_gate, spdif_xtal_sel, spdif0_sel, - spdif1_sel, spdif0_pred, spdif0_podf, spdif1_pred, spdif1_podf, - spdif0_com_s, spdif1_com_sel, spdif0_gate, spdif1_gate, spdif_ipg_gate, - ocram, clk_max -}; - -static struct clk *clk[clk_max]; +static struct clk *clk[IMX5_CLK_END]; static struct clk_onecell_data clk_data; static void __init mx5_clocks_common_init(unsigned long rate_ckil, @@ -135,236 +92,296 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, { int i; - clk[dummy] = imx_clk_fixed("dummy", 0); - clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil); - clk[osc] = imx_obtain_fixed_clock("osc", rate_osc); - clk[ckih1] = imx_obtain_fixed_clock("ckih1", rate_ckih1); - clk[ckih2] = imx_obtain_fixed_clock("ckih2", rate_ckih2); + clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); + clk[IMX5_CLK_CKIL] = imx_obtain_fixed_clock("ckil", rate_ckil); + clk[IMX5_CLK_OSC] = imx_obtain_fixed_clock("osc", rate_osc); + clk[IMX5_CLK_CKIH1] = imx_obtain_fixed_clock("ckih1", rate_ckih1); + clk[IMX5_CLK_CKIH2] = imx_obtain_fixed_clock("ckih2", rate_ckih2); - clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, - lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); - clk[periph_apm] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2, - periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); - clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, - main_bus_sel, ARRAY_SIZE(main_bus_sel)); - clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, - per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); - clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); - clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); - clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); - clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, - per_root_sel, ARRAY_SIZE(per_root_sel)); - clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); - clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); - clk[aips_tz1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); - clk[aips_tz2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); - clk[tmax1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); - clk[tmax2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); - clk[tmax3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); - clk[spba] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); - clk[ipg] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); - clk[axi_a] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); - clk[axi_b] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); - clk[uart_sel] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[uart_pred] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3); - clk[uart_root] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3); + clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2, + periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); + clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, + main_bus_sel, ARRAY_SIZE(main_bus_sel)); + clk[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, + per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); + clk[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); + clk[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); + clk[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); + clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, + per_root_sel, ARRAY_SIZE(per_root_sel)); + clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); + clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); + clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); + clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); + clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); + clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); + clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); + clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); + clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); + clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); + clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); + clk[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3); + clk[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3); - clk[esdhc_a_sel] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[esdhc_b_sel] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[esdhc_a_pred] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3); - clk[esdhc_a_podf] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3); - clk[esdhc_b_pred] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3); - clk[esdhc_b_podf] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3); - clk[esdhc_c_s] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel)); - clk[esdhc_d_s] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel)); + clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3); + clk[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3); + clk[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3); + clk[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3); + clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel)); + clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel)); - clk[emi_sel] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1, - emi_slow_sel, ARRAY_SIZE(emi_slow_sel)); - clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3); - clk[nfc_podf] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3); - clk[ecspi_sel] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[ecspi_pred] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3); - clk[ecspi_podf] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6); - clk[usboh3_sel] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[usboh3_pred] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3); - clk[usboh3_podf] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2); - clk[usb_phy_pred] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3); - clk[usb_phy_podf] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); - clk[usb_phy_sel] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, - usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); - clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); - clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); - clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); - clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); - clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); - clk[uart2_ipg_gate] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10); - clk[uart2_per_gate] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12); - clk[uart3_ipg_gate] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14); - clk[uart3_per_gate] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16); - clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18); - clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20); - clk[pwm1_ipg_gate] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10); - clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12); - clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); - clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16); - clk[gpt_ipg_gate] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18); - clk[gpt_hf_gate] = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20); - clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); - clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); - clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); - clk[esdhc1_ipg_gate] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0); - clk[esdhc2_ipg_gate] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4); - clk[esdhc3_ipg_gate] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8); - clk[esdhc4_ipg_gate] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12); - clk[ssi1_ipg_gate] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16); - clk[ssi2_ipg_gate] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20); - clk[ssi3_ipg_gate] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24); - clk[ecspi1_ipg_gate] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18); - clk[ecspi1_per_gate] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20); - clk[ecspi2_ipg_gate] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22); - clk[ecspi2_per_gate] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); - clk[cspi_ipg_gate] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); - clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); - clk[emi_fast_gate] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); - clk[emi_slow_gate] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); - clk[ipu_s] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); - clk[ipu_gate] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); - clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); - clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); - clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); - clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel)); - clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel)); - clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2); - clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4); - clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14); - clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); - clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); - clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); - clk[uart4_ipg_gate] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8); - clk[uart4_per_gate] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10); - clk[uart5_ipg_gate] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12); - clk[uart5_per_gate] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14); - clk[gpc_dvfs] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); + clk[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1, + emi_slow_sel, ARRAY_SIZE(emi_slow_sel)); + clk[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3); + clk[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3); + clk[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3); + clk[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6); + clk[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2, + standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); + clk[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3); + clk[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2); + clk[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3); + clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); + clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, + usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); + clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); + clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); + clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); + clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); + clk[IMX5_CLK_UART1_PER_GATE] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); + clk[IMX5_CLK_UART2_IPG_GATE] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10); + clk[IMX5_CLK_UART2_PER_GATE] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12); + clk[IMX5_CLK_UART3_IPG_GATE] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14); + clk[IMX5_CLK_UART3_PER_GATE] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16); + clk[IMX5_CLK_I2C1_GATE] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18); + clk[IMX5_CLK_I2C2_GATE] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20); + clk[IMX5_CLK_PWM1_IPG_GATE] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10); + clk[IMX5_CLK_PWM1_HF_GATE] = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12); + clk[IMX5_CLK_PWM2_IPG_GATE] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); + clk[IMX5_CLK_PWM2_HF_GATE] = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16); + clk[IMX5_CLK_GPT_IPG_GATE] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18); + clk[IMX5_CLK_GPT_HF_GATE] = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20); + clk[IMX5_CLK_FEC_GATE] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); + clk[IMX5_CLK_USBOH3_GATE] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); + clk[IMX5_CLK_USBOH3_PER_GATE] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); + clk[IMX5_CLK_ESDHC1_IPG_GATE] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0); + clk[IMX5_CLK_ESDHC2_IPG_GATE] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4); + clk[IMX5_CLK_ESDHC3_IPG_GATE] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8); + clk[IMX5_CLK_ESDHC4_IPG_GATE] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12); + clk[IMX5_CLK_SSI1_IPG_GATE] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16); + clk[IMX5_CLK_SSI2_IPG_GATE] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20); + clk[IMX5_CLK_SSI3_IPG_GATE] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24); + clk[IMX5_CLK_ECSPI1_IPG_GATE] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18); + clk[IMX5_CLK_ECSPI1_PER_GATE] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20); + clk[IMX5_CLK_ECSPI2_IPG_GATE] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22); + clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); + clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); + clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); + clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); + clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); + clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); + clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); + clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); + clk[IMX5_CLK_IPU_DI0_GATE] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); + clk[IMX5_CLK_IPU_DI1_GATE] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); + clk[IMX5_CLK_GPU3D_SEL] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel)); + clk[IMX5_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel)); + clk[IMX5_CLK_GPU3D_GATE] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2); + clk[IMX5_CLK_GARB_GATE] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4); + clk[IMX5_CLK_GPU2D_GATE] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14); + clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); + clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); + clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); + clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8); + clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10); + clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12); + clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14); + clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); - clk[ssi_apm] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); - clk[ssi1_root_sel] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[ssi2_root_sel] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[ssi3_root_sel] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels)); - clk[ssi_ext1_sel] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[ssi_ext2_sel] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[ssi_ext1_com_sel] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels)); - clk[ssi_ext2_com_sel] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels)); - clk[ssi1_root_pred] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3); - clk[ssi1_root_podf] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6); - clk[ssi2_root_pred] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3); - clk[ssi2_root_podf] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6); - clk[ssi_ext1_pred] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3); - clk[ssi_ext1_podf] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6); - clk[ssi_ext2_pred] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3); - clk[ssi_ext2_podf] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6); - clk[ssi1_root_gate] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18); - clk[ssi2_root_gate] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22); - clk[ssi3_root_gate] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26); - clk[ssi_ext1_gate] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28); - clk[ssi_ext2_gate] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30); - clk[epit1_ipg_gate] = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2); - clk[epit1_hf_gate] = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4); - clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); - clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); - clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); - clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28); - clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0); - clk[spdif0_sel] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel)); - clk[spdif0_pred] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3); - clk[spdif0_podf] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6); - clk[spdif0_com_s] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1, - spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT); - clk[spdif0_gate] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26); - clk[spdif_ipg_gate] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30); + clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); + clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[IMX5_CLK_SSI2_ROOT_SEL] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[IMX5_CLK_SSI3_ROOT_SEL] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels)); + clk[IMX5_CLK_SSI_EXT1_SEL] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[IMX5_CLK_SSI_EXT2_SEL] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); + clk[IMX5_CLK_SSI_EXT1_COM_SEL] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels)); + clk[IMX5_CLK_SSI_EXT2_COM_SEL] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels)); + clk[IMX5_CLK_SSI1_ROOT_PRED] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3); + clk[IMX5_CLK_SSI1_ROOT_PODF] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6); + clk[IMX5_CLK_SSI2_ROOT_PRED] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3); + clk[IMX5_CLK_SSI2_ROOT_PODF] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6); + clk[IMX5_CLK_SSI_EXT1_PRED] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3); + clk[IMX5_CLK_SSI_EXT1_PODF] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6); + clk[IMX5_CLK_SSI_EXT2_PRED] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3); + clk[IMX5_CLK_SSI_EXT2_PODF] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6); + clk[IMX5_CLK_SSI1_ROOT_GATE] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18); + clk[IMX5_CLK_SSI2_ROOT_GATE] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22); + clk[IMX5_CLK_SSI3_ROOT_GATE] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26); + clk[IMX5_CLK_SSI_EXT1_GATE] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28); + clk[IMX5_CLK_SSI_EXT2_GATE] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30); + clk[IMX5_CLK_EPIT1_IPG_GATE] = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2); + clk[IMX5_CLK_EPIT1_HF_GATE] = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4); + clk[IMX5_CLK_EPIT2_IPG_GATE] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); + clk[IMX5_CLK_EPIT2_HF_GATE] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); + clk[IMX5_CLK_OWIRE_GATE] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); + clk[IMX5_CLK_SRTC_GATE] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28); + clk[IMX5_CLK_PATA_GATE] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0); + clk[IMX5_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel)); + clk[IMX5_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3); + clk[IMX5_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6); + clk[IMX5_CLK_SPDIF0_COM_SEL] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1, + spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT); + clk[IMX5_CLK_SPDIF0_GATE] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26); + clk[IMX5_CLK_SPDIF_IPG_GATE] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30); + clk[IMX5_CLK_SAHARA_IPG_GATE] = imx_clk_gate2("sahara_ipg_gate", "ipg", MXC_CCM_CCGR4, 14); + clk[IMX5_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "usb_phy1_gate", 1, 1); for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) pr_err("i.MX5 clk %d: register failed with %ld\n", i, PTR_ERR(clk[i])); - clk_register_clkdev(clk[gpt_hf_gate], "per", "imx-gpt.0"); - clk_register_clkdev(clk[gpt_ipg_gate], "ipg", "imx-gpt.0"); - clk_register_clkdev(clk[uart1_per_gate], "per", "imx21-uart.0"); - clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0"); - clk_register_clkdev(clk[uart2_per_gate], "per", "imx21-uart.1"); - clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1"); - clk_register_clkdev(clk[uart3_per_gate], "per", "imx21-uart.2"); - clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2"); - clk_register_clkdev(clk[uart4_per_gate], "per", "imx21-uart.3"); - clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3"); - clk_register_clkdev(clk[uart5_per_gate], "per", "imx21-uart.4"); - clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4"); - clk_register_clkdev(clk[ecspi1_per_gate], "per", "imx51-ecspi.0"); - clk_register_clkdev(clk[ecspi1_ipg_gate], "ipg", "imx51-ecspi.0"); - clk_register_clkdev(clk[ecspi2_per_gate], "per", "imx51-ecspi.1"); - clk_register_clkdev(clk[ecspi2_ipg_gate], "ipg", "imx51-ecspi.1"); - clk_register_clkdev(clk[cspi_ipg_gate], NULL, "imx35-cspi.2"); - clk_register_clkdev(clk[pwm1_ipg_gate], "pwm", "mxc_pwm.0"); - clk_register_clkdev(clk[pwm2_ipg_gate], "pwm", "mxc_pwm.1"); - clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0"); - clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1"); - clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.0"); - clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.0"); - clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.0"); - clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.1"); - clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.1"); - clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.1"); - clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2"); - clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2"); - clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2"); - clk_register_clkdev(clk[usboh3_per_gate], "per", "imx-udc-mx51"); - clk_register_clkdev(clk[usboh3_gate], "ipg", "imx-udc-mx51"); - clk_register_clkdev(clk[usboh3_gate], "ahb", "imx-udc-mx51"); - clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand"); - clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0"); - clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1"); - clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2"); - clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); - clk_register_clkdev(clk[cpu_podf], NULL, "cpu0"); - clk_register_clkdev(clk[iim_gate], "iim", NULL); - clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0"); - clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1"); - clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); - clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); - clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); - clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0"); - clk_register_clkdev(clk[epit1_hf_gate], "per", "imx-epit.0"); - clk_register_clkdev(clk[epit2_ipg_gate], "ipg", "imx-epit.1"); - clk_register_clkdev(clk[epit2_hf_gate], "per", "imx-epit.1"); + clk_register_clkdev(clk[IMX5_CLK_GPT_HF_GATE], "per", "imx-gpt.0"); + clk_register_clkdev(clk[IMX5_CLK_GPT_IPG_GATE], "ipg", "imx-gpt.0"); + clk_register_clkdev(clk[IMX5_CLK_UART1_PER_GATE], "per", "imx21-uart.0"); + clk_register_clkdev(clk[IMX5_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0"); + clk_register_clkdev(clk[IMX5_CLK_UART2_PER_GATE], "per", "imx21-uart.1"); + clk_register_clkdev(clk[IMX5_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1"); + clk_register_clkdev(clk[IMX5_CLK_UART3_PER_GATE], "per", "imx21-uart.2"); + clk_register_clkdev(clk[IMX5_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2"); + clk_register_clkdev(clk[IMX5_CLK_UART4_PER_GATE], "per", "imx21-uart.3"); + clk_register_clkdev(clk[IMX5_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3"); + clk_register_clkdev(clk[IMX5_CLK_UART5_PER_GATE], "per", "imx21-uart.4"); + clk_register_clkdev(clk[IMX5_CLK_UART5_IPG_GATE], "ipg", "imx21-uart.4"); + clk_register_clkdev(clk[IMX5_CLK_ECSPI1_PER_GATE], "per", "imx51-ecspi.0"); + clk_register_clkdev(clk[IMX5_CLK_ECSPI1_IPG_GATE], "ipg", "imx51-ecspi.0"); + clk_register_clkdev(clk[IMX5_CLK_ECSPI2_PER_GATE], "per", "imx51-ecspi.1"); + clk_register_clkdev(clk[IMX5_CLK_ECSPI2_IPG_GATE], "ipg", "imx51-ecspi.1"); + clk_register_clkdev(clk[IMX5_CLK_CSPI_IPG_GATE], NULL, "imx35-cspi.2"); + clk_register_clkdev(clk[IMX5_CLK_PWM1_IPG_GATE], "pwm", "mxc_pwm.0"); + clk_register_clkdev(clk[IMX5_CLK_PWM2_IPG_GATE], "pwm", "mxc_pwm.1"); + clk_register_clkdev(clk[IMX5_CLK_I2C1_GATE], NULL, "imx21-i2c.0"); + clk_register_clkdev(clk[IMX5_CLK_I2C2_GATE], NULL, "imx21-i2c.1"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.0"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "mxc-ehci.0"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "mxc-ehci.0"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.1"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "mxc-ehci.1"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "mxc-ehci.1"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "mxc-ehci.2"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "mxc-ehci.2"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "mxc-ehci.2"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_PER_GATE], "per", "imx-udc-mx51"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ipg", "imx-udc-mx51"); + clk_register_clkdev(clk[IMX5_CLK_USBOH3_GATE], "ahb", "imx-udc-mx51"); + clk_register_clkdev(clk[IMX5_CLK_NFC_GATE], NULL, "imx51-nand"); + clk_register_clkdev(clk[IMX5_CLK_SSI1_IPG_GATE], NULL, "imx-ssi.0"); + clk_register_clkdev(clk[IMX5_CLK_SSI2_IPG_GATE], NULL, "imx-ssi.1"); + clk_register_clkdev(clk[IMX5_CLK_SSI3_IPG_GATE], NULL, "imx-ssi.2"); + clk_register_clkdev(clk[IMX5_CLK_SDMA_GATE], NULL, "imx35-sdma"); + clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0"); + clk_register_clkdev(clk[IMX5_CLK_IIM_GATE], "iim", NULL); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], NULL, "imx2-wdt.0"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], NULL, "imx2-wdt.1"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], NULL, "imx-keypad"); + clk_register_clkdev(clk[IMX5_CLK_IPU_DI1_GATE], "di1", "imx-tve.0"); + clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL); + clk_register_clkdev(clk[IMX5_CLK_EPIT1_IPG_GATE], "ipg", "imx-epit.0"); + clk_register_clkdev(clk[IMX5_CLK_EPIT1_HF_GATE], "per", "imx-epit.0"); + clk_register_clkdev(clk[IMX5_CLK_EPIT2_IPG_GATE], "ipg", "imx-epit.1"); + clk_register_clkdev(clk[IMX5_CLK_EPIT2_HF_GATE], "per", "imx-epit.1"); /* Set SDHC parents to be PLL2 */ - clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]); - clk_set_parent(clk[esdhc_b_sel], clk[pll2_sw]); + clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]); + clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]); /* move usb phy clk to 24MHz */ - clk_set_parent(clk[usb_phy_sel], clk[osc]); + clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); - clk_prepare_enable(clk[gpc_dvfs]); - clk_prepare_enable(clk[ahb_max]); /* esdhc3 */ - clk_prepare_enable(clk[aips_tz1]); - clk_prepare_enable(clk[aips_tz2]); /* fec */ - clk_prepare_enable(clk[spba]); - clk_prepare_enable(clk[emi_fast_gate]); /* fec */ - clk_prepare_enable(clk[emi_slow_gate]); /* eim */ - clk_prepare_enable(clk[mipi_hsc1_gate]); - clk_prepare_enable(clk[mipi_hsc2_gate]); - clk_prepare_enable(clk[mipi_esc_gate]); - clk_prepare_enable(clk[mipi_hsp_gate]); - clk_prepare_enable(clk[tmax1]); - clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */ - clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */ + clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]); + clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */ + clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]); + clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */ + clk_prepare_enable(clk[IMX5_CLK_SPBA]); + clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */ + clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */ + clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]); + clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]); + clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]); + clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]); + clk_prepare_enable(clk[IMX5_CLK_TMAX1]); + clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ + clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ } +static void __init mx50_clocks_init(struct device_node *np) +{ + void __iomem *base; + unsigned long r; + int i, irq; + + clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE); + clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE); + clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); + + clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1, + lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); + clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); + clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); + clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); + clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); + clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); + clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); + clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); + + clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, + mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); + clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); + clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); + + clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, + mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); + clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); + clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); + + for (i = 0; i < ARRAY_SIZE(clk); i++) + if (IS_ERR(clk[i])) + pr_err("i.MX50 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + + clk_data.clks = clk; + clk_data.clk_num = ARRAY_SIZE(clk); + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + + mx5_clocks_common_init(0, 0, 0, 0); + + /* set SDHC root clock to 200MHZ*/ + clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000); + clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000); + + clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); + imx_print_silicon_rev("i.MX50", IMX_CHIP_REVISION_1_1); + clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); + + r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); + clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx50-gpt"); + base = of_iomap(np, 0); + WARN_ON(!base); + irq = irq_of_parse_and_map(np, 0); + mxc_timer_init(base, irq); +} +CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init); + int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, unsigned long rate_ckih1, unsigned long rate_ckih2) { @@ -372,38 +389,40 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, u32 val; struct device_node *np; - clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE); - clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE); - clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE); - clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, - mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); - clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, - mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); - clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, - mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); - clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); - clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); - clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); - clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6); - clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10); - clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); - clk[usb_phy_gate] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); - clk[hsi2c_gate] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); - clk[mipi_hsc1_gate] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); - clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); - clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); - clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); - clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, - mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); - clk[spdif1_sel] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2, - spdif_sel, ARRAY_SIZE(spdif_sel)); - clk[spdif1_pred] = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3); - clk[spdif1_podf] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6); - clk[spdif1_com_sel] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1, - mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel)); - clk[spdif1_gate] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28); + clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE); + clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE); + clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE); + clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, + lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); + clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, + mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); + clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, + mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); + clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); + clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, + mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); + clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); + clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); + clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); + clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6); + clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10); + clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); + clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); + clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); + clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); + clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); + clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); + clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); + clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, + mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); + clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2, + spdif_sel, ARRAY_SIZE(spdif_sel)); + clk[IMX5_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3); + clk[IMX5_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6); + clk[IMX5_CLK_SPDIF1_COM_SEL] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1, + mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel)); + clk[IMX5_CLK_SPDIF1_GATE] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28); for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) @@ -417,37 +436,37 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2); - clk_register_clkdev(clk[hsi2c_gate], NULL, "imx21-i2c.2"); - clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL); - clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0"); - clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); - clk_register_clkdev(clk[usb_phy_gate], "phy", "mxc-ehci.0"); - clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx51.0"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.0"); - clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx51.0"); - clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx51.1"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.1"); - clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx51.1"); - clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx51.2"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.2"); - clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx51.2"); - clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx51.3"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.3"); - clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx51.3"); + clk_register_clkdev(clk[IMX5_CLK_HSI2C_GATE], NULL, "imx21-i2c.2"); + clk_register_clkdev(clk[IMX5_CLK_MX51_MIPI], "mipi_hsp", NULL); + clk_register_clkdev(clk[IMX5_CLK_VPU_GATE], NULL, "imx51-vpu.0"); + clk_register_clkdev(clk[IMX5_CLK_FEC_GATE], NULL, "imx27-fec.0"); + clk_register_clkdev(clk[IMX5_CLK_USB_PHY_GATE], "phy", "mxc-ehci.0"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC1_IPG_GATE], "ipg", "sdhci-esdhc-imx51.0"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.0"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC1_PER_GATE], "per", "sdhci-esdhc-imx51.0"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC2_IPG_GATE], "ipg", "sdhci-esdhc-imx51.1"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.1"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC2_PER_GATE], "per", "sdhci-esdhc-imx51.1"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC3_IPG_GATE], "ipg", "sdhci-esdhc-imx51.2"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.2"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC3_PER_GATE], "per", "sdhci-esdhc-imx51.2"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC4_IPG_GATE], "ipg", "sdhci-esdhc-imx51.3"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx51.3"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC4_PER_GATE], "per", "sdhci-esdhc-imx51.3"); /* set the usboh3 parent to pll2_sw */ - clk_set_parent(clk[usboh3_sel], clk[pll2_sw]); + clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]); /* set SDHC root clock to 166.25MHZ*/ - clk_set_rate(clk[esdhc_a_podf], 166250000); - clk_set_rate(clk[esdhc_b_podf], 166250000); + clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000); + clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000); /* System timer */ mxc_timer_init(MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), MX51_INT_GPT); - clk_prepare_enable(clk[iim_gate]); + clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); imx_print_silicon_rev("i.MX51", mx51_revision()); - clk_disable_unprepare(clk[iim_gate]); + clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); /* * Reference Manual says: Functionality of CCDR[18] and CLPCR[23] is no @@ -479,57 +498,59 @@ static void __init mx53_clocks_init(struct device_node *np) unsigned long r; void __iomem *base; - clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE); - clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE); - clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); - clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); + clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE); + clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE); + clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); + clk[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); - clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0); - clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, - mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT); - clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); - clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0); - clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, - mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); - clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); - clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); - clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, - mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); - clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, - mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); - clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); - clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); - clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); - clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); - clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); - clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); - clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); - clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); - clk[can_sel] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2, - mx53_can_sel, ARRAY_SIZE(mx53_can_sel)); - clk[can1_serial_gate] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22); - clk[can1_ipg_gate] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20); - clk[ocram] = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2); - clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8); - clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); - clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); - clk[sata_gate] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2); + clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1, + lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); + clk[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); + clk[IMX5_CLK_LDB_DI1_DIV] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0); + clk[IMX5_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, + mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT); + clk[IMX5_CLK_DI_PLL4_PODF] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); + clk[IMX5_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); + clk[IMX5_CLK_LDB_DI0_DIV] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0); + clk[IMX5_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, + mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); + clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); + clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); + clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, + mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); + clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, + mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); + clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); + clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); + clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); + clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); + clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); + clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); + clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); + clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); + clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); + clk[IMX5_CLK_CAN_SEL] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2, + mx53_can_sel, ARRAY_SIZE(mx53_can_sel)); + clk[IMX5_CLK_CAN1_SERIAL_GATE] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22); + clk[IMX5_CLK_CAN1_IPG_GATE] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20); + clk[IMX5_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2); + clk[IMX5_CLK_CAN2_SERIAL_GATE] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8); + clk[IMX5_CLK_CAN2_IPG_GATE] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); + clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); + clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2); - clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, - mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); - clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); - clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); + clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, + mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); + clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); + clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); - clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, - mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); - clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); - clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); - clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, - mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); + clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, + mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); + clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); + clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); + clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, + mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) @@ -542,33 +563,36 @@ static void __init mx53_clocks_init(struct device_node *np) mx5_clocks_common_init(0, 0, 0, 0); - clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0"); - clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2"); - clk_register_clkdev(clk[fec_gate], NULL, "imx25-fec.0"); - clk_register_clkdev(clk[usb_phy1_gate], "usb_phy1", "mxc-ehci.0"); - clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx53.0"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.0"); - clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx53.0"); - clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx53.1"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.1"); - clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx53.1"); - clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx53.2"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.2"); - clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx53.2"); - clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx53.3"); - clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.3"); - clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx53.3"); + clk_register_clkdev(clk[IMX5_CLK_VPU_GATE], NULL, "imx53-vpu.0"); + clk_register_clkdev(clk[IMX5_CLK_I2C3_GATE], NULL, "imx21-i2c.2"); + clk_register_clkdev(clk[IMX5_CLK_FEC_GATE], NULL, "imx25-fec.0"); + clk_register_clkdev(clk[IMX5_CLK_USB_PHY1_GATE], "usb_phy1", "mxc-ehci.0"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC1_IPG_GATE], "ipg", "sdhci-esdhc-imx53.0"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.0"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC1_PER_GATE], "per", "sdhci-esdhc-imx53.0"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC2_IPG_GATE], "ipg", "sdhci-esdhc-imx53.1"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.1"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC2_PER_GATE], "per", "sdhci-esdhc-imx53.1"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC3_IPG_GATE], "ipg", "sdhci-esdhc-imx53.2"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.2"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC3_PER_GATE], "per", "sdhci-esdhc-imx53.2"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC4_IPG_GATE], "ipg", "sdhci-esdhc-imx53.3"); + clk_register_clkdev(clk[IMX5_CLK_DUMMY], "ahb", "sdhci-esdhc-imx53.3"); + clk_register_clkdev(clk[IMX5_CLK_ESDHC4_PER_GATE], "per", "sdhci-esdhc-imx53.3"); /* set SDHC root clock to 200MHZ*/ - clk_set_rate(clk[esdhc_a_podf], 200000000); - clk_set_rate(clk[esdhc_b_podf], 200000000); + clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000); + clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000); - clk_prepare_enable(clk[iim_gate]); + /* move can bus clk to 24MHz */ + clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]); + + clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); imx_print_silicon_rev("i.MX53", mx53_revision()); - clk_disable_unprepare(clk[iim_gate]); + clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); - r = clk_round_rate(clk[usboh3_per_gate], 54000000); - clk_set_rate(clk[usboh3_per_gate], r); + r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); + clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); np = of_find_compatible_node(NULL, NULL, "fsl,imx53-gpt"); base = of_iomap(np, 0); diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 04cfd0fcb0e5..af2e582d2b74 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -114,7 +114,7 @@ static struct clk *clk[clk_max]; static struct clk_onecell_data clk_data; static enum mx6q_clks const clks_init_on[] __initconst = { - mmdc_ch0_axi, rom, pll1_sys, + mmdc_ch0_axi, rom, arm, }; static struct clk_div_table clk_enet_ref_table[] = { @@ -475,6 +475,9 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) if (ret) pr_warn("failed to set up CLKO: %d\n", ret); + /* Audio-related clocks configuration */ + clk_set_parent(clk[spdif_sel], clk[pll3_pfd3_454m]); + /* All existing boards with PCIe use LVDS1 */ if (IS_ENABLED(CONFIG_PCI_IMX6)) clk_set_parent(clk[lvds1_sel], clk[sata_ref]); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index c0c4ef55e35b..3781a1853998 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c @@ -29,14 +29,14 @@ static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf" static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", }; static const char const *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", }; static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", }; -static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_post_div", "dummy", }; +static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", }; static const char const *perclk_sels[] = { "ipg", "osc", }; static const char const *epdc_pxp_sels[] = { "mmdc", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd1", }; static const char const *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", }; static const char const *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", }; static const char const *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", }; static const char const *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", }; -static const char const *audio_sels[] = { "pll4_post_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", }; +static const char const *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", }; static const char const *ecspi_sels[] = { "pll3_60m", "osc", }; static const char const *uart_sels[] = { "pll3_80m", "osc", }; @@ -63,7 +63,7 @@ static struct clk_div_table video_div_table[] = { { } }; -static struct clk *clks[IMX6SL_CLK_CLK_END]; +static struct clk *clks[IMX6SL_CLK_END]; static struct clk_onecell_data clk_data; static void __init imx6sl_clocks_init(struct device_node *ccm_node) @@ -104,6 +104,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) /* dev name parent_name flags reg shift width div: flags, div_table lock */ clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); + clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); @@ -232,6 +233,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); + clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14); clks[IMX6SL_CLK_SSI1] = imx_clk_gate2("ssi1", "ssi1_podf", base + 0x7c, 18); clks[IMX6SL_CLK_SSI2] = imx_clk_gate2("ssi2", "ssi2_podf", base + 0x7c, 20); @@ -261,6 +263,9 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]); } + /* Audio-related clocks configuration */ + clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt"); base = of_iomap(np, 0); WARN_ON(!base); diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c index e2ed4160f329..0b0f6f66ec56 100644 --- a/arch/arm/mach-imx/clk-pfd.c +++ b/arch/arm/mach-imx/clk-pfd.c @@ -109,12 +109,23 @@ static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static int clk_pfd_is_enabled(struct clk_hw *hw) +{ + struct clk_pfd *pfd = to_clk_pfd(hw); + + if (readl_relaxed(pfd->reg) & (1 << ((pfd->idx + 1) * 8 - 1))) + return 0; + + return 1; +} + static const struct clk_ops clk_pfd_ops = { .enable = clk_pfd_enable, .disable = clk_pfd_disable, .recalc_rate = clk_pfd_recalc_rate, .round_rate = clk_pfd_round_rate, .set_rate = clk_pfd_set_rate, + .is_enabled = clk_pfd_is_enabled, }; struct clk *imx_clk_pfd(const char *name, const char *parent_name, diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c index c1eaee346954..d21d14ca46c1 100644 --- a/arch/arm/mach-imx/clk-pllv1.c +++ b/arch/arm/mach-imx/clk-pllv1.c @@ -18,6 +18,11 @@ * * PLL clock version 1, found on i.MX1/21/25/27/31/35 */ + +#define MFN_BITS (10) +#define MFN_SIGN (BIT(MFN_BITS - 1)) +#define MFN_MASK (MFN_SIGN - 1) + struct clk_pllv1 { struct clk_hw hw; void __iomem *base; @@ -25,6 +30,11 @@ struct clk_pllv1 { #define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk)) +static inline bool mfn_is_negative(unsigned int mfn) +{ + return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN); +} + static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -58,10 +68,15 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, /* * On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit - * 2's complements number + * 2's complements number. + * On i.MX27 the bit 9 is the sign bit. */ - if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200) - mfn_abs = 0x400 - mfn; + if (mfn_is_negative(mfn)) { + if (cpu_is_mx27()) + mfn_abs = mfn & MFN_MASK; + else + mfn_abs = BIT(MFN_BITS) - mfn; + } rate = parent_rate * 2; rate /= pd + 1; @@ -70,7 +85,7 @@ static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, do_div(ll, mfd + 1); - if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200) + if (mfn_is_negative(mfn)) ll = -ll; ll = (rate * mfi) + ll; diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index b169a396d93b..ecd66d8e20b6 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -298,6 +298,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(0)); clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(4)); + clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4)); + clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5)); + clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1)); + clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2)); + clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]); clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2); clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 24a7899e36a8..59c3b9b26bb4 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -108,6 +108,7 @@ void tzic_handle_irq(struct pt_regs *); #define imx27_handle_irq avic_handle_irq #define imx31_handle_irq avic_handle_irq #define imx35_handle_irq avic_handle_irq +#define imx50_handle_irq tzic_handle_irq #define imx51_handle_irq tzic_handle_irq #define imx53_handle_irq tzic_handle_irq diff --git a/arch/arm/mach-imx/imx31-dt.c b/arch/arm/mach-imx/imx31-dt.c index 818a1cc2fe45..e1e70ef7bc2d 100644 --- a/arch/arm/mach-imx/imx31-dt.c +++ b/arch/arm/mach-imx/imx31-dt.c @@ -25,7 +25,7 @@ static void __init imx31_dt_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static const char *imx31_dt_board_compat[] __initdata = { +static const char *imx31_dt_board_compat[] __initconst = { "fsl,imx31", NULL }; diff --git a/arch/arm/mach-imx/imx35-dt.c b/arch/arm/mach-imx/imx35-dt.c new file mode 100644 index 000000000000..9d48e0065a63 --- /dev/null +++ b/arch/arm/mach-imx/imx35-dt.c @@ -0,0 +1,50 @@ +/* + * Copyright 2012 Steffen Trumtrar, Pengutronix + * + * based on imx27-dt.c + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mx35.h" + +static void __init imx35_dt_init(void) +{ + mxc_arch_reset_init_dt(); + + of_platform_populate(NULL, of_default_bus_match_table, + NULL, NULL); +} + +static void __init imx35_irq_init(void) +{ + imx_init_l2cache(); + mx35_init_irq(); +} + +static const char *imx35_dt_board_compat[] __initconst = { + "fsl,imx35", + NULL +}; + +DT_MACHINE_START(IMX35_DT, "Freescale i.MX35 (Device Tree Support)") + .map_io = mx35_map_io, + .init_early = imx35_init_early, + .init_irq = imx35_irq_init, + .handle_irq = imx35_handle_irq, + .init_machine = imx35_dt_init, + .dt_compat = imx35_dt_board_compat, + .restart = mxc_restart, +MACHINE_END diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c index bece8a65e6f0..0230d78d1413 100644 --- a/arch/arm/mach-imx/imx51-dt.c +++ b/arch/arm/mach-imx/imx51-dt.c @@ -29,7 +29,7 @@ static void __init imx51_dt_init(void) platform_device_register_full(&devinfo); } -static const char *imx51_dt_board_compat[] __initdata = { +static const char *imx51_dt_board_compat[] __initconst = { "fsl,imx51", NULL }; diff --git a/arch/arm/mach-imx/irq-common.h b/arch/arm/mach-imx/irq-common.h index 5b2dabba330f..6e3175dc0c0a 100644 --- a/arch/arm/mach-imx/irq-common.h +++ b/arch/arm/mach-imx/irq-common.h @@ -24,7 +24,6 @@ struct mxc_extra_irq { - int (*set_priority)(unsigned char irq, unsigned char prio); int (*set_irq_fiq)(unsigned int irq, unsigned int type); }; diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c index 771362d1fbee..65e4c53e1554 100644 --- a/arch/arm/mach-imx/mach-cpuimx35.c +++ b/arch/arm/mach-imx/mach-cpuimx35.c @@ -53,7 +53,7 @@ static const struct imxi2c_platform_data }; #define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2) -static int tsc2007_get_pendown_state(void) +static int tsc2007_get_pendown_state(struct device *dev) { return !gpio_get_value(TSC2007_IRQGPIO); } diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index 9b5ddf5bbd33..1fba2b8e983f 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -121,7 +121,7 @@ static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; -static int tsc2007_get_pendown_state(void) +static int tsc2007_get_pendown_state(struct device *dev) { if (mx51_revision() < IMX_CHIP_REVISION_3_0) return !gpio_get_value(TSC2007_IRQGPIO_REV2); diff --git a/arch/arm/mach-imx/mach-imx50.c b/arch/arm/mach-imx/mach-imx50.c new file mode 100644 index 000000000000..77b77a92bb5d --- /dev/null +++ b/arch/arm/mach-imx/mach-imx50.c @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Greg Ungerer + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2011 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include + +#include "common.h" + +static void __init imx50_dt_init(void) +{ + mxc_arch_reset_init_dt(); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *imx50_dt_board_compat[] __initconst = { + "fsl,imx50", + NULL +}; + +DT_MACHINE_START(IMX50_DT, "Freescale i.MX50 (Device Tree Support)") + .map_io = mx53_map_io, + .init_irq = mx53_init_irq, + .handle_irq = imx50_handle_irq, + .init_machine = imx50_dt_init, + .dt_compat = imx50_dt_board_compat, + .restart = mxc_restart, +MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx53.c b/arch/arm/mach-imx/mach-imx53.c index c9c4d8d96931..65850908a4b4 100644 --- a/arch/arm/mach-imx/mach-imx53.c +++ b/arch/arm/mach-imx/mach-imx53.c @@ -31,7 +31,7 @@ static void __init imx53_dt_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static const char *imx53_dt_board_compat[] __initdata = { +static const char *imx53_dt_board_compat[] __initconst = { "fsl,imx53", NULL }; diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index d0cfb225ec9a..d2ea6e60ea7b 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +80,34 @@ static int ksz9031rn_phy_fixup(struct phy_device *dev) return 0; } +/* + * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High + * as they are used for slots1-7 PERST# + */ +static void ventana_pciesw_early_fixup(struct pci_dev *dev) +{ + u32 dw; + + if (!of_machine_is_compatible("gw,ventana")) + return; + + if (dev->devfn != 0) + return; + + pci_read_config_dword(dev, 0x62c, &dw); + dw |= 0xaaa8; // GPIO1-7 outputs + pci_write_config_dword(dev, 0x62c, dw); + + pci_read_config_dword(dev, 0x644, &dw); + dw |= 0xfe; // GPIO1-7 output high + pci_write_config_dword(dev, 0x644, dw); + + msleep(100); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup); + static int ar8031_phy_fixup(struct phy_device *dev) { u16 val; @@ -243,7 +273,7 @@ static void __init imx6q_init_irq(void) irqchip_init(); } -static const char *imx6q_dt_compat[] __initdata = { +static const char *imx6q_dt_compat[] __initconst = { "fsl,imx6dl", "fsl,imx6q", NULL, diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index 2f952e3fcf89..0f4fd4c0ab8e 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -34,6 +34,13 @@ static void __init imx6sl_fec_init(void) } } +static void __init imx6sl_init_late(void) +{ + /* imx6sl reuses imx6q cpufreq driver */ + if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) + platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0); +} + static void __init imx6sl_init_machine(void) { struct device *parent; @@ -61,7 +68,7 @@ static void __init imx6sl_init_irq(void) irqchip_init(); } -static const char *imx6sl_dt_compat[] __initdata = { +static const char *imx6sl_dt_compat[] __initconst = { "fsl,imx6sl", NULL, }; @@ -70,6 +77,7 @@ DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)") .map_io = debug_ll_io_init, .init_irq = imx6sl_init_irq, .init_machine = imx6sl_init_machine, + .init_late = imx6sl_init_late, .dt_compat = imx6sl_dt_compat, .restart = mxc_restart, MACHINE_END diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c index c5f95674e9b7..bf3ac51d5aca 100644 --- a/arch/arm/mach-imx/mach-pca100.c +++ b/arch/arm/mach-imx/mach-pca100.c @@ -249,7 +249,7 @@ static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq, "imx-mmc-detect", data); if (ret) printk(KERN_ERR - "pca100: Failed to reuest irq for sd/mmc detection\n"); + "pca100: Failed to request irq for sd/mmc detection\n"); return ret; } diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c index af0cb8a9dc48..2d8aef5a6efa 100644 --- a/arch/arm/mach-imx/mach-vf610.c +++ b/arch/arm/mach-imx/mach-vf610.c @@ -26,7 +26,7 @@ static void __init vf610_init_irq(void) irqchip_init(); } -static const char *vf610_dt_compat[] __initdata = { +static const char *vf610_dt_compat[] __initconst = { "fsl,vf610", NULL, }; diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index d1d52600f458..4c112021aa4e 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -89,15 +89,7 @@ void __init imx51_init_early(void) void __init imx53_init_early(void) { - struct device_node *np; - void __iomem *base; - mxc_set_cpu_type(MXC_CPU_MX53); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx53-iomuxc"); - base = of_iomap(np, 0); - WARN_ON(!base); - mxc_iomux_v3_init(base); imx_src_init(); } diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 1f24c1fdfea4..5b57c17c06bd 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -92,8 +92,7 @@ static void __init imx_smp_prepare_cpus(unsigned int max_cpus) * secondary cores when booting them. */ asm("mrc p15, 0, %0, c15, c0, 1" : "=r" (g_diag_reg) : : "cc"); - __cpuc_flush_dcache_area(&g_diag_reg, sizeof(g_diag_reg)); - outer_clean_range(__pa(&g_diag_reg), __pa(&g_diag_reg + 1)); + sync_cache_w(&g_diag_reg); } struct smp_operations imx_smp_ops __initdata = { diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c index aecd9f8037e0..9d47adc078aa 100644 --- a/arch/arm/mach-imx/pm-imx6q.c +++ b/arch/arm/mach-imx/pm-imx6q.c @@ -156,10 +156,16 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) } /* - * Unmask the always pending IOMUXC interrupt #32 as wakeup source to - * deassert dsm_request signal, so that we can ensure dsm_request - * is not asserted when we're going to write CLPCR register to set LPM. - * After setting up LPM bits, we need to mask this wakeup source. + * ERR007265: CCM: When improper low-power sequence is used, + * the SoC enters low power mode before the ARM core executes WFI. + * + * Software workaround: + * 1) Software should trigger IRQ #32 (IOMUX) to be always pending + * by setting IOMUX_GPR1_GINT. + * 2) Software should then unmask IRQ #32 in GPC before setting CCM + * Low-Power mode. + * 3) Software should mask IRQ #32 right after CCM Low-Power mode + * is set (set bits 0-1 of CCM_CLPCR). */ iomuxc_irq_desc = irq_to_desc(32); imx_gpc_irq_unmask(&iomuxc_irq_desc->irq_data); @@ -219,6 +225,8 @@ void __init imx6q_pm_init(void) WARN_ON(!ccm_base); /* + * This is for SW workaround step #1 of ERR007265, see comments + * in imx6q_set_lpm for details of this errata. * Force IOMUXC irq pending, so that the interrupt to GPC can be * used to deassert dsm_request signal when the signal gets * asserted unexpectedly. diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 9b6638aadeaa..1a3a5f615770 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -111,7 +111,7 @@ static void gpt_irq_acknowledge(void) static void __iomem *sched_clock_reg; -static u32 notrace mxc_read_sched_clock(void) +static u64 notrace mxc_read_sched_clock(void) { return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; } @@ -123,7 +123,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk) sched_clock_reg = reg; - setup_sched_clock(mxc_read_sched_clock, 32, c); + sched_clock_register(mxc_read_sched_clock, 32, c); return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, clocksource_mmio_readl_up); } diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index d50dc2dbfd89..17c0fe627435 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -63,6 +63,9 @@ /* Base address to the AP system controller */ void __iomem *ap_syscon_base; +/* Base address to the external bus interface */ +static void __iomem *ebi_base; + /* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx @@ -72,15 +75,11 @@ void __iomem *ap_syscon_base; * just for now). */ #define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE) -#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE) -#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC) /* * Logical Physical * ef000000 Cache flush - * f1000000 10000000 Core module registers * f1100000 11000000 System controller registers - * f1200000 12000000 EBI registers * f1300000 13000000 Counter/Timer * f1400000 14000000 Interrupt controller * f1600000 16000000 UART 0 @@ -91,16 +90,6 @@ void __iomem *ap_syscon_base; static struct map_desc ap_io_desc[] __initdata __maybe_unused = { { - .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), - .length = SZ_4K, - .type = MT_DEVICE - }, { - .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), - .length = SZ_4K, - .type = MT_DEVICE - }, { .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), .length = SZ_4K, @@ -174,9 +163,6 @@ device_initcall(irq_syscore_init); /* * Flash handling. */ -#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET) -#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET) - static int ap_flash_init(struct platform_device *dev) { u32 tmp; @@ -184,13 +170,15 @@ static int ap_flash_init(struct platform_device *dev) writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET); - tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE; - writel(tmp, EBI_CSR1); + tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) | + INTEGRATOR_EBI_WRITE_ENABLE; + writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET); - if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) { - writel(0xa05f, EBI_LOCK); - writel(tmp, EBI_CSR1); - writel(0, EBI_LOCK); + if (!(readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) + & INTEGRATOR_EBI_WRITE_ENABLE)) { + writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET); + writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET); + writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET); } return 0; } @@ -202,13 +190,15 @@ static void ap_flash_exit(struct platform_device *dev) writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, ap_syscon_base + INTEGRATOR_SC_CTRLC_OFFSET); - tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE; - writel(tmp, EBI_CSR1); + tmp = readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) & + ~INTEGRATOR_EBI_WRITE_ENABLE; + writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET); - if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) { - writel(0xa05f, EBI_LOCK); - writel(tmp, EBI_CSR1); - writel(0, EBI_LOCK); + if (readl(ebi_base + INTEGRATOR_EBI_CSR1_OFFSET) & + INTEGRATOR_EBI_WRITE_ENABLE) { + writel(0xa05f, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET); + writel(tmp, ebi_base + INTEGRATOR_EBI_CSR1_OFFSET); + writel(0, ebi_base + INTEGRATOR_EBI_LOCK_OFFSET); } } @@ -277,7 +267,7 @@ struct amba_pl010_data ap_uart_data = { static unsigned long timer_reload; -static u32 notrace integrator_read_sched_clock(void) +static u64 notrace integrator_read_sched_clock(void) { return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); } @@ -298,7 +288,7 @@ static void integrator_clocksource_init(unsigned long inrate, clocksource_mmio_init(base + TIMER_VALUE, "timer2", rate, 200, 16, clocksource_mmio_readl_down); - setup_sched_clock(integrator_read_sched_clock, 16, rate); + sched_clock_register(integrator_read_sched_clock, 16, rate); } static void __iomem * clkevt_base; @@ -475,11 +465,17 @@ static const struct of_device_id ap_syscon_match[] = { { }, }; +static const struct of_device_id ebi_match[] = { + { .compatible = "arm,external-bus-interface"}, + { }, +}; + static void __init ap_init_of(void) { unsigned long sc_dec; struct device_node *root; struct device_node *syscon; + struct device_node *ebi; struct device *parent; struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; @@ -495,10 +491,16 @@ static void __init ap_init_of(void) syscon = of_find_matching_node(root, ap_syscon_match); if (!syscon) return; + ebi = of_find_matching_node(root, ebi_match); + if (!ebi) + return; ap_syscon_base = of_iomap(syscon, 0); if (!ap_syscon_base) return; + ebi_base = of_iomap(ebi, 0); + if (!ebi_base) + return; ap_sc_id = readl(ap_syscon_base); diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 4fc0a195de01..5e84149d1790 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -64,9 +64,6 @@ static void __iomem *intcp_con_base; /* * Logical Physical - * f1000000 10000000 Core module registers - * f1100000 11000000 System controller registers - * f1200000 12000000 EBI registers * f1300000 13000000 Counter/Timer * f1400000 14000000 Interrupt controller * f1600000 16000000 UART 0 @@ -74,21 +71,10 @@ static void __iomem *intcp_con_base; * f1a00000 1a000000 Debug LEDs * fc900000 c9000000 GPIO * fca00000 ca000000 SIC - * fcb00000 cb000000 CP system control */ static struct map_desc intcp_io_desc[] __initdata __maybe_unused = { { - .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE), - .length = SZ_4K, - .type = MT_DEVICE - }, { - .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE), - .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE), - .length = SZ_4K, - .type = MT_DEVICE - }, { .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE), .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE), .length = SZ_4K, diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 6d6bde3e15fa..200970d56f6d 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -326,7 +326,7 @@ static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t s */ static int ixp4xx_pci_platform_notify(struct device *dev) { - if(dev->bus == &pci_bus_type) { + if (dev_is_pci(dev)) { *dev->dma_mask = SZ_64M - 1; dev->coherent_dma_mask = SZ_64M - 1; dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce); @@ -336,9 +336,9 @@ static int ixp4xx_pci_platform_notify(struct device *dev) static int ixp4xx_pci_platform_notify_remove(struct device *dev) { - if(dev->bus == &pci_bus_type) { + if (dev_is_pci(dev)) dmabounce_unregister_dev(dev); - } + return 0; } diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 9edaf4734fa8..6d68aed6548a 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -475,7 +475,7 @@ void __init ixp4xx_sys_init(void) /* * sched_clock() */ -static u32 notrace ixp4xx_read_sched_clock(void) +static u64 notrace ixp4xx_read_sched_clock(void) { return *IXP4XX_OSTS; } @@ -493,7 +493,7 @@ unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; EXPORT_SYMBOL(ixp4xx_timer_freq); static void __init ixp4xx_clocksource_init(void) { - setup_sched_clock(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq); + sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq); clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32, ixp4xx_clocksource_read); @@ -560,7 +560,7 @@ static void __init ixp4xx_clockevent_init(void) void ixp4xx_restart(enum reboot_mode mode, const char *cmd) { - if ( 1 && mode == REBOOT_SOFT) { + if (mode == REBOOT_SOFT) { /* Jump into ROM at address 0 */ soft_restart(0); } else { diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig index f20c53e75ed9..dabc5eee52e7 100644 --- a/arch/arm/mach-keystone/Kconfig +++ b/arch/arm/mach-keystone/Kconfig @@ -11,6 +11,8 @@ config ARCH_KEYSTONE select ARM_ERRATA_798181 if SMP select COMMON_CLK_KEYSTONE select TI_EDMA + select ARCH_SUPPORTS_BIG_ENDIAN + select ZONE_DMA if ARM_LPAE help Support for boards based on the Texas Instruments Keystone family of SoCs. diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index b661c5c2870a..6e6bb7d5ea30 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -41,6 +41,7 @@ static void __init keystone_init(void) if (WARN_ON(!keystone_rstctrl)) pr_warn("ti,keystone-reset iomap error\n"); + keystone_pm_runtime_init(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -68,6 +69,9 @@ void keystone_restart(enum reboot_mode mode, const char *cmd) } DT_MACHINE_START(KEYSTONE, "Keystone") +#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE) + .dma_zone_size = SZ_2G, +#endif .smp = smp_ops(keystone_smp_ops), .init_machine = keystone_init, .dt_compat = keystone_match, diff --git a/arch/arm/mach-keystone/keystone.h b/arch/arm/mach-keystone/keystone.h index 60bef9dedb12..cd04a1c14de8 100644 --- a/arch/arm/mach-keystone/keystone.h +++ b/arch/arm/mach-keystone/keystone.h @@ -18,6 +18,7 @@ extern struct smp_operations keystone_smp_ops; extern void secondary_startup(void); extern u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr); +extern int keystone_pm_runtime_init(void); #endif /* __ASSEMBLER__ */ #endif /* __KEYSTONE_H__ */ diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c index 29625232e954..ca79ddac38bc 100644 --- a/arch/arm/mach-keystone/pm_domain.c +++ b/arch/arm/mach-keystone/pm_domain.c @@ -74,9 +74,7 @@ int __init keystone_pm_runtime_init(void) if (!np) return 0; - of_clk_init(NULL); pm_clk_add_notifier(&platform_bus_type, &platform_domain_notifier); return 0; } -subsys_initcall(keystone_pm_runtime_init); diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 9caa4fe95913..78188159484d 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -10,55 +10,21 @@ * warranty of any kind, whether express or implied. */ +#include #include #include #include #include #include #include -#include #include #include #include #include -#include #include -#include -#include #include #include "common.h" -/* - * There are still devices that doesn't know about DT yet. Get clock - * gates here and add a clock lookup alias, so that old platform - * devices still work. -*/ - -static void __init kirkwood_legacy_clk_init(void) -{ - - struct device_node *np = of_find_compatible_node( - NULL, NULL, "marvell,kirkwood-gating-clock"); - struct of_phandle_args clkspec; - struct clk *clk; - - clkspec.np = np; - clkspec.args_count = 1; - - /* - * The ethernet interfaces forget the MAC address assigned by - * u-boot if the clocks are turned off. Until proper DT support - * is available we always enable them for now. - */ - clkspec.args[0] = CGC_BIT_GE0; - clk = of_clk_get_from_provider(&clkspec); - clk_prepare_enable(clk); - - clkspec.args[0] = CGC_BIT_GE1; - clk = of_clk_get_from_provider(&clkspec); - clk_prepare_enable(clk); -} - #define MV643XX_ETH_MAC_ADDR_LOW 0x0414 #define MV643XX_ETH_MAC_ADDR_HIGH 0x0418 @@ -140,7 +106,7 @@ eth_fixup_skip: static void __init kirkwood_dt_init(void) { - pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); + pr_info("Kirkwood: %s.\n", kirkwood_id()); /* * Disable propagation of mbus errors to the CPU local bus, @@ -156,8 +122,6 @@ static void __init kirkwood_dt_init(void) kirkwood_cpufreq_init(); kirkwood_cpuidle_init(); - /* Setup clocks for legacy devices */ - kirkwood_legacy_clk_init(); kirkwood_pm_init(); kirkwood_dt_eth_fixup(); diff --git a/arch/arm/mach-ks8695/include/mach/gpio.h b/arch/arm/mach-ks8695/include/mach/gpio.h deleted file mode 100644 index f5fda36e4512..000000000000 --- a/arch/arm/mach-ks8695/include/mach/gpio.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/arm/mach-ks8695/include/mach/gpio.h - * - * Copyright (C) 2006 Andrew Victor - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_GPIO_H_ -#define __ASM_ARCH_GPIO_H_ - -/* - * Map IRQ number to GPIO line. - */ -extern int irq_to_gpio(unsigned int irq); - -#endif diff --git a/arch/arm/mach-lpc32xx/include/mach/gpio.h b/arch/arm/mach-lpc32xx/include/mach/gpio.h deleted file mode 100644 index 0052e7a76179..000000000000 --- a/arch/arm/mach-lpc32xx/include/mach/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __MACH_GPIO_H -#define __MACH_GPIO_H - -#include "gpio-lpc32xx.h" - -#endif /* __MACH_GPIO_H */ diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index e54f87ec2e4a..34932e0e31fa 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -44,7 +45,6 @@ #include #include #include -#include #include "common.h" /* diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index ebdda8346a26..ebdba87b9671 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -136,4 +136,7 @@ config USB_EHCI_MV_U2O help Enables support for OTG controller which can be switched to host mode. +config MMP_SRAM + bool + endif diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 9b702a1dc7b0..98f0f6388e44 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -7,7 +7,8 @@ obj-y += common.o devices.o time.o # SoC support obj-$(CONFIG_CPU_PXA168) += pxa168.o obj-$(CONFIG_CPU_PXA910) += pxa910.o -obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o +obj-$(CONFIG_CPU_MMP2) += mmp2.o +obj-$(CONFIG_MMP_SRAM) += sram.o ifeq ($(CONFIG_COMMON_CLK), ) obj-y += clock.o diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c index 7ac41e83cfef..024022d91fe3 100644 --- a/arch/arm/mach-mmp/time.c +++ b/arch/arm/mach-mmp/time.c @@ -61,7 +61,7 @@ static inline uint32_t timer_read(void) return __raw_readl(mmp_timer_base + TMR_CVWR(1)); } -static u32 notrace mmp_read_sched_clock(void) +static u64 notrace mmp_read_sched_clock(void) { return timer_read(); } @@ -195,7 +195,7 @@ void __init timer_init(int irq) { timer_config(); - setup_sched_clock(mmp_read_sched_clock, 32, CLOCK_TICK_RATE); + sched_clock_register(mmp_read_sched_clock, 32, CLOCK_TICK_RATE); ckevt.cpumask = cpumask_of(0); diff --git a/arch/arm/mach-moxart/Kconfig b/arch/arm/mach-moxart/Kconfig new file mode 100644 index 000000000000..ba470d64493b --- /dev/null +++ b/arch/arm/mach-moxart/Kconfig @@ -0,0 +1,31 @@ +config ARCH_MOXART + bool "MOXA ART SoC" if ARCH_MULTI_V4T + select CPU_FA526 + select ARM_DMA_MEM_BUFFERABLE + select DMA_OF + select USE_OF + select CLKSRC_OF + select CLKSRC_MMIO + select HAVE_CLK + select COMMON_CLK + select GENERIC_IRQ_CHIP + select ARCH_REQUIRE_GPIOLIB + select GENERIC_CLOCKEVENTS + select PHYLIB if NETDEVICES + help + Say Y here if you want to run your kernel on hardware with a + MOXA ART SoC. + The MOXA ART SoC is based on a Faraday FA526 ARMv4 32-bit + 192 MHz CPU with MMU and 16KB/8KB D/I-cache (UC-7112-LX). + Used on models UC-7101, UC-7112/UC-7110, IA240/IA241, IA3341. + +if ARCH_MOXART + +config MACH_UC7112LX + bool "MOXA UC-7112-LX" + depends on ARCH_MOXART + help + Say Y here if you intend to run this kernel on a MOXA + UC-7112-LX embedded computer. + +endif diff --git a/arch/arm/mach-moxart/Makefile b/arch/arm/mach-moxart/Makefile new file mode 100644 index 000000000000..fa022eb10ca1 --- /dev/null +++ b/arch/arm/mach-moxart/Makefile @@ -0,0 +1,3 @@ +# Object file lists. + +obj-$(CONFIG_MACH_UC7112LX) += moxart.o diff --git a/arch/arm/mach-moxart/moxart.c b/arch/arm/mach-moxart/moxart.c new file mode 100644 index 000000000000..86b6d9b57c54 --- /dev/null +++ b/arch/arm/mach-moxart/moxart.c @@ -0,0 +1,15 @@ +/* + * arch/arm/mach-moxart/moxart.c + * + * (C) Copyright 2013, Jonas Jensen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 2586c2865874..9625cf378931 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -1,12 +1,50 @@ +config ARCH_MSM + bool + +config ARCH_MSM_DT + bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7 + select ARCH_MSM + select ARCH_REQUIRE_GPIOLIB + select CLKSRC_OF + select GENERIC_CLOCKEVENTS + help + Support for Qualcomm's devicetree based MSM systems. + if ARCH_MSM -comment "Qualcomm MSM SoC Type" +menu "Qualcomm MSM SoC Selection" depends on ARCH_MSM_DT +config ARCH_MSM8X60 + bool "Enable support for MSM8X60" + select ARM_GIC + select CPU_V7 + select HAVE_SMP + select MSM_SCM if SMP + select MSM_TIMER + +config ARCH_MSM8960 + bool "Enable support for MSM8960" + select ARM_GIC + select CPU_V7 + select HAVE_SMP + select MSM_SCM if SMP + select MSM_TIMER + +config ARCH_MSM8974 + bool "Enable support for MSM8974" + select ARM_GIC + select CPU_V7 + select HAVE_ARM_ARCH_TIMER + select HAVE_SMP + select MSM_SCM if SMP + +endmenu + choice prompt "Qualcomm MSM SoC Type" default ARCH_MSM7X00A - depends on !ARCH_MSM_DT + depends on ARCH_MSM_NODT config ARCH_MSM7X00A bool "MSM7x00A / MSM7x01A" @@ -16,6 +54,7 @@ config ARCH_MSM7X00A select MACH_TROUT if !MACH_HALIBUT select MSM_PROC_COMM select MSM_SMD + select MSM_TIMER select MSM_SMD_PKG3 config ARCH_MSM7X30 @@ -27,6 +66,7 @@ config ARCH_MSM7X30 select MSM_GPIOMUX select MSM_PROC_COMM select MSM_SMD + select MSM_TIMER select MSM_VIC config ARCH_QSD8X50 @@ -38,32 +78,11 @@ config ARCH_QSD8X50 select MSM_GPIOMUX select MSM_PROC_COMM select MSM_SMD + select MSM_TIMER select MSM_VIC endchoice -config ARCH_MSM8X60 - bool "MSM8X60" - select ARM_GIC - select CPU_V7 - select GPIO_MSM_V2 - select HAVE_SMP - select MSM_SCM if SMP - -config ARCH_MSM8960 - bool "MSM8960" - select ARM_GIC - select CPU_V7 - select HAVE_SMP - select GPIO_MSM_V2 - select MSM_SCM if SMP - -config ARCH_MSM_DT - def_bool y - depends on (ARCH_MSM8X60 || ARCH_MSM8960) - select SPARSE_IRQ - select USE_OF - config MSM_HAS_DEBUG_UART_HS bool @@ -80,7 +99,7 @@ config MSM_VIC bool menu "Qualcomm MSM Board Type" - depends on !ARCH_MSM_DT + depends on ARCH_MSM_NODT config MACH_HALIBUT depends on ARCH_MSM @@ -128,10 +147,13 @@ config MSM_SMD config MSM_GPIOMUX bool - depends on !ARCH_MSM_DT help Support for MSM V1 TLMM GPIOMUX architecture. config MSM_SCM bool + +config MSM_TIMER + bool + endif diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 7ed4c1b2bdd2..8e307a10d3c3 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -1,5 +1,5 @@ -obj-y += timer.o -obj-y += clock.o +obj-$(CONFIG_MSM_TIMER) += timer.o +obj-$(CONFIG_MSM_PROC_COMM) += clock.o obj-$(CONFIG_MSM_VIC) += irq-vic.o diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c index 16e6183ac9f1..1f11d93e700e 100644 --- a/arch/arm/mach-msm/board-dt.c +++ b/arch/arm/mach-msm/board-dt.c @@ -26,7 +26,16 @@ static const char * const msm_dt_match[] __initconst = { NULL }; +static const char * const apq8074_dt_match[] __initconst = { + "qcom,apq8074-dragonboard", + NULL +}; + DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") .smp = smp_ops(msm_smp_ops), .dt_compat = msm_dt_match, MACHINE_END + +DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)") + .dt_compat = apq8074_dt_match, +MACHINE_END diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index f9af5a46e8b6..46de789ad3ae 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -60,10 +61,44 @@ static int hsusb_phy_init_seq[] = { -1 }; +static int hsusb_link_clk_reset(struct clk *link_clk, bool assert) +{ + int ret; + + if (assert) { + ret = clk_reset(link_clk, CLK_RESET_ASSERT); + if (ret) + pr_err("usb hs_clk assert failed\n"); + } else { + ret = clk_reset(link_clk, CLK_RESET_DEASSERT); + if (ret) + pr_err("usb hs_clk deassert failed\n"); + } + return ret; +} + +static int hsusb_phy_clk_reset(struct clk *phy_clk) +{ + int ret; + + ret = clk_reset(phy_clk, CLK_RESET_ASSERT); + if (ret) { + pr_err("usb phy clk assert failed\n"); + return ret; + } + usleep_range(10000, 12000); + ret = clk_reset(phy_clk, CLK_RESET_DEASSERT); + if (ret) + pr_err("usb phy clk deassert failed\n"); + return ret; +} + static struct msm_otg_platform_data msm_otg_pdata = { .phy_init_seq = hsusb_phy_init_seq, .mode = USB_PERIPHERAL, .otg_control = OTG_PHY_CONTROL, + .link_clk_reset = hsusb_link_clk_reset, + .phy_clk_reset = hsusb_phy_clk_reset, }; struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = { diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 5f933bc50783..9169ec324a43 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "devices.h" @@ -81,10 +82,44 @@ static int hsusb_phy_init_seq[] = { -1 }; +static int hsusb_link_clk_reset(struct clk *link_clk, bool assert) +{ + int ret; + + if (assert) { + ret = clk_reset(link_clk, CLK_RESET_ASSERT); + if (ret) + pr_err("usb hs_clk assert failed\n"); + } else { + ret = clk_reset(link_clk, CLK_RESET_DEASSERT); + if (ret) + pr_err("usb hs_clk deassert failed\n"); + } + return ret; +} + +static int hsusb_phy_clk_reset(struct clk *phy_clk) +{ + int ret; + + ret = clk_reset(phy_clk, CLK_RESET_ASSERT); + if (ret) { + pr_err("usb phy clk assert failed\n"); + return ret; + } + usleep_range(10000, 12000); + ret = clk_reset(phy_clk, CLK_RESET_DEASSERT); + if (ret) + pr_err("usb phy clk deassert failed\n"); + return ret; +} + static struct msm_otg_platform_data msm_otg_pdata = { .phy_init_seq = hsusb_phy_init_seq, .mode = USB_PERIPHERAL, .otg_control = OTG_PHY_CONTROL, + .link_clk_reset = hsusb_link_clk_reset, + .phy_clk_reset = hsusb_phy_clk_reset, }; static struct platform_device *devices[] __initdata = { diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c index ccf6621bc664..015d544aa017 100644 --- a/arch/arm/mach-msm/board-trout.c +++ b/arch/arm/mach-msm/board-trout.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. * */ +#define pr_fmt(fmt) "%s: " fmt, __func__ #include #include @@ -68,12 +69,11 @@ static void __init trout_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); -#ifdef CONFIG_MMC - rc = trout_init_mmc(system_rev); - if (rc) - printk(KERN_CRIT "%s: MMC init failure (%d)\n", __func__, rc); -#endif - + if (IS_ENABLED(CONFIG_MMC)) { + rc = trout_init_mmc(system_rev); + if (rc) + pr_crit("MMC init failure (%d)\n", rc); + } } static struct map_desc trout_io_desc[] __initdata = { diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 3f06edcdd0ce..f10a1f58fde9 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c @@ -99,8 +99,7 @@ static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle) * "cpu" is Linux's internal ID. */ pen_release = cpu_logical_map(cpu); - __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); - outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); + sync_cache_w(&pen_release); /* * Send the secondary CPU a soft interrupt, thereby causing diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 1e9c3383daba..fd1644987534 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -187,7 +187,7 @@ static struct notifier_block msm_timer_cpu_nb = { .notifier_call = msm_timer_cpu_notify, }; -static notrace u32 msm_sched_clock_read(void) +static u64 notrace msm_sched_clock_read(void) { return msm_clocksource.read(&msm_clocksource); } @@ -229,7 +229,7 @@ err: res = clocksource_register_hz(cs, dgt_hz); if (res) pr_err("clocksource_register failed\n"); - setup_sched_clock(msm_sched_clock_read, sched_bits, dgt_hz); + sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz); } #ifdef CONFIG_OF diff --git a/arch/arm/mach-mv78xx0/include/mach/gpio.h b/arch/arm/mach-mv78xx0/include/mach/gpio.h deleted file mode 100644 index 77e1b843e768..000000000000 --- a/arch/arm/mach-mv78xx0/include/mach/gpio.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * arch/asm-arm/mach-mv78xx0/include/mach/gpio.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 2d04f0e21870..878aebe98dcc 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -3,7 +3,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \ AFLAGS_coherency_ll.o := -Wa,-march=armv7-a -obj-y += system-controller.o +obj-y += system-controller.o mvebu-soc-id.o obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index e2acff98e750..f6c9d1d85c14 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include "armada-370-xp.h" #include "common.h" #include "coherency.h" +#include "mvebu-soc-id.h" static void __init armada_370_xp_map_io(void) { @@ -45,8 +47,38 @@ static void __init armada_370_xp_timer_and_clk_init(void) #endif } +static void __init i2c_quirk(void) +{ + struct device_node *np; + u32 dev, rev; + + /* + * Only revisons more recent than A0 support the offload + * mechanism. We can exit only if we are sure that we can + * get the SoC revision and it is more recent than A0. + */ + if (mvebu_get_soc_id(&rev, &dev) == 0 && dev > MV78XX0_A0_REV) + return; + + for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") { + struct property *new_compat; + + new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL); + + new_compat->name = kstrdup("compatible", GFP_KERNEL); + new_compat->length = sizeof("marvell,mv78230-a0-i2c"); + new_compat->value = kstrdup("marvell,mv78230-a0-i2c", + GFP_KERNEL); + + of_update_property(np, new_compat); + } + return; +} + static void __init armada_370_xp_dt_init(void) { + if (of_machine_is_compatible("plathome,openblocks-ax3-4")) + i2c_quirk(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h index c612b2c4ed6c..237c86b83390 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.h +++ b/arch/arm/mach-mvebu/armada-370-xp.h @@ -18,8 +18,12 @@ #ifdef CONFIG_SMP #include +#define ARMADA_XP_MAX_CPUS 4 + void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq); void armada_xp_mpic_smp_cpu_init(void); +void armada_xp_secondary_startup(void); +extern struct smp_operations armada_xp_smp_ops; #endif #endif /* __MACH_ARMADA_370_XP_H */ diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 58adf2fd9cfc..4e9d58148ca7 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -27,6 +27,7 @@ #include #include #include "armada-370-xp.h" +#include "coherency.h" unsigned long coherency_phys_base; static void __iomem *coherency_base; diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h index df33ad8a6c08..760226c41353 100644 --- a/arch/arm/mach-mvebu/coherency.h +++ b/arch/arm/mach-mvebu/coherency.h @@ -14,7 +14,9 @@ #ifndef __MACH_370_XP_COHERENCY_H #define __MACH_370_XP_COHERENCY_H -int set_cpu_coherent(int cpu_id, int smp_group_id); +extern unsigned long coherency_phys_base; + +int set_cpu_coherent(unsigned int cpu_id, int smp_group_id); int coherency_init(void); #endif /* __MACH_370_XP_COHERENCY_H */ diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index e366010e1d91..55449c487c9e 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h @@ -15,18 +15,10 @@ #ifndef __ARCH_MVEBU_COMMON_H #define __ARCH_MVEBU_COMMON_H -#define ARMADA_XP_MAX_CPUS 4 - #include void mvebu_restart(enum reboot_mode mode, const char *cmd); -void armada_370_xp_init_irq(void); -void armada_370_xp_handle_irq(struct pt_regs *regs); - void armada_xp_cpu_die(unsigned int cpu); -int armada_370_xp_coherency_init(void); -int armada_370_xp_pmsu_init(void); -void armada_xp_secondary_startup(void); -extern struct smp_operations armada_xp_smp_ops; + #endif diff --git a/arch/arm/mach-mvebu/hotplug.c b/arch/arm/mach-mvebu/hotplug.c index b228b6a80c85..d95e91047168 100644 --- a/arch/arm/mach-mvebu/hotplug.c +++ b/arch/arm/mach-mvebu/hotplug.c @@ -15,6 +15,7 @@ #include #include #include +#include "common.h" /* * platform-specific code to shutdown a CPU diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c new file mode 100644 index 000000000000..fe4fc1cbdfaf --- /dev/null +++ b/arch/arm/mach-mvebu/mvebu-soc-id.c @@ -0,0 +1,119 @@ +/* + * ID and revision information for mvebu SoCs + * + * Copyright (C) 2014 Marvell + * + * Gregory CLEMENT + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * All the mvebu SoCs have information related to their variant and + * revision that can be read from the PCI control register. This is + * done before the PCI initialization to avoid any conflict. Once the + * ID and revision are retrieved, the mapping is freed. + */ + +#define pr_fmt(fmt) "mvebu-soc-id: " fmt + +#include +#include +#include +#include +#include +#include +#include "mvebu-soc-id.h" + +#define PCIE_DEV_ID_OFF 0x0 +#define PCIE_DEV_REV_OFF 0x8 + +#define SOC_ID_MASK 0xFFFF0000 +#define SOC_REV_MASK 0xFF + +static u32 soc_dev_id; +static u32 soc_rev; +static bool is_id_valid; + +static const struct of_device_id mvebu_pcie_of_match_table[] = { + { .compatible = "marvell,armada-xp-pcie", }, + { .compatible = "marvell,armada-370-pcie", }, + {}, +}; + +int mvebu_get_soc_id(u32 *dev, u32 *rev) +{ + if (is_id_valid) { + *dev = soc_dev_id; + *rev = soc_rev; + return 0; + } else + return -1; +} + +static int __init mvebu_soc_id_init(void) +{ + struct device_node *np; + int ret = 0; + void __iomem *pci_base; + struct clk *clk; + struct device_node *child; + + np = of_find_matching_node(NULL, mvebu_pcie_of_match_table); + if (!np) + return ret; + + /* + * ID and revision are available from any port, so we + * just pick the first one + */ + child = of_get_next_child(np, NULL); + if (child == NULL) { + pr_err("cannot get pci node\n"); + ret = -ENOMEM; + goto clk_err; + } + + clk = of_clk_get_by_name(child, NULL); + if (IS_ERR(clk)) { + pr_err("cannot get clock\n"); + ret = -ENOMEM; + goto clk_err; + } + + ret = clk_prepare_enable(clk); + if (ret) { + pr_err("cannot enable clock\n"); + goto clk_err; + } + + pci_base = of_iomap(child, 0); + if (IS_ERR(pci_base)) { + pr_err("cannot map registers\n"); + ret = -ENOMEM; + goto res_ioremap; + } + + /* SoC ID */ + soc_dev_id = readl(pci_base + PCIE_DEV_ID_OFF) >> 16; + + /* SoC revision */ + soc_rev = readl(pci_base + PCIE_DEV_REV_OFF) & SOC_REV_MASK; + + is_id_valid = true; + + pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev); + + iounmap(pci_base); + +res_ioremap: + clk_disable_unprepare(clk); + +clk_err: + of_node_put(child); + of_node_put(np); + + return ret; +} +core_initcall(mvebu_soc_id_init); + diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.h b/arch/arm/mach-mvebu/mvebu-soc-id.h new file mode 100644 index 000000000000..31654252fe35 --- /dev/null +++ b/arch/arm/mach-mvebu/mvebu-soc-id.h @@ -0,0 +1,32 @@ +/* + * Marvell EBU SoC ID and revision definitions. + * + * Copyright (C) 2014 Marvell Semiconductor + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __LINUX_MVEBU_SOC_ID_H +#define __LINUX_MVEBU_SOC_ID_H + +/* Armada XP ID */ +#define MV78230_DEV_ID 0x7823 +#define MV78260_DEV_ID 0x7826 +#define MV78460_DEV_ID 0x7846 + +/* Armada XP Revision */ +#define MV78XX0_A0_REV 0x1 +#define MV78XX0_B0_REV 0x2 + +#ifdef CONFIG_ARCH_MVEBU +int mvebu_get_soc_id(u32 *dev, u32 *rev); +#else +static inline int mvebu_get_soc_id(u32 *dev, u32 *rev) +{ + return -1; +} +#endif + +#endif /* __LINUX_MVEBU_SOC_ID_H */ diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index ff69c2df298b..a6da03f5b24e 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -46,7 +46,7 @@ static struct clk *__init get_cpu_clk(int cpu) return cpu_clk; } -void __init set_secondary_cpus_clock(void) +static void __init set_secondary_cpus_clock(void) { int thiscpu, cpu; unsigned long rate; @@ -94,7 +94,7 @@ static void __init armada_xp_smp_init_cpus(void) set_smp_cross_call(armada_mpic_send_doorbell); } -void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) +static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) { struct device_node *node; struct resource res; diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c index 27fc4f049474..d71ef53107c4 100644 --- a/arch/arm/mach-mvebu/pmsu.c +++ b/arch/arm/mach-mvebu/pmsu.c @@ -22,6 +22,7 @@ #include #include #include +#include "pmsu.h" static void __iomem *pmsu_mp_base; static void __iomem *pmsu_reset_base; @@ -58,7 +59,7 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr) } #endif -int __init armada_370_xp_pmsu_init(void) +static int __init armada_370_xp_pmsu_init(void) { struct device_node *np; diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c index 5175083cdb34..a7fb89a5b5d9 100644 --- a/arch/arm/mach-mvebu/system-controller.c +++ b/arch/arm/mach-mvebu/system-controller.c @@ -27,6 +27,7 @@ #include #include #include +#include "common.h" static void __iomem *system_controller_base; @@ -39,14 +40,14 @@ struct mvebu_system_controller { }; static struct mvebu_system_controller *mvebu_sc; -const struct mvebu_system_controller armada_370_xp_system_controller = { +static const struct mvebu_system_controller armada_370_xp_system_controller = { .rstoutn_mask_offset = 0x60, .system_soft_reset_offset = 0x64, .rstoutn_mask_reset_out_en = 0x1, .system_soft_reset = 0x1, }; -const struct mvebu_system_controller orion_system_controller = { +static const struct mvebu_system_controller orion_system_controller = { .rstoutn_mask_offset = 0x108, .system_soft_reset_offset = 0x10c, .rstoutn_mask_reset_out_en = 0x4, diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index cce2c9dfb5d1..4a1065e41e9c 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -109,38 +109,6 @@ static void cpu8815_restart(enum reboot_mode mode, const char *cmd) writel(1, srcbase + 0x18); } -/* - * The SMSC911x IRQ is connected to a GPIO pin, but the driver expects - * to simply request an IRQ passed as a resource. So the GPIO pin needs - * to be requested by this hog and set as input. - */ -static int __init cpu8815_eth_init(void) -{ - struct device_node *eth; - int gpio, irq, err; - - eth = of_find_node_by_path("/usb-s8815/ethernet-gpio"); - if (!eth) { - pr_info("could not find any ethernet GPIO\n"); - return 0; - } - gpio = of_get_gpio(eth, 0); - err = gpio_request(gpio, "eth_irq"); - if (err) { - pr_info("failed to request ethernet GPIO\n"); - return -ENODEV; - } - err = gpio_direction_input(gpio); - if (err) { - pr_info("failed to set ethernet GPIO as input\n"); - return -ENODEV; - } - irq = gpio_to_irq(gpio); - pr_info("enabled USB-S8815 ethernet GPIO %d, IRQ %d\n", gpio, irq); - return 0; -} -device_initcall(cpu8815_eth_init); - /* * This GPIO pin turns on a line that is used to detect card insertion * on this board. diff --git a/arch/arm/mach-omap1/include/mach/usb.h b/arch/arm/mach-omap1/include/mach/usb.h index 45e5ac707cbb..2c263051dc51 100644 --- a/arch/arm/mach-omap1/include/mach/usb.h +++ b/arch/arm/mach-omap1/include/mach/usb.h @@ -8,43 +8,7 @@ #define is_usb0_device(config) 0 #endif -struct omap_usb_config { - /* Configure drivers according to the connectors on your board: - * - "A" connector (rectagular) - * ... for host/OHCI use, set "register_host". - * - "B" connector (squarish) or "Mini-B" - * ... for device/gadget use, set "register_dev". - * - "Mini-AB" connector (very similar to Mini-B) - * ... for OTG use as device OR host, initialize "otg" - */ - unsigned register_host:1; - unsigned register_dev:1; - u8 otg; /* port number, 1-based: usb1 == 2 */ - - u8 hmc_mode; - - /* implicitly true if otg: host supports remote wakeup? */ - u8 rwc; - - /* signaling pins used to talk to transceiver on usbN: - * 0 == usbN unused - * 2 == usb0-only, using internal transceiver - * 3 == 3 wire bidirectional - * 4 == 4 wire bidirectional - * 6 == 6 wire unidirectional (or TLL) - */ - u8 pins[3]; - - struct platform_device *udc_device; - struct platform_device *ohci_device; - struct platform_device *otg_device; - - u32 (*usb0_init)(unsigned nwires, unsigned is_device); - u32 (*usb1_init)(unsigned nwires); - u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup); - - int (*ocpi_enable)(void); -}; +#include void omap_otg_init(struct omap_usb_config *config); diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index 6b5f298d6638..a7588cfd0286 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -181,7 +181,7 @@ static __init void omap_init_mpu_timer(unsigned long rate) * --------------------------------------------------------------------------- */ -static u32 notrace omap_mpu_read_sched_clock(void) +static u64 notrace omap_mpu_read_sched_clock(void) { return ~omap_mpu_timer_read(1); } @@ -193,7 +193,7 @@ static void __init omap_init_clocksource(unsigned long rate) "%s: can't register clocksource!\n"; omap_mpu_timer_start(1, ~0, 1); - setup_sched_clock(omap_mpu_read_sched_clock, 32, rate); + sched_clock_register(omap_mpu_read_sched_clock, 32, rate); if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate, 300, 32, clocksource_mmio_readl_down)) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index dc21df166161..4191ae08f4c8 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -192,19 +192,6 @@ config MACH_OMAP2_TUSB6010 depends on ARCH_OMAP2 && SOC_OMAP2420 default y if MACH_NOKIA_N8X0 -config MACH_OMAP_H4 - bool "OMAP 2420 H4 board" - depends on SOC_OMAP2420 - default y - select OMAP_DEBUG_DEVICES - select OMAP_PACKAGE_ZAF - -config MACH_OMAP_2430SDP - bool "OMAP 2430 SDP board" - depends on SOC_OMAP2430 - default y - select OMAP_PACKAGE_ZAC - config MACH_OMAP3_BEAGLE bool "OMAP3 BEAGLE board" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index adcef406ff0a..f78b177e8f4f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -66,8 +66,6 @@ obj-$(CONFIG_SOC_OMAP5) += omap4-restart.o obj-$(CONFIG_SOC_DRA7XX) += omap4-restart.o # Pin multiplexing -obj-$(CONFIG_SOC_OMAP2420) += mux2420.o -obj-$(CONFIG_SOC_OMAP2430) += mux2430.o obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o # SMS/SDRC @@ -237,8 +235,6 @@ obj-$(CONFIG_SOC_OMAP2420) += msdi.o # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o pdata-quirks.o -obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o -obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c deleted file mode 100644 index c711ad6ac067..000000000000 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * linux/arch/arm/mach-omap2/board-2430sdp.c - * - * Copyright (C) 2006 Texas Instruments - * - * Modified from mach-omap2/board-generic.c - * - * Initial Code : Based on a patch from Komal Shah and Richard Woodruff - * Updated the Code for 2430 SDP : Syed Mohammed Khasim - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "common.h" -#include "gpmc.h" -#include "gpmc-smc91x.h" - -#include

.*) usecs", last) + if(mc and mr and (mc.group("t") == mr.group("t")) and (mc.group("f") == mr.group("f"))): + i = dmesglist.index(last) + j = dmesglist.index(line) + dmesglist[i] = line + dmesglist[j] = last + last = line + return dmesglist + +# Function: analyzeKernelLog +# Description: +# Analyse a dmesg log output file generated from this app during +# the execution phase. Create a set of device structures in memory +# for subsequent formatting in the html output file +def analyzeKernelLog(): + global sysvals, data + + print("PROCESSING DATA") + data.vprint("Analyzing the dmesg data...") + if(os.path.exists(sysvals.dmesgfile) == False): + print("ERROR: %s doesn't exist") % sysvals.dmesgfile + return False + + lf = sortKernelLog() + phase = "suspend_runtime" + + dm = { + 'suspend_general': r"PM: Syncing filesystems.*", + 'suspend_early': r"PM: suspend of devices complete after.*", + 'suspend_noirq': r"PM: late suspend of devices complete after.*", + 'suspend_cpu': r"PM: noirq suspend of devices complete after.*", + 'resume_cpu': r"ACPI: Low-level resume complete.*", + 'resume_noirq': r"ACPI: Waking up from system sleep state.*", + 'resume_early': r"PM: noirq resume of devices complete after.*", + 'resume_general': r"PM: early resume of devices complete after.*", + 'resume_complete': r".*Restarting tasks \.\.\..*", + } + if(sysvals.suspendmode == "standby"): + dm['resume_cpu'] = r"PM: Restoring platform NVS memory" + elif(sysvals.suspendmode == "disk"): + dm['suspend_early'] = r"PM: freeze of devices complete after.*" + dm['suspend_noirq'] = r"PM: late freeze of devices complete after.*" + dm['suspend_cpu'] = r"PM: noirq freeze of devices complete after.*" + dm['resume_cpu'] = r"PM: Restoring platform NVS memory" + dm['resume_early'] = r"PM: noirq restore of devices complete after.*" + dm['resume_general'] = r"PM: early restore of devices complete after.*" + + action_start = 0.0 + for line in lf: + # -- preprocessing -- + # parse each dmesg line into the time and message + m = re.match(r".*(\[ *)(?P[0-9\.]*)(\]) (?P.*)", line) + if(m): + ktime = float(m.group("ktime")) + msg = m.group("msg") + else: + print line + continue + + # -- phase changes -- + # suspend_general start + if(re.match(dm['suspend_general'], msg)): + phase = "suspend_general" + data.dmesg[phase]['start'] = ktime + data.start = ktime + # action start: syncing filesystems + action_start = ktime + # suspend_early start + elif(re.match(dm['suspend_early'], msg)): + data.dmesg["suspend_general"]['end'] = ktime + phase = "suspend_early" + data.dmesg[phase]['start'] = ktime + # suspend_noirq start + elif(re.match(dm['suspend_noirq'], msg)): + data.dmesg["suspend_early"]['end'] = ktime + phase = "suspend_noirq" + data.dmesg[phase]['start'] = ktime + # suspend_cpu start + elif(re.match(dm['suspend_cpu'], msg)): + data.dmesg["suspend_noirq"]['end'] = ktime + phase = "suspend_cpu" + data.dmesg[phase]['start'] = ktime + # resume_cpu start + elif(re.match(dm['resume_cpu'], msg)): + data.tSuspended = ktime + data.dmesg["suspend_cpu"]['end'] = ktime + phase = "resume_cpu" + data.dmesg[phase]['start'] = ktime + # resume_noirq start + elif(re.match(dm['resume_noirq'], msg)): + data.dmesg["resume_cpu"]['end'] = ktime + phase = "resume_noirq" + data.dmesg[phase]['start'] = ktime + # action end: ACPI resume + data.newAction("resume_cpu", "ACPI", -1, "", action_start, ktime) + # resume_early start + elif(re.match(dm['resume_early'], msg)): + data.dmesg["resume_noirq"]['end'] = ktime + phase = "resume_early" + data.dmesg[phase]['start'] = ktime + # resume_general start + elif(re.match(dm['resume_general'], msg)): + data.dmesg["resume_early"]['end'] = ktime + phase = "resume_general" + data.dmesg[phase]['start'] = ktime + # resume complete start + elif(re.match(dm['resume_complete'], msg)): + data.dmesg["resume_general"]['end'] = ktime + data.end = ktime + phase = "resume_runtime" + break + + # -- device callbacks -- + if(phase in data.phases): + # device init call + if(re.match(r"calling (?P.*)\+ @ .*, parent: .*", msg)): + sm = re.match(r"calling (?P.*)\+ @ (?P.*), parent: (?P\n" + output = '
\n' + + # set scale for timeline + tTotal = tMax - t0 + tS = 0.1 + if(tTotal <= 0): + return output + if(tTotal > 4): + tS = 1 + if(tSuspended < 0): + for i in range(int(tTotal/tS)+1): + pos = "%0.3f" % (100 - ((float(i)*tS*100)/tTotal)) + if(i > 0): + val = "%0.f" % (float(i)*tS*1000) + else: + val = "" + output += timescale.format(pos, val) + else: + tSuspend = tSuspended - t0 + divTotal = int(tTotal/tS) + 1 + divSuspend = int(tSuspend/tS) + s0 = (tSuspend - tS*divSuspend)*100/tTotal + for i in range(divTotal): + pos = "%0.3f" % (100 - ((float(i)*tS*100)/tTotal) - s0) + if((i == 0) and (s0 < 3)): + val = "" + elif(i == divSuspend): + val = "S/R" + else: + val = "%0.f" % (float(i-divSuspend)*tS*1000) + output += timescale.format(pos, val) + output += '
\n' + return output + +# Function: createHTML +# Description: +# Create the output html file. +def createHTML(): + global sysvals, data + + data.normalizeTime() + + # html function templates + headline_stamp = '
{0} {1} {2} {3}
\n' + html_zoombox = '
\n
\n' + html_timeline = '
\n' + html_device = '
{6}
\n' + html_phase = '
{5}
\n' + html_legend = '
 {2}
\n' + html_timetotal = '\n'\ + ''\ + ''\ + '\n
{2} Suspend Time: {0} ms{2} Resume Time: {1} ms
\n' + html_timegroups = '\n'\ + ''\ + ''\ + ''\ + ''\ + '\n
Kernel Suspend: {0} msFirmware Suspend: {1} msFirmware Resume: {2} msKernel Resume: {3} ms
\n' + + # device timeline (dmesg) + if(data.usedmesg): + data.vprint("Creating Device Timeline...") + devtl = Timeline() + + # Generate the header for this timeline + t0 = data.start + tMax = data.end + tTotal = tMax - t0 + if(tTotal == 0): + print("ERROR: No timeline data") + sys.exit() + suspend_time = "%.0f"%(-data.start*1000) + resume_time = "%.0f"%(data.end*1000) + if data.fwValid: + devtl.html['timeline'] = html_timetotal.format(suspend_time, resume_time, "Total") + sktime = "%.3f"%((data.dmesg['suspend_cpu']['end'] - data.dmesg['suspend_general']['start'])*1000) + sftime = "%.3f"%(data.fwSuspend / 1000000.0) + rftime = "%.3f"%(data.fwResume / 1000000.0) + rktime = "%.3f"%((data.dmesg['resume_general']['end'] - data.dmesg['resume_cpu']['start'])*1000) + devtl.html['timeline'] += html_timegroups.format(sktime, sftime, rftime, rktime) + else: + devtl.html['timeline'] = html_timetotal.format(suspend_time, resume_time, "Kernel") + + # determine the maximum number of rows we need to draw + timelinerows = 0 + for phase in data.dmesg: + list = data.dmesg[phase]['list'] + rows = setTimelineRows(list, list) + data.dmesg[phase]['row'] = rows + if(rows > timelinerows): + timelinerows = rows + + # calculate the timeline height and create its bounding box + devtl.setRows(timelinerows + 1) + devtl.html['timeline'] += html_zoombox; + devtl.html['timeline'] += html_timeline.format("dmesg", devtl.height); + + # draw the colored boxes for each of the phases + for b in data.dmesg: + phase = data.dmesg[b] + left = "%.3f" % (((phase['start']-data.start)*100)/tTotal) + width = "%.3f" % (((phase['end']-phase['start'])*100)/tTotal) + devtl.html['timeline'] += html_phase.format(left, width, "%.3f"%devtl.scaleH, "%.3f"%(100-devtl.scaleH), data.dmesg[b]['color'], "") + + # draw the time scale, try to make the number of labels readable + devtl.html['scale'] = createTimeScale(t0, tMax, data.tSuspended) + devtl.html['timeline'] += devtl.html['scale'] + for b in data.dmesg: + phaselist = data.dmesg[b]['list'] + for d in phaselist: + name = d + if(d in data.altdevname): + name = data.altdevname[d] + dev = phaselist[d] + height = (100.0 - devtl.scaleH)/data.dmesg[b]['row'] + top = "%.3f" % ((dev['row']*height) + devtl.scaleH) + left = "%.3f" % (((dev['start']-data.start)*100)/tTotal) + width = "%.3f" % (((dev['end']-dev['start'])*100)/tTotal) + len = " (%0.3f ms) " % ((dev['end']-dev['start'])*1000) + color = "rgba(204,204,204,0.5)" + devtl.html['timeline'] += html_device.format(dev['id'], name+len+b, left, top, "%.3f"%height, width, name) + + # timeline is finished + devtl.html['timeline'] += "
\n
\n" + + # draw a legend which describes the phases by color + devtl.html['legend'] = "
\n" + pdelta = 100.0/data.phases.__len__() + pmargin = pdelta / 4.0 + for phase in data.phases: + order = "%.2f" % ((data.dmesg[phase]['order'] * pdelta) + pmargin) + name = string.replace(phase, "_", "  ") + devtl.html['legend'] += html_legend.format(order, data.dmesg[phase]['color'], name) + devtl.html['legend'] += "
\n" + + hf = open(sysvals.htmlfile, 'w') + thread_height = 0 + + # write the html header first (html head, css code, everything up to the start of body) + html_header = "\n\n\n\ + \n\ + AnalyzeSuspend\n\ + \n\n\n" + hf.write(html_header) + + # write the test title and general info header + if(data.stamp['time'] != ""): + hf.write(headline_stamp.format(data.stamp['host'], + data.stamp['kernel'], data.stamp['mode'], data.stamp['time'])) + + # write the dmesg data (device timeline) + if(data.usedmesg): + hf.write(devtl.html['timeline']) + hf.write(devtl.html['legend']) + hf.write('
\n') + hf.write('
\n') + + # write the ftrace data (callgraph) + if(data.useftrace): + hf.write('
\n') + # write out the ftrace data converted to html + html_func_top = '
\n\n' + html_func_start = '
\n\n' + html_func_end = '
\n' + html_func_leaf = '
{0} {1}
\n' + num = 0 + for p in data.phases: + list = data.dmesg[p]['list'] + for devname in data.sortedDevices(p): + if('ftrace' not in list[devname]): + continue + name = devname + if(devname in data.altdevname): + name = data.altdevname[devname] + devid = list[devname]['id'] + cg = list[devname]['ftrace'] + flen = "(%.3f ms)" % ((cg.end - cg.start)*1000) + hf.write(html_func_top.format(devid, data.dmesg[p]['color'], num, name+" "+p, flen)) + num += 1 + for line in cg.list: + if(line.length < 0.000000001): + flen = "" + else: + flen = "(%.3f ms)" % (line.length*1000) + if(line.freturn and line.fcall): + hf.write(html_func_leaf.format(line.name, flen)) + elif(line.freturn): + hf.write(html_func_end) + else: + hf.write(html_func_start.format(num, line.name, flen)) + num += 1 + hf.write(html_func_end) + hf.write("\n\n
\n") + # write the footer and close + addScriptCode(hf) + hf.write("\n\n") + hf.close() + return True + +def addScriptCode(hf): + global data + + t0 = (data.start - data.tSuspended) * 1000 + tMax = (data.end - data.tSuspended) * 1000 + # create an array in javascript memory with the device details + detail = ' var bounds = [%f,%f];\n' % (t0, tMax) + detail += ' var d = [];\n' + dfmt = ' d["%s"] = { n:"%s", p:"%s", c:[%s] };\n'; + for p in data.dmesg: + list = data.dmesg[p]['list'] + for d in list: + parent = data.deviceParentID(d, p) + idlist = data.deviceChildrenIDs(d, p) + idstr = "" + for i in idlist: + if(idstr == ""): + idstr += '"'+i+'"' + else: + idstr += ', '+'"'+i+'"' + detail += dfmt % (list[d]['id'], d, parent, idstr) + + # add the code which will manipulate the data in the browser + script_code = \ + '\n' + hf.write(script_code); + +# Function: executeSuspend +# Description: +# Execute system suspend through the sysfs interface +def executeSuspend(): + global sysvals, data + + detectUSB() + pf = open(sysvals.powerfile, 'w') + # clear the kernel ring buffer just as we start + os.system("dmesg -C") + # start ftrace + if(data.useftrace): + print("START TRACING") + os.system("echo 1 > "+sysvals.tpath+"tracing_on") + os.system("echo SUSPEND START > "+sysvals.tpath+"trace_marker") + # initiate suspend + if(sysvals.rtcwake): + print("SUSPEND START") + os.system("rtcwake -s 10 -m "+sysvals.suspendmode) + else: + print("SUSPEND START (press a key to resume)") + pf.write(sysvals.suspendmode) + # execution will pause here + pf.close() + # return from suspend + print("RESUME COMPLETE") + # stop ftrace + if(data.useftrace): + os.system("echo RESUME COMPLETE > "+sysvals.tpath+"trace_marker") + os.system("echo 0 > "+sysvals.tpath+"tracing_on") + print("CAPTURING FTRACE") + os.system("echo \""+sysvals.teststamp+"\" > "+sysvals.ftracefile) + os.system("cat "+sysvals.tpath+"trace >> "+sysvals.ftracefile) + # grab a copy of the dmesg output + print("CAPTURING DMESG") + os.system("echo \""+sysvals.teststamp+"\" > "+sysvals.dmesgfile) + os.system("dmesg -c >> "+sysvals.dmesgfile) + +# Function: detectUSB +# Description: +# Detect all the USB hosts and devices currently connected +def detectUSB(): + global sysvals, data + + for dirname, dirnames, filenames in os.walk("/sys/devices"): + if(re.match(r".*/usb[0-9]*.*", dirname) and + "idVendor" in filenames and "idProduct" in filenames): + vid = os.popen("cat %s/idVendor 2>/dev/null" % dirname).read().replace('\n', '') + pid = os.popen("cat %s/idProduct 2>/dev/null" % dirname).read().replace('\n', '') + product = os.popen("cat %s/product 2>/dev/null" % dirname).read().replace('\n', '') + name = dirname.split('/')[-1] + if(len(product) > 0): + data.altdevname[name] = "%s [%s]" % (product, name) + else: + data.altdevname[name] = "%s:%s [%s]" % (vid, pid, name) + +def getModes(): + global sysvals + modes = "" + if(os.path.exists(sysvals.powerfile)): + fp = open(sysvals.powerfile, 'r') + modes = string.split(fp.read()) + fp.close() + return modes + +# Function: statusCheck +# Description: +# Verify that the requested command and options will work +def statusCheck(dryrun): + global sysvals, data + res = dict() + + if(data.notestrun): + print("SUCCESS: The command should run!") + return + + # check we have root access + check = "YES" + if(os.environ['USER'] != "root"): + if(not dryrun): + doError("root access is required", False) + check = "NO" + res[" have root access: "] = check + + # check sysfs is mounted + check = "YES" + if(not os.path.exists(sysvals.powerfile)): + if(not dryrun): + doError("sysfs must be mounted", False) + check = "NO" + res[" is sysfs mounted: "] = check + + # check target mode is a valid mode + check = "YES" + modes = getModes() + if(sysvals.suspendmode not in modes): + if(not dryrun): + doError("%s is not a value power mode" % sysvals.suspendmode, False) + check = "NO" + res[" is "+sysvals.suspendmode+" a power mode: "] = check + + # check if ftrace is available + if(data.useftrace): + check = "YES" + if(not verifyFtrace()): + if(not dryrun): + doError("ftrace is not configured", False) + check = "NO" + res[" is ftrace usable: "] = check + + # check if rtcwake + if(sysvals.rtcwake): + check = "YES" + version = os.popen("rtcwake -V 2>/dev/null").read() + if(not version.startswith("rtcwake")): + if(not dryrun): + doError("rtcwake is not installed", False) + check = "NO" + res[" is rtcwake usable: "] = check + + if(dryrun): + status = True + print("Checking if system can run the current command:") + for r in res: + print("%s\t%s" % (r, res[r])) + if(res[r] != "YES"): + status = False + if(status): + print("SUCCESS: The command should run!") + else: + print("FAILURE: The command won't run!") + +def printHelp(): + global sysvals + modes = getModes() + + print("") + print("AnalyzeSuspend") + print("Usage: sudo analyze_suspend.py ") + print("") + print("Description:") + print(" Initiates a system suspend/resume while capturing dmesg") + print(" and (optionally) ftrace data to analyze device timing") + print("") + print(" Generates output files in subdirectory: suspend-mmddyy-HHMMSS") + print(" HTML output: _.html") + print(" raw dmesg output: __dmesg.txt") + print(" raw ftrace output (with -f): __ftrace.txt") + print("") + print("Options:") + print(" [general]") + print(" -h Print this help text") + print(" -verbose Print extra information during execution and analysis") + print(" -status Test to see if the system is enabled to run this tool") + print(" -modes List available suspend modes") + print(" -m mode Mode to initiate for suspend %s (default: %s)") % (modes, sysvals.suspendmode) + print(" -rtcwake Use rtcwake to autoresume after 10 seconds (default: disabled)") + print(" -f Use ftrace to create device callgraphs (default: disabled)") + print(" [re-analyze data from previous runs]") + print(" -dmesg dmesgfile Create HTML timeline from dmesg file") + print(" -ftrace ftracefile Create HTML callgraph from ftrace file") + print("") + return True + +def doError(msg, help): + print("ERROR: %s") % msg + if(help == True): + printHelp() + sys.exit() + +# -- script main -- +# loop through the command line arguments +cmd = "" +args = iter(sys.argv[1:]) +for arg in args: + if(arg == "-m"): + try: + val = args.next() + except: + doError("No mode supplied", True) + sysvals.suspendmode = val + elif(arg == "-f"): + data.useftrace = True + elif(arg == "-modes"): + cmd = "modes" + elif(arg == "-status"): + cmd = "status" + elif(arg == "-verbose"): + data.verbose = True + elif(arg == "-rtcwake"): + sysvals.rtcwake = True + elif(arg == "-dmesg"): + try: + val = args.next() + except: + doError("No dmesg file supplied", True) + data.notestrun = True + data.usedmesg = True + sysvals.dmesgfile = val + elif(arg == "-ftrace"): + try: + val = args.next() + except: + doError("No ftrace file supplied", True) + data.notestrun = True + data.useftrace = True + sysvals.ftracefile = val + elif(arg == "-h"): + printHelp() + sys.exit() + else: + doError("Invalid argument: "+arg, True) + +# just run a utility command and exit +if(cmd != ""): + if(cmd == "status"): + statusCheck(True) + elif(cmd == "modes"): + modes = getModes() + print modes + sys.exit() + +data.initialize() + +# if instructed, re-analyze existing data files +if(data.notestrun): + sysvals.setOutputFile() + data.vprint("Output file: %s" % sysvals.htmlfile) + if(sysvals.dmesgfile != ""): + analyzeKernelLog() + if(sysvals.ftracefile != ""): + analyzeTraceLog() + createHTML() + sys.exit() + +# verify that we can run a test +data.usedmesg = True +statusCheck(False) + +# prepare for the test +if(data.useftrace): + initFtrace() +sysvals.initTestOutput() + +data.vprint("Output files:\n %s" % sysvals.dmesgfile) +if(data.useftrace): + data.vprint(" %s" % sysvals.ftracefile) +data.vprint(" %s" % sysvals.htmlfile) + +# execute the test +executeSuspend() +analyzeKernelLog() +if(data.useftrace): + analyzeTraceLog() +createHTML() diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 9c9810030377..1dbd6d1cd1b5 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -29,6 +29,7 @@ my $mailback = 0; my $summary_file = 0; my $show_types = 0; my $fix = 0; +my $fix_inplace = 0; my $root; my %debug; my %camelcase = (); @@ -76,6 +77,9 @@ Options: ".EXPERIMENTAL-checkpatch-fixes" with potential errors corrected to the preferred checkpatch style + --fix-inplace EXPERIMENTAL - may create horrible results + Is the same as --fix, but overwrites the input + file. It's your fault if there's no backup or git --ignore-perl-version override checking of perl version. expect runtime errors. -h, --help, --version display this help and exit @@ -131,6 +135,7 @@ GetOptions( 'mailback!' => \$mailback, 'summary-file!' => \$summary_file, 'fix!' => \$fix, + 'fix-inplace!' => \$fix_inplace, 'ignore-perl-version!' => \$ignore_perl_version, 'debug=s' => \%debug, 'test-only=s' => \$tst_only, @@ -140,6 +145,8 @@ GetOptions( help(0) if ($help); +$fix = 1 if ($fix_inplace); + my $exit = 0; if ($^V && $^V lt $minimum_perl_version) { @@ -1963,15 +1970,14 @@ sub process { } # Check for FSF mailing addresses. - if ($rawline =~ /You should have received a copy/ || - $rawline =~ /write to the Free Software/ || - $rawline =~ /59 Temple Place/ || - $rawline =~ /51 Franklin Street/) { + if ($rawline =~ /\bwrite to the Free/i || + $rawline =~ /\b59\s+Temple\s+Pl/i || + $rawline =~ /\b51\s+Franklin\s+St/i) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; my $msg_type = \&ERROR; $msg_type = \&CHK if ($file); &{$msg_type}("FSF_MAILING_ADDRESS", - "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) + "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) } # check for Kconfig help text having a real description @@ -2034,6 +2040,33 @@ sub process { "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); } +# check for DT compatible documentation + if (defined $root && $realfile =~ /\.dts/ && + $rawline =~ /^\+\s*compatible\s*=/) { + my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; + + foreach my $compat (@compats) { + my $compat2 = $compat; + my $dt_path = $root . "/Documentation/devicetree/bindings/"; + $compat2 =~ s/\,[a-z]*\-/\,<\.\*>\-/; + `grep -Erq "$compat|$compat2" $dt_path`; + if ( $? >> 8 ) { + WARN("UNDOCUMENTED_DT_STRING", + "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); + } + + my $vendor = $compat; + my $vendor_path = $dt_path . "vendor-prefixes.txt"; + next if (! -f $vendor_path); + $vendor =~ s/^([a-zA-Z0-9]+)\,.*/$1/; + `grep -Eq "$vendor" $vendor_path`; + if ( $? >> 8 ) { + WARN("UNDOCUMENTED_DT_STRING", + "DT compatible string vendor \"$vendor\" appears un-documented -- check $vendor_path\n" . $herecurr); + } + } + } + # check we are in a valid source file if not then ignore this hunk next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); @@ -2049,16 +2082,12 @@ sub process { } # Check for user-visible strings broken across lines, which breaks the ability -# to grep for the string. Limited to strings used as parameters (those -# following an open parenthesis), which almost completely eliminates false -# positives, as well as warning only once per parameter rather than once per -# line of the string. Make an exception when the previous string ends in a -# newline (multiple lines in one string constant) or \n\t (common in inline -# assembly to indent the instruction on the following line). +# to grep for the string. Make exceptions when the previous string ends in a +# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' +# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value if ($line =~ /^\+\s*"/ && $prevline =~ /"\s*$/ && - $prevline =~ /\(/ && - $prevrawline !~ /\\n(?:\\t)*"\s*$/) { + $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { WARN("SPLIT_STRING", "quoted string split across lines\n" . $hereprev); } @@ -2115,8 +2144,10 @@ sub process { if (WARN("SPACE_BEFORE_TAB", "please, no space before tabs\n" . $herevet) && $fix) { - $fixed[$linenr - 1] =~ - s/(^\+.*) +\t/$1\t/; + while ($fixed[$linenr - 1] =~ + s/(^\+.*) {8,8}+\t/$1\t\t/) {} + while ($fixed[$linenr - 1] =~ + s/(^\+.*) +\t/$1\t/) {} } } @@ -2634,10 +2665,13 @@ sub process { $herecurr); } -# check for declarations of struct pci_device_id - if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { - WARN("DEFINE_PCI_DEVICE_TABLE", - "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); +# check for uses of DEFINE_PCI_DEVICE_TABLE + if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) { + if (WARN("DEFINE_PCI_DEVICE_TABLE", + "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) && + $fix) { + $fixed[$linenr - 1] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /; + } } # check for new typedefs, only function parameters and sparse annotations @@ -2802,6 +2836,65 @@ sub process { } } +# Function pointer declarations +# check spacing between type, funcptr, and args +# canonical declaration is "type (*funcptr)(args...)" +# +# the $Declare variable will capture all spaces after the type +# so check it for trailing missing spaces or multiple spaces + if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)$Ident(\s*)\)(\s*)\(/) { + my $declare = $1; + my $pre_pointer_space = $2; + my $post_pointer_space = $3; + my $funcname = $4; + my $post_funcname_space = $5; + my $pre_args_space = $6; + + if ($declare !~ /\s$/) { + WARN("SPACING", + "missing space after return type\n" . $herecurr); + } + +# unnecessary space "type (*funcptr)(args...)" + elsif ($declare =~ /\s{2,}$/) { + WARN("SPACING", + "Multiple spaces after return type\n" . $herecurr); + } + +# unnecessary space "type ( *funcptr)(args...)" + if (defined $pre_pointer_space && + $pre_pointer_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space after function pointer open parenthesis\n" . $herecurr); + } + +# unnecessary space "type (* funcptr)(args...)" + if (defined $post_pointer_space && + $post_pointer_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space before function pointer name\n" . $herecurr); + } + +# unnecessary space "type (*funcptr )(args...)" + if (defined $post_funcname_space && + $post_funcname_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space after function pointer name\n" . $herecurr); + } + +# unnecessary space "type (*funcptr) (args...)" + if (defined $pre_args_space && + $pre_args_space =~ /^\s/) { + WARN("SPACING", + "Unnecessary space before function pointer arguments\n" . $herecurr); + } + + if (show_type("SPACING") && $fix) { + $fixed[$linenr - 1] =~ + s/^(.\s*$Declare)\(\s*\*\s*($Ident)\s*\)\s*\(/rtrim($1) . " " . "\(\*$2\)\("/ex; + } + } + # check for spacing round square brackets; allowed: # 1. with a type on the left -- int [] a; # 2. at the beginning of a line for slice initialisers -- [0...10] = 5, @@ -3122,7 +3215,7 @@ sub process { } # check for whitespace before a non-naked semicolon - if ($line =~ /^\+.*\S\s+;/) { + if ($line =~ /^\+.*\S\s+;\s*$/) { if (WARN("SPACING", "space prohibited before semicolon\n" . $herecurr) && $fix) { @@ -3246,6 +3339,20 @@ sub process { } } +# if statements using unnecessary parentheses - ie: if ((foo == bar)) + if ($^V && $^V ge 5.10.0 && + $line =~ /\bif\s*((?:\(\s*){2,})/) { + my $openparens = $1; + my $count = $openparens =~ tr@\(@\(@; + my $msg = ""; + if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { + my $comp = $4; #Not $1 because of $LvalOrFunc + $msg = " - maybe == should be = ?" if ($comp eq "=="); + WARN("UNNECESSARY_PARENTHESES", + "Unnecessary parentheses$msg\n" . $herecurr); + } + } + # Return of what appears to be an errno should normally be -'ve if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { my $name = $1; @@ -3980,6 +4087,16 @@ sub process { } } +# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) + if ($^V && $^V ge 5.10.0 && + $line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) { + if (WARN("PREFER_ETHER_ADDR_COPY", + "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) && + $fix) { + $fixed[$linenr - 1] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; + } + } + # typecasts on min/max could be min_t/max_t if ($^V && $^V ge 5.10.0 && defined $stat && @@ -4114,6 +4231,12 @@ sub process { "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); } +# check for GFP_NOWAIT use + if ($line =~ /\b__GFP_NOFAIL\b/) { + WARN("__GFP_NOFAIL", + "Use of __GFP_NOFAIL is deprecated, no new users should be added\n" . $herecurr); + } + # check for multiple semicolons if ($line =~ /;\s*;\s*$/) { if (WARN("ONE_SEMICOLON", @@ -4123,6 +4246,31 @@ sub process { } } +# check for case / default statements not preceeded by break/fallthrough/switch + if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { + my $has_break = 0; + my $has_statement = 0; + my $count = 0; + my $prevline = $linenr; + while ($prevline > 1 && $count < 3 && !$has_break) { + $prevline--; + my $rline = $rawlines[$prevline - 1]; + my $fline = $lines[$prevline - 1]; + last if ($fline =~ /^\@\@/); + next if ($fline =~ /^\-/); + next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/); + $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i); + next if ($fline =~ /^.[\s$;]*$/); + $has_statement = 1; + $count++; + $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/); + } + if (!$has_break && $has_statement) { + WARN("MISSING_BREAK", + "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr); + } + } + # check for switch/default statements without a break; if ($^V && $^V ge 5.10.0 && defined $stat && @@ -4358,7 +4506,8 @@ sub process { hash_show_words(\%ignore_type, "Ignored"); if ($clean == 0 && $fix && "@rawlines" ne "@fixed") { - my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes"; + my $newfile = $filename; + $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); my $linecount = 0; my $f; diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh index a2af2e88daf3..c9469d34ecc6 100644 --- a/scripts/gcc-goto.sh +++ b/scripts/gcc-goto.sh @@ -5,7 +5,7 @@ cat << "END" | $@ -x c - -c -o /dev/null >/dev/null 2>&1 && echo "y" int main(void) { -#ifdef __arm__ +#if defined(__arm__) || defined(__aarch64__) /* * Not related to asm goto, but used by jump label * and broken on some ARM GCC versions (see GCC Bug 48637). diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl index 5e4fb144a04f..9c3986f4140c 100755 --- a/scripts/get_maintainer.pl +++ b/scripts/get_maintainer.pl @@ -98,6 +98,7 @@ my %VCS_cmds_git = ( "available" => '(which("git") ne "") && (-d ".git")', "find_signers_cmd" => "git log --no-color --follow --since=\$email_git_since " . + '--numstat --no-merges ' . '--format="GitCommit: %H%n' . 'GitAuthor: %an <%ae>%n' . 'GitDate: %aD%n' . @@ -106,6 +107,7 @@ my %VCS_cmds_git = ( " -- \$file", "find_commit_signers_cmd" => "git log --no-color " . + '--numstat ' . '--format="GitCommit: %H%n' . 'GitAuthor: %an <%ae>%n' . 'GitDate: %aD%n' . @@ -114,6 +116,7 @@ my %VCS_cmds_git = ( " -1 \$commit", "find_commit_author_cmd" => "git log --no-color " . + '--numstat ' . '--format="GitCommit: %H%n' . 'GitAuthor: %an <%ae>%n' . 'GitDate: %aD%n' . @@ -125,6 +128,7 @@ my %VCS_cmds_git = ( "blame_commit_pattern" => "^([0-9a-f]+) ", "author_pattern" => "^GitAuthor: (.*)", "subject_pattern" => "^GitSubject: (.*)", + "stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$", ); my %VCS_cmds_hg = ( @@ -152,6 +156,7 @@ my %VCS_cmds_hg = ( "blame_commit_pattern" => "^([ 0-9a-f]+):", "author_pattern" => "^HgAuthor: (.*)", "subject_pattern" => "^HgSubject: (.*)", + "stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$", ); my $conf = which_conf(".get_maintainer.conf"); @@ -1269,20 +1274,30 @@ sub extract_formatted_signatures { } sub vcs_find_signers { - my ($cmd) = @_; + my ($cmd, $file) = @_; my $commits; my @lines = (); my @signatures = (); + my @authors = (); + my @stats = (); @lines = &{$VCS_cmds{"execute_cmd"}}($cmd); my $pattern = $VCS_cmds{"commit_pattern"}; + my $author_pattern = $VCS_cmds{"author_pattern"}; + my $stat_pattern = $VCS_cmds{"stat_pattern"}; + + $stat_pattern =~ s/(\$\w+)/$1/eeg; #interpolate $stat_pattern $commits = grep(/$pattern/, @lines); # of commits + @authors = grep(/$author_pattern/, @lines); @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines); + @stats = grep(/$stat_pattern/, @lines); - return (0, @signatures) if !@signatures; +# print("stats: <@stats>\n"); + + return (0, \@signatures, \@authors, \@stats) if !@signatures; save_commits_by_author(@lines) if ($interactive); save_commits_by_signer(@lines) if ($interactive); @@ -1291,9 +1306,10 @@ sub vcs_find_signers { @signatures = grep(!/${penguin_chiefs}/i, @signatures); } + my ($author_ref, $authors_ref) = extract_formatted_signatures(@authors); my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures); - return ($commits, @$signers_ref); + return ($commits, $signers_ref, $authors_ref, \@stats); } sub vcs_find_author { @@ -1849,7 +1865,12 @@ sub vcs_assign { sub vcs_file_signoffs { my ($file) = @_; + my $authors_ref; + my $signers_ref; + my $stats_ref; + my @authors = (); my @signers = (); + my @stats = (); my $commits; $vcs_used = vcs_exists(); @@ -1858,13 +1879,59 @@ sub vcs_file_signoffs { my $cmd = $VCS_cmds{"find_signers_cmd"}; $cmd =~ s/(\$\w+)/$1/eeg; # interpolate $cmd - ($commits, @signers) = vcs_find_signers($cmd); + ($commits, $signers_ref, $authors_ref, $stats_ref) = vcs_find_signers($cmd, $file); + + @signers = @{$signers_ref} if defined $signers_ref; + @authors = @{$authors_ref} if defined $authors_ref; + @stats = @{$stats_ref} if defined $stats_ref; + +# print("commits: <$commits>\nsigners:<@signers>\nauthors: <@authors>\nstats: <@stats>\n"); foreach my $signer (@signers) { $signer = deduplicate_email($signer); } vcs_assign("commit_signer", $commits, @signers); + vcs_assign("authored", $commits, @authors); + if ($#authors == $#stats) { + my $stat_pattern = $VCS_cmds{"stat_pattern"}; + $stat_pattern =~ s/(\$\w+)/$1/eeg; #interpolate $stat_pattern + + my $added = 0; + my $deleted = 0; + for (my $i = 0; $i <= $#stats; $i++) { + if ($stats[$i] =~ /$stat_pattern/) { + $added += $1; + $deleted += $2; + } + } + my @tmp_authors = uniq(@authors); + foreach my $author (@tmp_authors) { + $author = deduplicate_email($author); + } + @tmp_authors = uniq(@tmp_authors); + my @list_added = (); + my @list_deleted = (); + foreach my $author (@tmp_authors) { + my $auth_added = 0; + my $auth_deleted = 0; + for (my $i = 0; $i <= $#stats; $i++) { + if ($author eq deduplicate_email($authors[$i]) && + $stats[$i] =~ /$stat_pattern/) { + $auth_added += $1; + $auth_deleted += $2; + } + } + for (my $i = 0; $i < $auth_added; $i++) { + push(@list_added, $author); + } + for (my $i = 0; $i < $auth_deleted; $i++) { + push(@list_deleted, $author); + } + } + vcs_assign("added_lines", $added, @list_added); + vcs_assign("removed_lines", $deleted, @list_deleted); + } } sub vcs_file_blame { @@ -1887,6 +1954,10 @@ sub vcs_file_blame { if ($email_git_blame_signatures) { if (vcs_is_hg()) { my $commit_count; + my $commit_authors_ref; + my $commit_signers_ref; + my $stats_ref; + my @commit_authors = (); my @commit_signers = (); my $commit = join(" -r ", @commits); my $cmd; @@ -1894,19 +1965,27 @@ sub vcs_file_blame { $cmd = $VCS_cmds{"find_commit_signers_cmd"}; $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd - ($commit_count, @commit_signers) = vcs_find_signers($cmd); + ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, $file); + @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref; + @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref; push(@signers, @commit_signers); } else { foreach my $commit (@commits) { my $commit_count; + my $commit_authors_ref; + my $commit_signers_ref; + my $stats_ref; + my @commit_authors = (); my @commit_signers = (); my $cmd; $cmd = $VCS_cmds{"find_commit_signers_cmd"}; $cmd =~ s/(\$\w+)/$1/eeg; #substitute variables in $cmd - ($commit_count, @commit_signers) = vcs_find_signers($cmd); + ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, $file); + @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref; + @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref; push(@signers, @commit_signers); } diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 64ac2380e4d5..62320f93e903 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -65,7 +65,11 @@ sub check_include sub check_declarations { - if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { + # soundcard.h is what it is + if ($line =~ m/^void seqbuf_dump\(void\);/) { + return; + } + if ($line =~ m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { printf STDERR "$filename:$lineno: " . "userspace cannot reference function or " . "variable defined in the kernel\n"; diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 4606cdfb859d..31331723e810 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl @@ -219,6 +219,13 @@ sub read_kconfig { $depends{$config} = $1; } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { $depends{$config} .= " " . $1; + } elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { + my $dep = $3; + if ($dep !~ /^\s*(y|m|n)\s*$/) { + $dep =~ s/.*\sif\s+//; + $depends{$config} .= " " . $dep; + dprint "Added default depends $dep to $config\n"; + } # Get the configs that select this config } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 32b10f53d0b4..2dcb37736d84 100644 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -82,7 +82,9 @@ kallsyms() kallsymopt="${kallsymopt} --all-symbols" fi - kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET" + if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then + kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET" + fi local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" diff --git a/scripts/sortextable.c b/scripts/sortextable.c index 7941fbdfb050..cc49062acdee 100644 --- a/scripts/sortextable.c +++ b/scripts/sortextable.c @@ -39,6 +39,10 @@ #define EM_AARCH64 183 #endif +#ifndef EM_MICROBLAZE +#define EM_MICROBLAZE 189 +#endif + static int fd_map; /* File descriptor for file being modified. */ static int mmap_failed; /* Boolean flag. */ static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ @@ -275,6 +279,7 @@ do_file(char const *const fname) case EM_ARCOMPACT: case EM_ARM: case EM_AARCH64: + case EM_MICROBLAZE: case EM_MIPS: break; } /* end switch */ diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 7c2a0a71049e..d3b6d2cd3a06 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -274,10 +274,9 @@ static void set_majmin(char *str, unsigned m) sprintf(str, "%u", m); } -static int devcgroup_seq_read(struct cgroup_subsys_state *css, - struct cftype *cft, struct seq_file *m) +static int devcgroup_seq_show(struct seq_file *m, void *v) { - struct dev_cgroup *devcgroup = css_to_devcgroup(css); + struct dev_cgroup *devcgroup = css_to_devcgroup(seq_css(m)); struct dev_exception_item *ex; char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; @@ -679,7 +678,7 @@ static struct cftype dev_cgroup_files[] = { }, { .name = "list", - .read_seq_string = devcgroup_seq_read, + .seq_show = devcgroup_seq_show, .private = DEVCG_LIST, }, { } /* terminate */ diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index c38adcc910fb..1683bbf289a4 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c @@ -162,8 +162,7 @@ void ima_show_template_sig(struct seq_file *m, enum ima_show_type show, } static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, - struct ima_field_data *field_data, - bool size_limit) + struct ima_field_data *field_data) { /* * digest formats: @@ -176,11 +175,10 @@ static int ima_eventdigest_init_common(u8 *digest, u32 digestsize, u8 hash_algo, enum data_formats fmt = DATA_FMT_DIGEST; u32 offset = 0; - if (!size_limit) { + if (hash_algo < HASH_ALGO__LAST) { fmt = DATA_FMT_DIGEST_WITH_ALGO; - if (hash_algo < HASH_ALGO__LAST) - offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, - "%s", hash_algo_name[hash_algo]); + offset += snprintf(buffer, CRYPTO_MAX_ALG_NAME + 1, "%s", + hash_algo_name[hash_algo]); buffer[offset] = ':'; offset += 2; } @@ -243,8 +241,8 @@ int ima_eventdigest_init(struct integrity_iint_cache *iint, struct file *file, cur_digest = hash.hdr.digest; cur_digestsize = hash.hdr.length; out: - return ima_eventdigest_init_common(cur_digest, cur_digestsize, -1, - field_data, true); + return ima_eventdigest_init_common(cur_digest, cur_digestsize, + HASH_ALGO__LAST, field_data); } /* @@ -255,7 +253,7 @@ int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, struct evm_ima_xattr_data *xattr_value, int xattr_len, struct ima_field_data *field_data) { - u8 *cur_digest = NULL, hash_algo = HASH_ALGO__LAST; + u8 *cur_digest = NULL, hash_algo = HASH_ALGO_SHA1; u32 cur_digestsize = 0; /* If iint is NULL, we are recording a violation. */ @@ -268,7 +266,7 @@ int ima_eventdigest_ng_init(struct integrity_iint_cache *iint, hash_algo = iint->ima_hash->algo; out: return ima_eventdigest_init_common(cur_digest, cur_digestsize, - hash_algo, field_data, false); + hash_algo, field_data); } static int ima_eventname_init_common(struct integrity_iint_cache *iint, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 419491d8e7d2..4b34847208cc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -82,7 +82,6 @@ #include #include #include -#include #include #include @@ -234,6 +233,14 @@ static int inode_alloc_security(struct inode *inode) return 0; } +static void inode_free_rcu(struct rcu_head *head) +{ + struct inode_security_struct *isec; + + isec = container_of(head, struct inode_security_struct, rcu); + kmem_cache_free(sel_inode_cache, isec); +} + static void inode_free_security(struct inode *inode) { struct inode_security_struct *isec = inode->i_security; @@ -244,8 +251,16 @@ static void inode_free_security(struct inode *inode) list_del_init(&isec->list); spin_unlock(&sbsec->isec_lock); - inode->i_security = NULL; - kmem_cache_free(sel_inode_cache, isec); + /* + * The inode may still be referenced in a path walk and + * a call to selinux_inode_permission() can be made + * after inode_free_security() is called. Ideally, the VFS + * wouldn't do this, but fixing that is a much harder + * job. For now, simply free the i_security via RCU, and + * leave the current inode->i_security pointer intact. + * The inode will be freed after the RCU grace period too. + */ + call_rcu(&isec->rcu, inode_free_rcu); } static int file_alloc_security(struct file *file) @@ -4334,8 +4349,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) } err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, PEER__RECV, &ad); - if (err) + if (err) { selinux_netlbl_err(skb, err, 0); + return err; + } } if (secmark_active) { @@ -4472,14 +4489,10 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, { struct sk_security_struct *sksec = sk->sk_security; int err; - u16 family = sk->sk_family; + u16 family = req->rsk_ops->family; u32 connsid; u32 peersid; - /* handle mapped IPv4 packets arriving via IPv6 sockets */ - if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) - family = PF_INET; - err = selinux_skb_peerlbl_sid(skb, family, &peersid); if (err) return err; @@ -5586,11 +5599,11 @@ static int selinux_setprocattr(struct task_struct *p, /* Check for ptracing, and update the task SID if ok. Otherwise, leave SID unchanged and fail. */ ptsid = 0; - task_lock(p); + rcu_read_lock(); tracer = ptrace_parent(p); if (tracer) ptsid = task_sid(tracer); - task_unlock(p); + rcu_read_unlock(); if (tracer) { error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index b1dfe1049450..078e553f52f2 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -38,7 +38,10 @@ struct task_security_struct { struct inode_security_struct { struct inode *inode; /* back pointer to inode object */ - struct list_head list; /* list of inode_security_struct */ + union { + struct list_head list; /* list of inode_security_struct */ + struct rcu_head rcu; /* for freeing the inode_security_struct */ + }; u32 task_sid; /* SID of creating task */ u32 sid; /* SID of this object */ u16 sclass; /* security class of this object */ diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index fe341ae37004..8ed8daf7f1ee 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -33,13 +33,14 @@ #define POLICYDB_VERSION_ROLETRANS 26 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27 #define POLICYDB_VERSION_DEFAULT_TYPE 28 +#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #else -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_DEFAULT_TYPE +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_CONSTRAINT_NAMES #endif /* Mask for just the mount related flags */ diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 6235d052338b..0364120d1ec8 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -100,6 +100,32 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) return secattr; } +/** + * selinux_netlbl_sock_getattr - Get the cached NetLabel secattr + * @sk: the socket + * @sid: the SID + * + * Query the socket's cached secattr and if the SID matches the cached value + * return the cache, otherwise return NULL. + * + */ +static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( + const struct sock *sk, + u32 sid) +{ + struct sk_security_struct *sksec = sk->sk_security; + struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; + + if (secattr == NULL) + return NULL; + + if ((secattr->flags & NETLBL_SECATTR_SECID) && + (secattr->attr.secid == sid)) + return secattr; + + return NULL; +} + /** * selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache * @@ -224,7 +250,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, struct sk_security_struct *sksec = sk->sk_security; if (sksec->nlbl_state != NLBL_REQSKB) return 0; - secattr = sksec->nlbl_secattr; + secattr = selinux_netlbl_sock_getattr(sk, sid); } if (secattr == NULL) { secattr = &secattr_storage; @@ -410,6 +436,9 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, sksec->nlbl_state == NLBL_CONNLABELED)) { netlbl_secattr_init(&secattr); lock_sock(sk); + /* call the netlabel function directly as we want to see the + * on-the-wire label that is assigned via the socket's options + * and not the cached netlabel/lsm attributes */ rc = netlbl_sock_getattr(sk, &secattr); release_sock(sk); if (rc == 0) diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h index 149dda731fd3..96fd947c494b 100644 --- a/security/selinux/ss/constraint.h +++ b/security/selinux/ss/constraint.h @@ -48,6 +48,7 @@ struct constraint_expr { u32 op; /* operator */ struct ebitmap names; /* names */ + struct type_set *type_names; struct constraint_expr *next; /* next expression */ }; diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index f6195ebde3c9..c0f498842129 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -143,6 +143,11 @@ static struct policydb_compat_info policydb_compat[] = { .sym_num = SYM_NUM, .ocon_num = OCON_NUM, }, + { + .version = POLICYDB_VERSION_CONSTRAINT_NAMES, + .sym_num = SYM_NUM, + .ocon_num = OCON_NUM, + }, }; static struct policydb_compat_info *policydb_lookup_compat(int version) @@ -613,6 +618,19 @@ static int common_destroy(void *key, void *datum, void *p) return 0; } +static void constraint_expr_destroy(struct constraint_expr *expr) +{ + if (expr) { + ebitmap_destroy(&expr->names); + if (expr->type_names) { + ebitmap_destroy(&expr->type_names->types); + ebitmap_destroy(&expr->type_names->negset); + kfree(expr->type_names); + } + kfree(expr); + } +} + static int cls_destroy(void *key, void *datum, void *p) { struct class_datum *cladatum; @@ -628,10 +646,9 @@ static int cls_destroy(void *key, void *datum, void *p) while (constraint) { e = constraint->expr; while (e) { - ebitmap_destroy(&e->names); etmp = e; e = e->next; - kfree(etmp); + constraint_expr_destroy(etmp); } ctemp = constraint; constraint = constraint->next; @@ -642,16 +659,14 @@ static int cls_destroy(void *key, void *datum, void *p) while (constraint) { e = constraint->expr; while (e) { - ebitmap_destroy(&e->names); etmp = e; e = e->next; - kfree(etmp); + constraint_expr_destroy(etmp); } ctemp = constraint; constraint = constraint->next; kfree(ctemp); } - kfree(cladatum->comkey); } kfree(datum); @@ -1156,8 +1171,34 @@ bad: return rc; } -static int read_cons_helper(struct constraint_node **nodep, int ncons, - int allowxtarget, void *fp) +static void type_set_init(struct type_set *t) +{ + ebitmap_init(&t->types); + ebitmap_init(&t->negset); +} + +static int type_set_read(struct type_set *t, void *fp) +{ + __le32 buf[1]; + int rc; + + if (ebitmap_read(&t->types, fp)) + return -EINVAL; + if (ebitmap_read(&t->negset, fp)) + return -EINVAL; + + rc = next_entry(buf, fp, sizeof(u32)); + if (rc < 0) + return -EINVAL; + t->flags = le32_to_cpu(buf[0]); + + return 0; +} + + +static int read_cons_helper(struct policydb *p, + struct constraint_node **nodep, + int ncons, int allowxtarget, void *fp) { struct constraint_node *c, *lc; struct constraint_expr *e, *le; @@ -1225,6 +1266,18 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, rc = ebitmap_read(&e->names, fp); if (rc) return rc; + if (p->policyvers >= + POLICYDB_VERSION_CONSTRAINT_NAMES) { + e->type_names = kzalloc(sizeof + (*e->type_names), + GFP_KERNEL); + if (!e->type_names) + return -ENOMEM; + type_set_init(e->type_names); + rc = type_set_read(e->type_names, fp); + if (rc) + return rc; + } break; default: return -EINVAL; @@ -1301,7 +1354,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) goto bad; } - rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp); + rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp); if (rc) goto bad; @@ -1311,7 +1364,8 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) if (rc) goto bad; ncons = le32_to_cpu(buf[0]); - rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); + rc = read_cons_helper(p, &cladatum->validatetrans, + ncons, 1, fp); if (rc) goto bad; } @@ -1941,7 +1995,19 @@ static int filename_trans_read(struct policydb *p, void *fp) if (rc) goto out; - hashtab_insert(p->filename_trans, ft, otype); + rc = hashtab_insert(p->filename_trans, ft, otype); + if (rc) { + /* + * Do not return -EEXIST to the caller, or the system + * will not boot. + */ + if (rc != -EEXIST) + goto out; + /* But free memory to avoid memory leak. */ + kfree(ft); + kfree(name); + kfree(otype); + } } hash_eval(p->filename_trans, "filenametr"); return 0; @@ -2753,6 +2819,24 @@ static int common_write(void *vkey, void *datum, void *ptr) return 0; } +static int type_set_write(struct type_set *t, void *fp) +{ + int rc; + __le32 buf[1]; + + if (ebitmap_write(&t->types, fp)) + return -EINVAL; + if (ebitmap_write(&t->negset, fp)) + return -EINVAL; + + buf[0] = cpu_to_le32(t->flags); + rc = put_entry(buf, sizeof(u32), 1, fp); + if (rc) + return -EINVAL; + + return 0; +} + static int write_cons_helper(struct policydb *p, struct constraint_node *node, void *fp) { @@ -2784,6 +2868,12 @@ static int write_cons_helper(struct policydb *p, struct constraint_node *node, rc = ebitmap_write(&e->names, fp); if (rc) return rc; + if (p->policyvers >= + POLICYDB_VERSION_CONSTRAINT_NAMES) { + rc = type_set_write(e->type_names, fp); + if (rc) + return rc; + } break; default: break; diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index da637471d4ce..725d5945a97e 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -153,6 +153,17 @@ struct cond_bool_datum { struct cond_node; +/* + * type set preserves data needed to determine constraint info from + * policy source. This is not used by the kernel policy but allows + * utilities such as audit2allow to determine constraint denials. + */ +struct type_set { + struct ebitmap types; + struct ebitmap negset; + u32 flags; +}; + /* * The configuration data includes security contexts for * initial SIDs, unlabeled file systems, TCP and UDP port numbers, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index d106733ad987..c93c21127f0c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1831,7 +1831,7 @@ static int security_preserve_bools(struct policydb *p); */ int security_load_policy(void *data, size_t len) { - struct policydb oldpolicydb, newpolicydb; + struct policydb *oldpolicydb, *newpolicydb; struct sidtab oldsidtab, newsidtab; struct selinux_mapping *oldmap, *map = NULL; struct convert_context_args args; @@ -1840,12 +1840,19 @@ int security_load_policy(void *data, size_t len) int rc = 0; struct policy_file file = { data, len }, *fp = &file; + oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL); + if (!oldpolicydb) { + rc = -ENOMEM; + goto out; + } + newpolicydb = oldpolicydb + 1; + if (!ss_initialized) { avtab_cache_init(); rc = policydb_read(&policydb, fp); if (rc) { avtab_cache_destroy(); - return rc; + goto out; } policydb.len = len; @@ -1855,14 +1862,14 @@ int security_load_policy(void *data, size_t len) if (rc) { policydb_destroy(&policydb); avtab_cache_destroy(); - return rc; + goto out; } rc = policydb_load_isids(&policydb, &sidtab); if (rc) { policydb_destroy(&policydb); avtab_cache_destroy(); - return rc; + goto out; } security_load_policycaps(); @@ -1874,36 +1881,36 @@ int security_load_policy(void *data, size_t len) selinux_status_update_policyload(seqno); selinux_netlbl_cache_invalidate(); selinux_xfrm_notify_policyload(); - return 0; + goto out; } #if 0 sidtab_hash_eval(&sidtab, "sids"); #endif - rc = policydb_read(&newpolicydb, fp); + rc = policydb_read(newpolicydb, fp); if (rc) - return rc; + goto out; - newpolicydb.len = len; + newpolicydb->len = len; /* If switching between different policy types, log MLS status */ - if (policydb.mls_enabled && !newpolicydb.mls_enabled) + if (policydb.mls_enabled && !newpolicydb->mls_enabled) printk(KERN_INFO "SELinux: Disabling MLS support...\n"); - else if (!policydb.mls_enabled && newpolicydb.mls_enabled) + else if (!policydb.mls_enabled && newpolicydb->mls_enabled) printk(KERN_INFO "SELinux: Enabling MLS support...\n"); - rc = policydb_load_isids(&newpolicydb, &newsidtab); + rc = policydb_load_isids(newpolicydb, &newsidtab); if (rc) { printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); - policydb_destroy(&newpolicydb); - return rc; + policydb_destroy(newpolicydb); + goto out; } - rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size); + rc = selinux_set_mapping(newpolicydb, secclass_map, &map, &map_size); if (rc) goto err; - rc = security_preserve_bools(&newpolicydb); + rc = security_preserve_bools(newpolicydb); if (rc) { printk(KERN_ERR "SELinux: unable to preserve booleans\n"); goto err; @@ -1921,7 +1928,7 @@ int security_load_policy(void *data, size_t len) * in the new SID table. */ args.oldp = &policydb; - args.newp = &newpolicydb; + args.newp = newpolicydb; rc = sidtab_map(&newsidtab, convert_context, &args); if (rc) { printk(KERN_ERR "SELinux: unable to convert the internal" @@ -1931,12 +1938,12 @@ int security_load_policy(void *data, size_t len) } /* Save the old policydb and SID table to free later. */ - memcpy(&oldpolicydb, &policydb, sizeof policydb); + memcpy(oldpolicydb, &policydb, sizeof(policydb)); sidtab_set(&oldsidtab, &sidtab); /* Install the new policydb and SID table. */ write_lock_irq(&policy_rwlock); - memcpy(&policydb, &newpolicydb, sizeof policydb); + memcpy(&policydb, newpolicydb, sizeof(policydb)); sidtab_set(&sidtab, &newsidtab); security_load_policycaps(); oldmap = current_mapping; @@ -1946,7 +1953,7 @@ int security_load_policy(void *data, size_t len) write_unlock_irq(&policy_rwlock); /* Free the old policydb and SID table. */ - policydb_destroy(&oldpolicydb); + policydb_destroy(oldpolicydb); sidtab_destroy(&oldsidtab); kfree(oldmap); @@ -1956,14 +1963,17 @@ int security_load_policy(void *data, size_t len) selinux_netlbl_cache_invalidate(); selinux_xfrm_notify_policyload(); - return 0; + rc = 0; + goto out; err: kfree(map); sidtab_destroy(&newsidtab); - policydb_destroy(&newpolicydb); - return rc; + policydb_destroy(newpolicydb); +out: + kfree(oldpolicydb); + return rc; } size_t security_policydb_len(void) @@ -2938,25 +2948,21 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, struct selinux_audit_rule *rule = vrule; int match = 0; - if (!rule) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: missing rule\n"); + if (unlikely(!rule)) { + WARN_ONCE(1, "selinux_audit_rule_match: missing rule\n"); return -ENOENT; } read_lock(&policy_rwlock); if (rule->au_seqno < latest_granting) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: stale rule\n"); match = -ESTALE; goto out; } ctxt = sidtab_search(&sidtab, sid); - if (!ctxt) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "selinux_audit_rule_match: unrecognized SID %d\n", + if (unlikely(!ctxt)) { + WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", sid); match = -ENOENT; goto out; diff --git a/security/smack/smack.h b/security/smack/smack.h index 364cc64fce71..d072fd32212d 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -241,7 +241,8 @@ u32 smack_to_secid(const char *); extern int smack_cipso_direct; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; -extern char *smack_onlycap; +extern struct smack_known *smack_onlycap; +extern struct smack_known *smack_syslog_label; extern const char *smack_cipso_option; extern struct smack_known smack_known_floor; @@ -312,7 +313,7 @@ static inline int smack_privileged(int cap) if (!capable(cap)) return 0; - if (smack_onlycap == NULL || smack_onlycap == skp->smk_known) + if (smack_onlycap == NULL || smack_onlycap == skp) return 1; return 0; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index b0be893ad44d..14f52be78c75 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -219,8 +219,6 @@ static int smack_ptrace_traceme(struct task_struct *ptp) * smack_syslog - Smack approval on syslog * @type: message type * - * Require that the task has the floor label - * * Returns 0 on success, error code otherwise. */ static int smack_syslog(int typefrom_file) @@ -231,7 +229,7 @@ static int smack_syslog(int typefrom_file) if (smack_privileged(CAP_MAC_OVERRIDE)) return 0; - if (skp != &smack_known_floor) + if (smack_syslog_label != NULL && smack_syslog_label != skp) rc = -EACCES; return rc; @@ -341,10 +339,12 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) struct inode *inode = root->d_inode; struct superblock_smack *sp = sb->s_security; struct inode_smack *isp; + struct smack_known *skp; char *op; char *commap; char *nsp; int transmute = 0; + int specified = 0; if (sp->smk_initialized) return 0; @@ -359,34 +359,56 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { op += strlen(SMK_FSHAT); nsp = smk_import(op, 0); - if (nsp != NULL) + if (nsp != NULL) { sp->smk_hat = nsp; + specified = 1; + } } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { op += strlen(SMK_FSFLOOR); nsp = smk_import(op, 0); - if (nsp != NULL) + if (nsp != NULL) { sp->smk_floor = nsp; + specified = 1; + } } else if (strncmp(op, SMK_FSDEFAULT, strlen(SMK_FSDEFAULT)) == 0) { op += strlen(SMK_FSDEFAULT); nsp = smk_import(op, 0); - if (nsp != NULL) + if (nsp != NULL) { sp->smk_default = nsp; + specified = 1; + } } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { op += strlen(SMK_FSROOT); nsp = smk_import(op, 0); - if (nsp != NULL) + if (nsp != NULL) { sp->smk_root = nsp; + specified = 1; + } } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { op += strlen(SMK_FSTRANS); nsp = smk_import(op, 0); if (nsp != NULL) { sp->smk_root = nsp; transmute = 1; + specified = 1; } } } + if (!smack_privileged(CAP_MAC_ADMIN)) { + /* + * Unprivileged mounts don't get to specify Smack values. + */ + if (specified) + return -EPERM; + /* + * Unprivileged mounts get root and default from the caller. + */ + skp = smk_of_current(); + sp->smk_root = skp->smk_known; + sp->smk_default = skp->smk_known; + } /* * Initialize the root inode. */ @@ -423,53 +445,6 @@ static int smack_sb_statfs(struct dentry *dentry) return rc; } -/** - * smack_sb_mount - Smack check for mounting - * @dev_name: unused - * @path: mount point - * @type: unused - * @flags: unused - * @data: unused - * - * Returns 0 if current can write the floor of the filesystem - * being mounted on, an error code otherwise. - */ -static int smack_sb_mount(const char *dev_name, struct path *path, - const char *type, unsigned long flags, void *data) -{ - struct superblock_smack *sbp = path->dentry->d_sb->s_security; - struct smk_audit_info ad; - - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); - smk_ad_setfield_u_fs_path(&ad, *path); - - return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); -} - -/** - * smack_sb_umount - Smack check for unmounting - * @mnt: file system to unmount - * @flags: unused - * - * Returns 0 if current can write the floor of the filesystem - * being unmounted, an error code otherwise. - */ -static int smack_sb_umount(struct vfsmount *mnt, int flags) -{ - struct superblock_smack *sbp; - struct smk_audit_info ad; - struct path path; - - path.dentry = mnt->mnt_root; - path.mnt = mnt; - - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); - smk_ad_setfield_u_fs_path(&ad, path); - - sbp = path.dentry->d_sb->s_security; - return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); -} - /* * BPRM hooks */ @@ -837,31 +812,43 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct smk_audit_info ad; + struct smack_known *skp; + int check_priv = 0; + int check_import = 0; + int check_star = 0; int rc = 0; + /* + * Check label validity here so import won't fail in post_setxattr + */ if (strcmp(name, XATTR_NAME_SMACK) == 0 || strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || - strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 || - strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || - strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { - if (!smack_privileged(CAP_MAC_ADMIN)) - rc = -EPERM; - /* - * check label validity here so import wont fail on - * post_setxattr - */ - if (size == 0 || size >= SMK_LONGLABEL || - smk_import(value, size) == NULL) - rc = -EINVAL; + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + check_priv = 1; + check_import = 1; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || + strcmp(name, XATTR_NAME_SMACKMMAP) == 0) { + check_priv = 1; + check_import = 1; + check_star = 1; } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { - if (!smack_privileged(CAP_MAC_ADMIN)) - rc = -EPERM; + check_priv = 1; if (size != TRANS_TRUE_SIZE || strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) rc = -EINVAL; } else rc = cap_inode_setxattr(dentry, name, value, size, flags); + if (check_priv && !smack_privileged(CAP_MAC_ADMIN)) + rc = -EPERM; + + if (rc == 0 && check_import) { + skp = smk_import_entry(value, size); + if (skp == NULL || (check_star && + (skp == &smack_known_star || skp == &smack_known_web))) + rc = -EINVAL; + } + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); @@ -1364,7 +1351,7 @@ static int smack_file_receive(struct file *file) int may = 0; struct smk_audit_info ad; - smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); /* * This code relies on bitmasks. @@ -2847,8 +2834,17 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) if (rc >= 0) transflag = SMK_INODE_TRANSMUTE; } - isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); - isp->smk_mmap = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); + /* + * Don't let the exec or mmap label be "*" or "@". + */ + skp = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp); + if (skp == &smack_known_star || skp == &smack_known_web) + skp = NULL; + isp->smk_task = skp; + skp = smk_fetch(XATTR_NAME_SMACKMMAP, inode, dp); + if (skp == &smack_known_star || skp == &smack_known_web) + skp = NULL; + isp->smk_mmap = skp; dput(dp); break; @@ -3620,9 +3616,8 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule, struct smack_known *skp; char *rule = vrule; - if (!rule) { - audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, - "Smack: missing rule\n"); + if (unlikely(!rule)) { + WARN_ONCE(1, "Smack: missing rule\n"); return -ENOENT; } @@ -3743,8 +3738,6 @@ struct security_operations smack_ops = { .sb_copy_data = smack_sb_copy_data, .sb_kern_mount = smack_sb_kern_mount, .sb_statfs = smack_sb_statfs, - .sb_mount = smack_sb_mount, - .sb_umount = smack_sb_umount, .bprm_set_creds = smack_bprm_set_creds, .bprm_committing_creds = smack_bprm_committing_creds, diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 160aa08e3cd5..3198cfe1dcc6 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -52,6 +52,7 @@ enum smk_inos { SMK_CIPSO2 = 17, /* load long label -> CIPSO mapping */ SMK_REVOKE_SUBJ = 18, /* set rules with subject label to '-' */ SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */ + SMK_SYSLOG = 20, /* change syslog label) */ }; /* @@ -59,6 +60,7 @@ enum smk_inos { */ static DEFINE_MUTEX(smack_cipso_lock); static DEFINE_MUTEX(smack_ambient_lock); +static DEFINE_MUTEX(smack_syslog_lock); static DEFINE_MUTEX(smk_netlbladdr_lock); /* @@ -90,7 +92,13 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT; * everyone. It is expected that the hat (^) label * will be used if any label is used. */ -char *smack_onlycap; +struct smack_known *smack_onlycap; + +/* + * If this value is set restrict syslog use to the label specified. + * It can be reset via smackfs/syslog + */ +struct smack_known *smack_syslog_label; /* * Certain IP addresses may be designated as single label hosts. @@ -301,7 +309,8 @@ static int smk_perm_from_str(const char *string) * @import: if non-zero, import labels * @len: label length limit * - * Returns 0 on success, -1 on failure + * Returns 0 on success, -EINVAL on failure and -ENOENT when either subject + * or object is missing. */ static int smk_fill_rule(const char *subject, const char *object, const char *access1, const char *access2, @@ -314,28 +323,28 @@ static int smk_fill_rule(const char *subject, const char *object, if (import) { rule->smk_subject = smk_import_entry(subject, len); if (rule->smk_subject == NULL) - return -1; + return -EINVAL; rule->smk_object = smk_import(object, len); if (rule->smk_object == NULL) - return -1; + return -EINVAL; } else { cp = smk_parse_smack(subject, len); if (cp == NULL) - return -1; + return -EINVAL; skp = smk_find_entry(cp); kfree(cp); if (skp == NULL) - return -1; + return -ENOENT; rule->smk_subject = skp; cp = smk_parse_smack(object, len); if (cp == NULL) - return -1; + return -EINVAL; skp = smk_find_entry(cp); kfree(cp); if (skp == NULL) - return -1; + return -ENOENT; rule->smk_object = skp->smk_known; } @@ -381,6 +390,7 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, { ssize_t cnt = 0; char *tok[4]; + int rc; int i; /* @@ -405,10 +415,8 @@ static ssize_t smk_parse_long_rule(char *data, struct smack_parsed_rule *rule, while (i < 4) tok[i++] = NULL; - if (smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0)) - return -1; - - return cnt; + rc = smk_fill_rule(tok[0], tok[1], tok[2], tok[3], rule, import, 0); + return rc == 0 ? cnt : rc; } #define SMK_FIXED24_FMT 0 /* Fixed 24byte label format */ @@ -1603,7 +1611,7 @@ static const struct file_operations smk_ambient_ops = { }; /** - * smk_read_onlycap - read() for /smack/onlycap + * smk_read_onlycap - read() for smackfs/onlycap * @filp: file pointer, not actually used * @buf: where to put the result * @cn: maximum to send along @@ -1622,7 +1630,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, return 0; if (smack_onlycap != NULL) - smack = smack_onlycap; + smack = smack_onlycap->smk_known; asize = strlen(smack) + 1; @@ -1633,7 +1641,7 @@ static ssize_t smk_read_onlycap(struct file *filp, char __user *buf, } /** - * smk_write_onlycap - write() for /smack/onlycap + * smk_write_onlycap - write() for smackfs/onlycap * @file: file pointer, not actually used * @buf: where to get the data from * @count: bytes sent @@ -1656,7 +1664,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, * explicitly for clarity. The smk_access() implementation * would use smk_access(smack_onlycap, MAY_WRITE) */ - if (smack_onlycap != NULL && smack_onlycap != skp->smk_known) + if (smack_onlycap != NULL && smack_onlycap != skp) return -EPERM; data = kzalloc(count, GFP_KERNEL); @@ -1676,7 +1684,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, if (copy_from_user(data, buf, count) != 0) rc = -EFAULT; else - smack_onlycap = smk_import(data, count); + smack_onlycap = smk_import_entry(data, count); kfree(data); return rc; @@ -1856,11 +1864,12 @@ static ssize_t smk_user_access(struct file *file, const char __user *buf, res = smk_parse_long_rule(data, &rule, 0, 3); } - if (res < 0) + if (res >= 0) + res = smk_access(rule.smk_subject, rule.smk_object, + rule.smk_access1, NULL); + else if (res != -ENOENT) return -EINVAL; - res = smk_access(rule.smk_subject, rule.smk_object, - rule.smk_access1, NULL); data[0] = res == 0 ? '1' : '0'; data[1] = '\0'; @@ -2143,7 +2152,7 @@ static ssize_t smk_write_change_rule(struct file *file, const char __user *buf, /* * Must have privilege. */ - if (!capable(CAP_MAC_ADMIN)) + if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; return smk_write_rules_list(file, buf, count, ppos, NULL, NULL, @@ -2158,12 +2167,89 @@ static const struct file_operations smk_change_rule_ops = { }; /** - * smk_fill_super - fill the /smackfs superblock + * smk_read_syslog - read() for smackfs/syslog + * @filp: file pointer, not actually used + * @buf: where to put the result + * @cn: maximum to send along + * @ppos: where to start + * + * Returns number of bytes read or error code, as appropriate + */ +static ssize_t smk_read_syslog(struct file *filp, char __user *buf, + size_t cn, loff_t *ppos) +{ + struct smack_known *skp; + ssize_t rc = -EINVAL; + int asize; + + if (*ppos != 0) + return 0; + + if (smack_syslog_label == NULL) + skp = &smack_known_star; + else + skp = smack_syslog_label; + + asize = strlen(skp->smk_known) + 1; + + if (cn >= asize) + rc = simple_read_from_buffer(buf, cn, ppos, skp->smk_known, + asize); + + return rc; +} + +/** + * smk_write_syslog - write() for smackfs/syslog + * @file: file pointer, not actually used + * @buf: where to get the data from + * @count: bytes sent + * @ppos: where to start + * + * Returns number of bytes written or error code, as appropriate + */ +static ssize_t smk_write_syslog(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + char *data; + struct smack_known *skp; + int rc = count; + + if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + + data = kzalloc(count, GFP_KERNEL); + if (data == NULL) + return -ENOMEM; + + if (copy_from_user(data, buf, count) != 0) + rc = -EFAULT; + else { + skp = smk_import_entry(data, count); + if (skp == NULL) + rc = -EINVAL; + else + smack_syslog_label = smk_import_entry(data, count); + } + + kfree(data); + return rc; +} + +static const struct file_operations smk_syslog_ops = { + .read = smk_read_syslog, + .write = smk_write_syslog, + .llseek = default_llseek, +}; + + +/** + * smk_fill_super - fill the smackfs superblock * @sb: the empty superblock * @data: unused * @silent: unused * - * Fill in the well known entries for /smack + * Fill in the well known entries for the smack filesystem * * Returns 0 on success, an error code on failure */ @@ -2208,6 +2294,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) S_IRUGO|S_IWUSR}, [SMK_CHANGE_RULE] = { "change-rule", &smk_change_rule_ops, S_IRUGO|S_IWUSR}, + [SMK_SYSLOG] = { + "syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR}, /* last one */ {""} }; diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 1ca8dc2ccb89..c421fdb3c7a1 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -753,7 +753,7 @@ static struct snd_pcm_ops aaci_capture_ops = { * Power Management. */ #ifdef CONFIG_PM -static int aaci_do_suspend(struct snd_card *card, unsigned int state) +static int aaci_do_suspend(struct snd_card *card) { struct aaci *aaci = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3cold); @@ -761,28 +761,28 @@ static int aaci_do_suspend(struct snd_card *card, unsigned int state) return 0; } -static int aaci_do_resume(struct snd_card *card, unsigned int state) +static int aaci_do_resume(struct snd_card *card) { snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } -static int aaci_suspend(struct amba_device *dev, pm_message_t state) +static int aaci_suspend(struct device *dev) { - struct snd_card *card = amba_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); return card ? aaci_do_suspend(card) : 0; } -static int aaci_resume(struct amba_device *dev) +static int aaci_resume(struct device *dev) { - struct snd_card *card = amba_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); return card ? aaci_do_resume(card) : 0; } + +static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume); +#define AACI_DEV_PM_OPS (&aaci_dev_pm_ops) #else -#define aaci_do_suspend NULL -#define aaci_do_resume NULL -#define aaci_suspend NULL -#define aaci_resume NULL +#define AACI_DEV_PM_OPS NULL #endif @@ -1100,11 +1100,10 @@ MODULE_DEVICE_TABLE(amba, aaci_ids); static struct amba_driver aaci_driver = { .drv = { .name = DRIVER_NAME, + .pm = AACI_DEV_PM_OPS, }, .probe = aaci_probe, .remove = aaci_remove, - .suspend = aaci_suspend, - .resume = aaci_resume, .id_table = aaci_ids, }; diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c index 721d8fd45685..3519518e25a0 100644 --- a/sound/atmel/abdac.c +++ b/sound/atmel/abdac.c @@ -354,7 +354,7 @@ static int set_sample_rates(struct atmel_abdac *dac) /* we start at 192 kHz and work our way down to 5112 Hz */ while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) { new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate); - if (new_rate < 0) + if (new_rate <= 0) break; /* make sure we are below the ABDAC clock */ if (index < MAX_NUM_RATES && diff --git a/sound/core/Makefile b/sound/core/Makefile index 5e890cfed423..394a38909f6b 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -10,14 +10,12 @@ snd-$(CONFIG_SND_VMASTER) += vmaster.o snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o snd-$(CONFIG_SND_JACK) += jack.o -snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ - pcm_memory.o +snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ + pcm_memory.o memalloc.o +snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o snd-pcm-dmaengine-objs := pcm_dmaengine.o -snd-page-alloc-y := memalloc.o -snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o - snd-rawmidi-objs := rawmidi.o snd-timer-objs := timer.o snd-hrtimer-objs := hrtimer.o @@ -31,7 +29,7 @@ obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o obj-$(CONFIG_SND_TIMER) += snd-timer.o obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o -obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o +obj-$(CONFIG_SND_PCM) += snd-pcm.o obj-$(CONFIG_SND_DMAENGINE_PCM) += snd-pcm-dmaengine.o obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 9d518ac73eea..7a20897d33db 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -501,9 +501,6 @@ static int snd_compress_check_input(struct snd_compr_params *params) if (params->codec.ch_in == 0 || params->codec.ch_out == 0) return -EINVAL; - if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000)) - return -EINVAL; - return 0; } diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 5e1c7bc73b29..4595f93d151e 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -21,60 +21,18 @@ * */ -#include -#include -#include -#include #include #include -#include -#include #include #include -#include -#include #include - -MODULE_AUTHOR("Takashi Iwai , Jaroslav Kysela "); -MODULE_DESCRIPTION("Memory allocator for ALSA system."); -MODULE_LICENSE("GPL"); - - -/* - */ - -static DEFINE_MUTEX(list_mutex); -static LIST_HEAD(mem_list_head); - -/* buffer preservation list */ -struct snd_mem_list { - struct snd_dma_buffer buffer; - unsigned int id; - struct list_head list; -}; - -/* id for pre-allocated buffers */ -#define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1 - /* * * Generic memory allocators * */ -static long snd_allocated_pages; /* holding the number of allocated pages */ - -static inline void inc_snd_pages(int order) -{ - snd_allocated_pages += 1 << order; -} - -static inline void dec_snd_pages(int order) -{ - snd_allocated_pages -= 1 << order; -} - /** * snd_malloc_pages - allocate pages with the given size * @size: the size to allocate in bytes @@ -87,7 +45,6 @@ static inline void dec_snd_pages(int order) void *snd_malloc_pages(size_t size, gfp_t gfp_flags) { int pg; - void *res; if (WARN_ON(!size)) return NULL; @@ -95,9 +52,7 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags) return NULL; gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ pg = get_order(size); - if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) - inc_snd_pages(pg); - return res; + return (void *) __get_free_pages(gfp_flags, pg); } /** @@ -114,7 +69,6 @@ void snd_free_pages(void *ptr, size_t size) if (ptr == NULL) return; pg = get_order(size); - dec_snd_pages(pg); free_pages((unsigned long) ptr, pg); } @@ -129,7 +83,6 @@ void snd_free_pages(void *ptr, size_t size) static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *dma) { int pg; - void *res; gfp_t gfp_flags; if (WARN_ON(!dma)) @@ -139,11 +92,7 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d | __GFP_COMP /* compound page lets parts be mapped */ | __GFP_NORETRY /* don't trigger OOM-killer */ | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ - res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); - if (res != NULL) - inc_snd_pages(pg); - - return res; + return dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); } /* free the coherent DMA pages */ @@ -155,7 +104,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, if (ptr == NULL) return; pg = get_order(size); - dec_snd_pages(pg); dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma); } @@ -340,256 +288,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) } } - -/** - * snd_dma_get_reserved - get the reserved buffer for the given device - * @dmab: the buffer allocation record to store - * @id: the buffer id - * - * Looks for the reserved-buffer list and re-uses if the same buffer - * is found in the list. When the buffer is found, it's removed from the free list. - * - * Return: The size of buffer if the buffer is found, or zero if not found. - */ -size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) -{ - struct snd_mem_list *mem; - - if (WARN_ON(!dmab)) - return 0; - - mutex_lock(&list_mutex); - list_for_each_entry(mem, &mem_list_head, list) { - if (mem->id == id && - (mem->buffer.dev.dev == NULL || dmab->dev.dev == NULL || - ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev)))) { - struct device *dev = dmab->dev.dev; - list_del(&mem->list); - *dmab = mem->buffer; - if (dmab->dev.dev == NULL) - dmab->dev.dev = dev; - kfree(mem); - mutex_unlock(&list_mutex); - return dmab->bytes; - } - } - mutex_unlock(&list_mutex); - return 0; -} - -/** - * snd_dma_reserve_buf - reserve the buffer - * @dmab: the buffer to reserve - * @id: the buffer id - * - * Reserves the given buffer as a reserved buffer. - * - * Return: Zero if successful, or a negative code on error. - */ -int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) -{ - struct snd_mem_list *mem; - - if (WARN_ON(!dmab)) - return -EINVAL; - mem = kmalloc(sizeof(*mem), GFP_KERNEL); - if (! mem) - return -ENOMEM; - mutex_lock(&list_mutex); - mem->buffer = *dmab; - mem->id = id; - list_add_tail(&mem->list, &mem_list_head); - mutex_unlock(&list_mutex); - return 0; -} - -/* - * purge all reserved buffers - */ -static void free_all_reserved_pages(void) -{ - struct list_head *p; - struct snd_mem_list *mem; - - mutex_lock(&list_mutex); - while (! list_empty(&mem_list_head)) { - p = mem_list_head.next; - mem = list_entry(p, struct snd_mem_list, list); - list_del(p); - snd_dma_free_pages(&mem->buffer); - kfree(mem); - } - mutex_unlock(&list_mutex); -} - - -#ifdef CONFIG_PROC_FS -/* - * proc file interface - */ -#define SND_MEM_PROC_FILE "driver/snd-page-alloc" -static struct proc_dir_entry *snd_mem_proc; - -static int snd_mem_proc_read(struct seq_file *seq, void *offset) -{ - long pages = snd_allocated_pages >> (PAGE_SHIFT-12); - struct snd_mem_list *mem; - int devno; - static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" }; - - mutex_lock(&list_mutex); - seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n", - pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); - devno = 0; - list_for_each_entry(mem, &mem_list_head, list) { - devno++; - seq_printf(seq, "buffer %d : ID %08x : type %s\n", - devno, mem->id, types[mem->buffer.dev.type]); - seq_printf(seq, " addr = 0x%lx, size = %d bytes\n", - (unsigned long)mem->buffer.addr, - (int)mem->buffer.bytes); - } - mutex_unlock(&list_mutex); - return 0; -} - -static int snd_mem_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, snd_mem_proc_read, NULL); -} - -/* FIXME: for pci only - other bus? */ -#ifdef CONFIG_PCI -#define gettoken(bufp) strsep(bufp, " \t\n") - -static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer, - size_t count, loff_t * ppos) -{ - char buf[128]; - char *token, *p; - - if (count > sizeof(buf) - 1) - return -EINVAL; - if (copy_from_user(buf, buffer, count)) - return -EFAULT; - buf[count] = '\0'; - - p = buf; - token = gettoken(&p); - if (! token || *token == '#') - return count; - if (strcmp(token, "add") == 0) { - char *endp; - int vendor, device, size, buffers; - long mask; - int i, alloced; - struct pci_dev *pci; - - if ((token = gettoken(&p)) == NULL || - (vendor = simple_strtol(token, NULL, 0)) <= 0 || - (token = gettoken(&p)) == NULL || - (device = simple_strtol(token, NULL, 0)) <= 0 || - (token = gettoken(&p)) == NULL || - (mask = simple_strtol(token, NULL, 0)) < 0 || - (token = gettoken(&p)) == NULL || - (size = memparse(token, &endp)) < 64*1024 || - size > 16*1024*1024 /* too big */ || - (token = gettoken(&p)) == NULL || - (buffers = simple_strtol(token, NULL, 0)) <= 0 || - buffers > 4) { - printk(KERN_ERR "snd-page-alloc: invalid proc write format\n"); - return count; - } - vendor &= 0xffff; - device &= 0xffff; - - alloced = 0; - pci = NULL; - while ((pci = pci_get_device(vendor, device, pci)) != NULL) { - if (mask > 0 && mask < 0xffffffff) { - if (pci_set_dma_mask(pci, mask) < 0 || - pci_set_consistent_dma_mask(pci, mask) < 0) { - printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device); - pci_dev_put(pci); - return count; - } - } - for (i = 0; i < buffers; i++) { - struct snd_dma_buffer dmab; - memset(&dmab, 0, sizeof(dmab)); - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), - size, &dmab) < 0) { - printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size); - pci_dev_put(pci); - return count; - } - snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci)); - } - alloced++; - } - if (! alloced) { - for (i = 0; i < buffers; i++) { - struct snd_dma_buffer dmab; - memset(&dmab, 0, sizeof(dmab)); - /* FIXME: We can allocate only in ZONE_DMA - * without a device pointer! - */ - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, NULL, - size, &dmab) < 0) { - printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size); - break; - } - snd_dma_reserve_buf(&dmab, (unsigned int)((vendor << 16) | device)); - } - } - } else if (strcmp(token, "erase") == 0) - /* FIXME: need for releasing each buffer chunk? */ - free_all_reserved_pages(); - else - printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n"); - return count; -} -#endif /* CONFIG_PCI */ - -static const struct file_operations snd_mem_proc_fops = { - .owner = THIS_MODULE, - .open = snd_mem_proc_open, - .read = seq_read, -#ifdef CONFIG_PCI - .write = snd_mem_proc_write, -#endif - .llseek = seq_lseek, - .release = single_release, -}; - -#endif /* CONFIG_PROC_FS */ - -/* - * module entry - */ - -static int __init snd_mem_init(void) -{ -#ifdef CONFIG_PROC_FS - snd_mem_proc = proc_create(SND_MEM_PROC_FILE, 0644, NULL, - &snd_mem_proc_fops); -#endif - return 0; -} - -static void __exit snd_mem_exit(void) -{ - remove_proc_entry(SND_MEM_PROC_FILE, NULL); - free_all_reserved_pages(); - if (snd_allocated_pages > 0) - printk(KERN_ERR "snd-malloc: Memory leak? pages not freed = %li\n", snd_allocated_pages); -} - - -module_init(snd_mem_init) -module_exit(snd_mem_exit) - - /* * exports */ @@ -597,8 +295,5 @@ EXPORT_SYMBOL(snd_dma_alloc_pages); EXPORT_SYMBOL(snd_dma_alloc_pages_fallback); EXPORT_SYMBOL(snd_dma_free_pages); -EXPORT_SYMBOL(snd_dma_get_reserved_buf); -EXPORT_SYMBOL(snd_dma_reserve_buf); - EXPORT_SYMBOL(snd_malloc_pages); EXPORT_SYMBOL(snd_free_pages); diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 0af622c34e19..54debc07f5cb 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -51,17 +51,9 @@ static const size_t snd_minimum_buffer = 16384; static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size) { struct snd_dma_buffer *dmab = &substream->dma_buffer; + size_t orig_size = size; int err; - /* already reserved? */ - if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { - if (dmab->bytes >= size) - return 0; /* yes */ - /* no, free the reserved block */ - snd_dma_free_pages(dmab); - dmab->bytes = 0; - } - do { if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev, size, dmab)) < 0) { @@ -72,6 +64,10 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz size >>= 1; } while (size >= snd_minimum_buffer); dmab->bytes = 0; /* tell error */ + pr_warn("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n", + substream->pcm->card->number, substream->pcm->device, + substream->stream ? 'c' : 'p', substream->number, + substream->pcm->name, orig_size); return 0; } @@ -82,10 +78,7 @@ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream { if (substream->dma_buffer.area == NULL) return; - if (substream->dma_buf_id) - snd_dma_reserve_buf(&substream->dma_buffer, substream->dma_buf_id); - else - snd_dma_free_pages(&substream->dma_buffer); + snd_dma_free_pages(&substream->dma_buffer); substream->dma_buffer.area = NULL; } @@ -260,11 +253,6 @@ static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream, * * Do pre-allocation for the given DMA buffer type. * - * When substream->dma_buf_id is set, the function tries to look for - * the reserved buffer, and the buffer is not freed but reserved at - * destruction time. The dma_buf_id must be unique for all systems - * (in the same DMA buffer type) e.g. using snd_dma_pci_buf_id(). - * * Return: Zero if successful, or a negative error code on failure. */ int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream, diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 43f24cce3dec..4560ca0e5651 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -514,3 +514,42 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) return 0; } EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); + +static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates) +{ + if (rates & SNDRV_PCM_RATE_CONTINUOUS) + return SNDRV_PCM_RATE_CONTINUOUS; + else if (rates & SNDRV_PCM_RATE_KNOT) + return SNDRV_PCM_RATE_KNOT; + return rates; +} + +/** + * snd_pcm_rate_mask_intersect - computes the intersection between two rate masks + * @rates_a: The first rate mask + * @rates_b: The second rate mask + * + * This function computes the rates that are supported by both rate masks passed + * to the function. It will take care of the special handling of + * SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT. + * + * Return: A rate mask containing the rates that are supported by both rates_a + * and rates_b. + */ +unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, + unsigned int rates_b) +{ + rates_a = snd_pcm_rate_mask_sanitize(rates_a); + rates_b = snd_pcm_rate_mask_sanitize(rates_b); + + if (rates_a & SNDRV_PCM_RATE_CONTINUOUS) + return rates_b; + else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS) + return rates_a; + else if (rates_a & SNDRV_PCM_RATE_KNOT) + return rates_b; + else if (rates_b & SNDRV_PCM_RATE_KNOT) + return rates_a; + return rates_a & rates_b; +} +EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect); diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c index 461d94cfecbe..e3f29132d3ac 100644 --- a/sound/oss/dmabuf.c +++ b/sound/oss/dmabuf.c @@ -28,6 +28,7 @@ #include #include #include "sound_config.h" +#include "sleep.h" #define DMAP_FREE_ON_CLOSE 0 #define DMAP_KEEP_ON_CLOSE 1 @@ -351,8 +352,7 @@ static void dma_reset_output(int dev) if (!signal_pending(current) && adev->dmap_out->qlen && adev->dmap_out->underrun_count == 0){ spin_unlock_irqrestore(&dmap->lock,flags); - interruptible_sleep_on_timeout(&adev->out_sleeper, - dmabuf_timeout(dmap)); + oss_broken_sleep_on(&adev->out_sleeper, dmabuf_timeout(dmap)); spin_lock_irqsave(&dmap->lock,flags); } adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE); @@ -446,7 +446,7 @@ int DMAbuf_sync(int dev) long t = dmabuf_timeout(dmap); spin_unlock_irqrestore(&dmap->lock,flags); /* FIXME: not safe may miss events */ - t = interruptible_sleep_on_timeout(&adev->out_sleeper, t); + t = oss_broken_sleep_on(&adev->out_sleeper, t); spin_lock_irqsave(&dmap->lock,flags); if (!t) { adev->dmap_out->flags &= ~DMA_SYNCING; @@ -466,7 +466,7 @@ int DMAbuf_sync(int dev) while (!signal_pending(current) && adev->d->local_qlen(dev)){ spin_unlock_irqrestore(&dmap->lock,flags); - interruptible_sleep_on_timeout(&adev->out_sleeper, + oss_broken_sleep_on(&adev->out_sleeper, dmabuf_timeout(dmap)); spin_lock_irqsave(&dmap->lock,flags); } @@ -587,8 +587,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock) timeout = dmabuf_timeout(dmap); spin_unlock_irqrestore(&dmap->lock,flags); - timeout = interruptible_sleep_on_timeout(&adev->in_sleeper, - timeout); + timeout = oss_broken_sleep_on(&adev->in_sleeper, timeout); if (!timeout) { /* FIXME: include device name */ err = -EIO; @@ -768,8 +767,7 @@ static int output_sleep(int dev, int dontblock) timeout_value = dmabuf_timeout(dmap); else timeout_value = MAX_SCHEDULE_TIMEOUT; - timeout_value = interruptible_sleep_on_timeout(&adev->out_sleeper, - timeout_value); + timeout_value = oss_broken_sleep_on(&adev->out_sleeper, timeout_value); if (timeout != MAX_SCHEDULE_TIMEOUT && !timeout_value) { printk(KERN_WARNING "Sound: DMA (output) timed out - IRQ/DRQ config error?\n"); dma_reset_output(dev); diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index 1308d8d34186..01019f06fa91 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -239,7 +239,6 @@ struct sound_queue { int busy, syncing, xruns, died; }; -#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ) #define WAKE_UP(queue) (wake_up_interruptible(&queue)) extern struct sound_queue dmasound_write_sq; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index bac43b5b6e95..f4ee85a4c42f 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -619,15 +619,27 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft, } while (uLeft) { + DEFINE_WAIT(wait); + while (write_sq.count >= write_sq.max_active) { + prepare_to_wait(&write_sq.action_queue, &wait, TASK_INTERRUPTIBLE); sq_play(); - if (write_sq.non_blocking) + if (write_sq.non_blocking) { + finish_wait(&write_sq.action_queue, &wait); return uWritten > 0 ? uWritten : -EAGAIN; - SLEEP(write_sq.action_queue); - if (signal_pending(current)) + } + if (write_sq.count < write_sq.max_active) + break; + + schedule_timeout(HZ); + if (signal_pending(current)) { + finish_wait(&write_sq.action_queue, &wait); return uWritten > 0 ? uWritten : -EINTR; + } } + finish_wait(&write_sq.action_queue, &wait); + /* Here, we can avoid disabling the interrupt by first * copying and translating the data, and then updating * the write_sq variables. Until this is done, the interrupt @@ -707,11 +719,8 @@ static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode, if (file->f_flags & O_NONBLOCK) return rc; rc = -EINTR; - while (sq->busy) { - SLEEP(sq->open_queue); - if (signal_pending(current)) - return rc; - } + if (wait_event_interruptible(sq->open_queue, !sq->busy)) + return rc; rc = 0; #else /* OSS manual says we will return EBUSY regardless @@ -844,7 +853,8 @@ static int sq_fsync(void) sq_play(); /* there may be an incomplete frame waiting */ while (write_sq.active) { - SLEEP(write_sq.sync_queue); + wait_event_interruptible_timeout(write_sq.sync_queue, + !write_sq.active, HZ); if (signal_pending(current)) { /* While waiting for audio output to drain, an * interrupt occurred. Stop audio output immediately diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c index 8cdb2cfe65c8..8f45cd999965 100644 --- a/sound/oss/midibuf.c +++ b/sound/oss/midibuf.c @@ -86,9 +86,8 @@ static void drain_midi_queue(int dev) */ if (midi_devs[dev]->buffer_status != NULL) - while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev)) - interruptible_sleep_on_timeout(&midi_sleeper[dev], - HZ/10); + wait_event_interruptible_timeout(midi_sleeper[dev], + !midi_devs[dev]->buffer_status(dev), HZ/10); } static void midi_input_intr(int dev, unsigned char data) @@ -233,8 +232,8 @@ void MIDIbuf_release(int dev, struct file *file) * devices */ - while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev])) - interruptible_sleep_on(&midi_sleeper[dev]); + wait_event_interruptible(midi_sleeper[dev], + !DATA_AVAIL(midi_out_buf[dev])); /* * Sync */ @@ -282,8 +281,8 @@ int MIDIbuf_write(int dev, struct file *file, const char __user *buf, int count) goto out; } - interruptible_sleep_on(&midi_sleeper[dev]); - if (signal_pending(current)) + if (wait_event_interruptible(midi_sleeper[dev], + SPACE_AVAIL(midi_out_buf[dev]))) { c = -EINTR; goto out; @@ -325,8 +324,9 @@ int MIDIbuf_read(int dev, struct file *file, char __user *buf, int count) c = -EAGAIN; goto out; } - interruptible_sleep_on_timeout(&input_sleeper[dev], - parms[dev].prech_timeout); + wait_event_interruptible_timeout(input_sleeper[dev], + DATA_AVAIL(midi_in_buf[dev]), + parms[dev].prech_timeout); if (signal_pending(current)) c = -EINTR; /* The user is getting restless */ diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index 11ff7c55240c..c23f9f95bfa5 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c @@ -664,12 +664,15 @@ static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static void dsp_write_flush(void) { + int timeout = get_play_delay_jiffies(dev.DAPF.len); + if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags)) return; set_bit(F_WRITEFLUSH, &dev.flags); - interruptible_sleep_on_timeout( - &dev.writeflush, - get_play_delay_jiffies(dev.DAPF.len)); + wait_event_interruptible_timeout( + dev.writeflush, + !test_bit(F_WRITEFLUSH, &dev.flags), + timeout); clear_bit(F_WRITEFLUSH, &dev.flags); if (!signal_pending(current)) { current->state = TASK_INTERRUPTIBLE; @@ -897,6 +900,7 @@ static int dsp_read(char __user *buf, size_t len) { int count = len; char *page = (char *)__get_free_page(GFP_KERNEL); + int timeout = get_rec_delay_jiffies(DAR_BUFF_SIZE); if (!page) return -ENOMEM; @@ -936,11 +940,11 @@ static int dsp_read(char __user *buf, size_t len) if (count > 0) { set_bit(F_READBLOCK, &dev.flags); - if (!interruptible_sleep_on_timeout( - &dev.readblock, - get_rec_delay_jiffies(DAR_BUFF_SIZE))) + if (wait_event_interruptible_timeout( + dev.readblock, + test_bit(F_READBLOCK, &dev.flags), + timeout) <= 0) clear_bit(F_READING, &dev.flags); - clear_bit(F_READBLOCK, &dev.flags); if (signal_pending(current)) { free_page((unsigned long)page); return -EINTR; @@ -955,6 +959,7 @@ static int dsp_write(const char __user *buf, size_t len) { int count = len; char *page = (char *)__get_free_page(GFP_KERNEL); + int timeout = get_play_delay_jiffies(DAP_BUFF_SIZE); if (!page) return -ENOMEM; @@ -995,10 +1000,10 @@ static int dsp_write(const char __user *buf, size_t len) if (count > 0) { set_bit(F_WRITEBLOCK, &dev.flags); - interruptible_sleep_on_timeout( - &dev.writeblock, - get_play_delay_jiffies(DAP_BUFF_SIZE)); - clear_bit(F_WRITEBLOCK, &dev.flags); + wait_event_interruptible_timeout( + dev.writeblock, + test_bit(F_WRITEBLOCK, &dev.flags), + timeout); if (signal_pending(current)) { free_page((unsigned long)page); return -EINTR; @@ -1044,7 +1049,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage) clear_bit(F_WRITING, &dev.flags); } - if (test_bit(F_WRITEBLOCK, &dev.flags)) + if (test_and_clear_bit(F_WRITEBLOCK, &dev.flags)) wake_up_interruptible(&dev.writeblock); break; @@ -1055,7 +1060,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage) pack_DARQ_to_DARF(dev.last_recbank); - if (test_bit(F_READBLOCK, &dev.flags)) + if (test_and_clear_bit(F_READBLOCK, &dev.flags)) wake_up_interruptible(&dev.readblock); break; diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index 4ff60a6427d9..9b9f7d385134 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c @@ -19,6 +19,7 @@ #include "sound_config.h" #include "midi_ctrl.h" +#include "sleep.h" static int sequencer_ok; static struct sound_timer_operations *tmr; @@ -100,8 +101,7 @@ int sequencer_read(int dev, struct file *file, char __user *buf, int count) return -EAGAIN; } - interruptible_sleep_on_timeout(&midi_sleeper, - pre_event_timeout); + oss_broken_sleep_on(&midi_sleeper, pre_event_timeout); spin_lock_irqsave(&lock,flags); if (!iqlen) { @@ -343,7 +343,7 @@ static int seq_queue(unsigned char *note, char nonblock) /* * Sleep until there is enough space on the queue */ - interruptible_sleep_on(&seq_sleeper); + oss_broken_sleep_on(&seq_sleeper, MAX_SCHEDULE_TIMEOUT); } if (qlen >= SEQ_MAX_QUEUE) { @@ -1122,8 +1122,7 @@ static void seq_drain_midi_queues(void) */ if (n) - interruptible_sleep_on_timeout(&seq_sleeper, - HZ/10); + oss_broken_sleep_on(&seq_sleeper, HZ/10); } } @@ -1145,8 +1144,7 @@ void sequencer_release(int dev, struct file *file) while (!signal_pending(current) && qlen > 0) { seq_sync(); - interruptible_sleep_on_timeout(&seq_sleeper, - 3*HZ); + oss_broken_sleep_on(&seq_sleeper, 3*HZ); /* Extra delay */ } } @@ -1201,7 +1199,7 @@ static int seq_sync(void) seq_startplay(); if (qlen > 0) - interruptible_sleep_on_timeout(&seq_sleeper, HZ); + oss_broken_sleep_on(&seq_sleeper, HZ); return qlen; } @@ -1224,7 +1222,7 @@ static void midi_outc(int dev, unsigned char data) spin_lock_irqsave(&lock,flags); while (n && !midi_devs[dev]->outputc(dev, data)) { - interruptible_sleep_on_timeout(&seq_sleeper, HZ/25); + oss_broken_sleep_on(&seq_sleeper, HZ/25); n--; } spin_unlock_irqrestore(&lock,flags); diff --git a/sound/oss/sleep.h b/sound/oss/sleep.h new file mode 100644 index 000000000000..a20fc925a5ce --- /dev/null +++ b/sound/oss/sleep.h @@ -0,0 +1,18 @@ +#include + +/* + * Do not use. This is a replacement for the old + * "interruptible_sleep_on_timeout" function that has been + * deprecated for ages. All users should instead try to use + * wait_event_interruptible_timeout. + */ + +static inline long +oss_broken_sleep_on(wait_queue_head_t *q, long timeout) +{ + DEFINE_WAIT(wait); + prepare_to_wait(q, &wait, TASK_INTERRUPTIBLE); + timeout = schedule_timeout(timeout); + finish_wait(q, &wait); + return timeout; +} diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 7d8803a00b79..f851fd0e199c 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -90,6 +90,8 @@ #include #include +#include "sleep.h" + struct cs4297a_state; static DEFINE_MUTEX(swarm_cs4297a_mutex); @@ -748,7 +750,7 @@ static int serdma_reg_access(struct cs4297a_state *s, u64 data) /* Since a writer has the DSP open, we have to mux the request in */ s->reg_request = data; - interruptible_sleep_on(&s->dma_dac.reg_wait); + oss_broken_sleep_on(&s->dma_dac.reg_wait, MAX_SCHEDULE_TIMEOUT); /* XXXKW how can I deal with the starvation case where the opener isn't writing? */ } else { @@ -790,7 +792,7 @@ static int cs4297a_read_ac97(struct cs4297a_state *s, u32 offset, if (serdma_reg_access(s, (0xCLL << 60) | (1LL << 47) | ((u64)(offset & 0x7F) << 40))) return -1; - interruptible_sleep_on(&s->dma_adc.reg_wait); + oss_broken_sleep_on(&s->dma_adc.reg_wait, MAX_SCHEDULE_TIMEOUT); *value = s->read_value; CS_DBGOUT(CS_AC97, 2, printk(KERN_INFO "cs4297a: rdr reg %x -> %x\n", s->read_reg, s->read_value)); @@ -1740,7 +1742,7 @@ static ssize_t cs4297a_read(struct file *file, char *buffer, size_t count, start_adc(s); if (file->f_flags & O_NONBLOCK) return ret ? ret : -EAGAIN; - interruptible_sleep_on(&s->dma_adc.wait); + oss_broken_sleep_on(&s->dma_adc.wait, MAX_SCHEDULE_TIMEOUT); if (signal_pending(current)) return ret ? ret : -ERESTARTSYS; continue; @@ -1836,7 +1838,7 @@ static ssize_t cs4297a_write(struct file *file, const char *buffer, start_dac(s); if (file->f_flags & O_NONBLOCK) return ret ? ret : -EAGAIN; - interruptible_sleep_on(&d->wait); + oss_broken_sleep_on(&d->wait, MAX_SCHEDULE_TIMEOUT); if (signal_pending(current)) return ret ? ret : -ERESTARTSYS; continue; @@ -2452,7 +2454,7 @@ static int cs4297a_locked_open(struct inode *inode, struct file *file) return -EBUSY; } mutex_unlock(&s->open_sem_dac); - interruptible_sleep_on(&s->open_wait_dac); + oss_broken_sleep_on(&s->open_wait_dac, MAX_SCHEDULE_TIMEOUT); if (signal_pending(current)) { printk("open - sig pending\n"); @@ -2469,7 +2471,7 @@ static int cs4297a_locked_open(struct inode *inode, struct file *file) return -EBUSY; } mutex_unlock(&s->open_sem_adc); - interruptible_sleep_on(&s->open_wait_adc); + oss_broken_sleep_on(&s->open_wait_adc, MAX_SCHEDULE_TIMEOUT); if (signal_pending(current)) { printk("open - sig pending\n"); diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index 4bbcc0fcd4eb..a077e9c69a5e 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) vwsnd_dev_t *devc; int minor = iminor(inode); int sw_samplefmt; + DEFINE_WAIT(wait); DBGE("(inode=0x%p, file=0x%p)\n", inode, file); @@ -2937,21 +2938,26 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file) } mutex_lock(&devc->open_mutex); - while (devc->open_mode & file->f_mode) { + while (1) { + prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE); + if (!(devc->open_mode & file->f_mode)) + break; + mutex_unlock(&devc->open_mutex); + mutex_unlock(&vwsnd_mutex); if (file->f_flags & O_NONBLOCK) { DEC_USE_COUNT; - mutex_unlock(&vwsnd_mutex); return -EBUSY; } - interruptible_sleep_on(&devc->open_wait); + schedule(); if (signal_pending(current)) { DEC_USE_COUNT; - mutex_unlock(&vwsnd_mutex); return -ERESTARTSYS; } + mutex_lock(&vwsnd_mutex); mutex_lock(&devc->open_mutex); } + finish_wait(&devc->open_wait, &wait); devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); mutex_unlock(&devc->open_mutex); diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 46ed9e8ae0fd..8756c8e32922 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -25,6 +25,7 @@ config SND_ALS300 select SND_PCM select SND_AC97_CODEC select SND_OPL3_LIB + select ZONE_DMA help Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+ @@ -49,6 +50,7 @@ config SND_ALI5451 tristate "ALi M5451 PCI Audio Controller" select SND_MPU401_UART select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for the integrated AC97 sound device on motherboards using the ALi M5451 Audio Controller @@ -153,6 +155,7 @@ config SND_AZT3328 select SND_PCM select SND_RAWMIDI select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for Aztech AZF3328 (PCI168) soundcards. @@ -254,6 +257,7 @@ config SND_CS46XX tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x" select SND_RAWMIDI select SND_AC97_CODEC + select FW_LOADER help Say Y here to include support for Cirrus Logic CS4610/CS4612/ CS4614/CS4615/CS4622/CS4624/CS4630/CS4280 chips. @@ -458,6 +462,7 @@ config SND_EMU10K1 select SND_HWDEP select SND_RAWMIDI select SND_AC97_CODEC + select ZONE_DMA help Say Y to include support for Sound Blaster PCI 512, Live!, Audigy and E-mu APS (partially supported) soundcards. @@ -473,6 +478,7 @@ config SND_EMU10K1X tristate "Emu10k1X (Dell OEM Version)" select SND_AC97_CODEC select SND_RAWMIDI + select ZONE_DMA help Say Y here to include support for the Dell OEM version of the Sound Blaster Live!. @@ -506,6 +512,7 @@ config SND_ES1938 select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for soundcards based on ESS Solo-1 (ES1938, ES1946, ES1969) chips. @@ -517,6 +524,7 @@ config SND_ES1968 tristate "ESS ES1968/1978 (Maestro-1/2/2E)" select SND_MPU401_UART select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for soundcards based on ESS Maestro 1/2/2E chips. @@ -605,6 +613,7 @@ config SND_ICE1712 select SND_MPU401_UART select SND_AC97_CODEC select BITREVERSE + select ZONE_DMA help Say Y here to include support for soundcards based on the ICE1712 (Envy24) chip. @@ -692,6 +701,7 @@ config SND_LX6464ES config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for soundcards based on ESS Maestro 3 (Allegro) chips. @@ -788,6 +798,7 @@ config SND_SIS7019 tristate "SiS 7019 Audio Accelerator" depends on X86 && !X86_64 select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for the SiS 7019 Audio Accelerator. @@ -799,6 +810,7 @@ config SND_SONICVIBES select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for soundcards based on the S3 SonicVibes chip. @@ -810,6 +822,7 @@ config SND_TRIDENT tristate "Trident 4D-Wave DX/NX; SiS 7018" select SND_MPU401_UART select SND_AC97_CODEC + select ZONE_DMA help Say Y here to include support for soundcards based on Trident 4D-Wave DX/NX or SiS 7018 chips. diff --git a/sound/pci/cs46xx/cs46xx.h b/sound/pci/cs46xx/cs46xx.h index fc339ef0a0ae..c49a082c378b 100644 --- a/sound/pci/cs46xx/cs46xx.h +++ b/sound/pci/cs46xx/cs46xx.h @@ -1716,9 +1716,14 @@ struct snd_cs46xx { struct snd_pcm *pcm_rear; struct snd_pcm *pcm_center_lfe; struct snd_pcm *pcm_iec958; + +#define CS46XX_DSP_MODULES 5 + struct dsp_module_desc *modules[CS46XX_DSP_MODULES]; #else /* for compatibility */ struct snd_cs46xx_pcm *playback_pcm; unsigned int play_ctl; + + struct ba1_struct *ba1; #endif #ifdef CONFIG_PM_SLEEP diff --git a/sound/pci/cs46xx/cs46xx_image.h b/sound/pci/cs46xx/cs46xx_image.h deleted file mode 100644 index dc93f62db2c2..000000000000 --- a/sound/pci/cs46xx/cs46xx_image.h +++ /dev/null @@ -1,3468 +0,0 @@ -struct BA1struct { - struct { - unsigned long offset; - unsigned long size; - } memory[BA1_MEMORY_COUNT]; - u32 map[BA1_DWORD_SIZE]; -}; - - -static struct BA1struct BA1Struct = { -{{ 0x00000000, 0x00003000 },{ 0x00010000, 0x00003800 },{ 0x00020000, 0x00007000 }}, -{0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000163,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00200040,0x00008010,0x00000000, -0x00000000,0x80000001,0x00000001,0x00060000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00900080,0x00000173,0x00000000, -0x00000000,0x00000010,0x00800000,0x00900000, -0xf2c0000f,0x00000200,0x00000000,0x00010600, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000163,0x330300c2, -0x06000000,0x00000000,0x80008000,0x80008000, -0x3fc0000f,0x00000301,0x00010400,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00b00000,0x00d0806d,0x330480c3, -0x04800000,0x00000001,0x00800001,0x0000ffff, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x066a0600,0x06350070,0x0000929d,0x929d929d, -0x00000000,0x0000735a,0x00000600,0x00000000, -0x929d735a,0x8734abfe,0x00010000,0x735a735a, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x0000804f,0x000000c3, -0x05000000,0x00a00010,0x00000000,0x80008000, -0x00000000,0x00000000,0x00000700,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000080,0x00a00000,0x0000809a,0x000000c2, -0x07400000,0x00000000,0x80008000,0xffffffff, -0x00c80028,0x00005555,0x00000000,0x000107a0, -0x00c80028,0x000000c2,0x06800000,0x00000000, -0x06e00080,0x00300000,0x000080bb,0x000000c9, -0x07a00000,0x04000000,0x80008000,0xffffffff, -0x00c80028,0x00005555,0x00000000,0x00000780, -0x00c80028,0x000000c5,0xff800000,0x00000000, -0x00640080,0x00c00000,0x00008197,0x000000c9, -0x07800000,0x04000000,0x80008000,0xffffffff, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x0000805e,0x000000c1, -0x00000000,0x00800000,0x80008000,0x80008000, -0x00020000,0x0000ffff,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x929d0600,0x929d929d,0x929d929d,0x929d0000, -0x929d929d,0x929d929d,0x929d929d,0x929d929d, -0x929d929d,0x00100635,0x060b013f,0x00000004, -0x00000001,0x007a0002,0x00000000,0x066e0610, -0x0105929d,0x929d929d,0x929d929d,0x929d929d, -0x929d929d,0xa431ac75,0x0001735a,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051, -0x00000000,0x929d929d,0x929d929d,0x929d929d, -0x929d929d,0x929d929d,0x929d929d,0x929d929d, -0x929d929d,0x929d929d,0x00000000,0x06400136, -0x0000270f,0x00010000,0x007a0000,0x00000000, -0x068e0645,0x0105929d,0x929d929d,0x929d929d, -0x929d929d,0x929d929d,0xa431ac75,0x0001735a, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -0x735a0100,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00010004, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00001705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00009705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00011705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00019705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00021705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00029705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00031705,0x00001400,0x000a411e,0x00001003, -0x00040730,0x00001002,0x000f619e,0x00001003, -0x00039705,0x00001400,0x000a411e,0x00001003, -0x000fe19e,0x00001003,0x0009c730,0x00001003, -0x0008e19c,0x00001003,0x000083c1,0x00093040, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00009705,0x00001400,0x000a211e,0x00001003, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00011705,0x00001400,0x000a211e,0x00001003, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00019705,0x00001400,0x000a211e,0x00001003, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00021705,0x00001400,0x000a211e,0x00001003, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00029705,0x00001400,0x000a211e,0x00001003, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00031705,0x00001400,0x000a211e,0x00001003, -0x00098730,0x00001002,0x000ee19e,0x00001003, -0x00039705,0x00001400,0x000a211e,0x00001003, -0x0000a730,0x00001008,0x000e2730,0x00001002, -0x0000a731,0x00001002,0x0000a731,0x00001002, -0x0000a731,0x00001002,0x0000a731,0x00001002, -0x0000a731,0x00001002,0x0000a731,0x00001002, -0x00000000,0x00000000,0x000f619c,0x00001003, -0x0007f801,0x000c0000,0x00000037,0x00001000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x000c0000,0x00000000,0x00000000, -0x0000373c,0x00001000,0x00000000,0x00000000, -0x000ee19c,0x00001003,0x0007f801,0x000c0000, -0x00000037,0x00001000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x0000273c,0x00001000, -0x00000033,0x00001000,0x000e679e,0x00001003, -0x00007705,0x00001400,0x000ac71e,0x00001003, -0x00087fc1,0x000c3be0,0x0007f801,0x000c0000, -0x00000037,0x00001000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x0000a730,0x00001003, -0x00000033,0x00001000,0x0007f801,0x000c0000, -0x00000037,0x00001000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x000c0000, -0x00000032,0x00001000,0x0000273d,0x00001000, -0x0004a730,0x00001003,0x00000f41,0x00097140, -0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -0x00000000,0x00000000,0x0001bf05,0x0003fc40, -0x00002725,0x000aa400,0x00013705,0x00093a00, -0x0000002e,0x0009d6c0,0x00038630,0x00001004, -0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000, -0x00000000,0x000c70e0,0x0007d182,0x0002c640, -0x00000630,0x00001004,0x000799b8,0x0002c6c0, -0x00031705,0x00092240,0x00039f05,0x000932c0, -0x0003520a,0x00000000,0x00040731,0x0000100b, -0x00010705,0x000b20c0,0x00000000,0x000eba44, -0x00032108,0x000c60c4,0x00065208,0x000c2917, -0x000406b0,0x00001007,0x00012f05,0x00036880, -0x0002818e,0x000c0000,0x0004410a,0x00000000, -0x00040630,0x00001007,0x00029705,0x000c0000, -0x00000000,0x00000000,0x00003fc1,0x0003fc40, -0x000037c1,0x00091b40,0x00003fc1,0x000911c0, -0x000037c1,0x000957c0,0x00003fc1,0x000951c0, -0x000037c1,0x00000000,0x00003fc1,0x000991c0, -0x000037c1,0x00000000,0x00003fc1,0x0009d1c0, -0x000037c1,0x00000000,0x0001ccc1,0x000915c0, -0x0001c441,0x0009d800,0x0009cdc1,0x00091240, -0x0001c541,0x00091d00,0x0009cfc1,0x00095240, -0x0001c741,0x00095c80,0x000e8ca9,0x00099240, -0x000e85ad,0x00095640,0x00069ca9,0x00099d80, -0x000e952d,0x00099640,0x000eaca9,0x0009d6c0, -0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80, -0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0, -0x000ec5ad,0x0009da40,0x000edca9,0x0009d300, -0x000a6e0a,0x00001000,0x000ed52d,0x00091e40, -0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40, -0x0006fca9,0x00002500,0x000fb208,0x000c59a0, -0x000ef52d,0x0009de40,0x00068ca9,0x000912c1, -0x000683ad,0x00095241,0x00020f05,0x000991c1, -0x00000000,0x00000000,0x00086f88,0x00001000, -0x0009cf81,0x000b5340,0x0009c701,0x000b92c0, -0x0009de81,0x000bd300,0x0009d601,0x000b1700, -0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0, -0x000a0f81,0x000bd740,0x00020701,0x000b5c80, -0x000a1681,0x000b97c0,0x00021601,0x00002500, -0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0, -0x00021681,0x00002d00,0x00020f81,0x000bd800, -0x000a0701,0x000b5bc0,0x00021601,0x00003500, -0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0, -0x00021681,0x00003d00,0x00020f81,0x000b1d00, -0x000a0701,0x000b1fc0,0x00021601,0x00020500, -0x00020f81,0x000b1341,0x000a0701,0x000b9fc0, -0x00021681,0x00020d00,0x00020f81,0x000bde80, -0x000a0701,0x000bdfc0,0x00021601,0x00021500, -0x00020f81,0x000b9341,0x00020701,0x000b53c1, -0x00021681,0x00021d00,0x000a0f81,0x000d0380, -0x0000b601,0x000b15c0,0x00007b01,0x00000000, -0x00007b81,0x000bd1c0,0x00007b01,0x00000000, -0x00007b81,0x000b91c0,0x00007b01,0x000b57c0, -0x00007b81,0x000b51c0,0x00007b01,0x000b1b40, -0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0, -0x0007e488,0x000d7e45,0x00000000,0x000d7a44, -0x0007e48a,0x00000000,0x00011f05,0x00084080, -0x00000000,0x00000000,0x00001705,0x000b3540, -0x00008a01,0x000bf040,0x00007081,0x000bb5c0, -0x00055488,0x00000000,0x0000d482,0x0003fc40, -0x0003fc88,0x00000000,0x0001e401,0x000b3a00, -0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784, -0x000c86b0,0x00001007,0x00008281,0x000bb240, -0x0000b801,0x000b7140,0x00007888,0x00000000, -0x0000073c,0x00001000,0x0007f188,0x000c0000, -0x00000000,0x00000000,0x00055288,0x000c555c, -0x0005528a,0x000c0000,0x0009fa88,0x000c5d00, -0x0000fa88,0x00000000,0x00000032,0x00001000, -0x0000073d,0x00001000,0x0007f188,0x000c0000, -0x00000000,0x00000000,0x0008c01c,0x00001003, -0x00002705,0x00001008,0x0008b201,0x000c1392, -0x0000ba01,0x00000000,0x00008731,0x00001400, -0x0004c108,0x000fe0c4,0x00057488,0x00000000, -0x000a6388,0x00001001,0x0008b334,0x000bc141, -0x0003020e,0x00000000,0x000886b0,0x00001008, -0x00003625,0x000c5dfa,0x000a638a,0x00001001, -0x0008020e,0x00001002,0x0008a6b0,0x00001008, -0x0007f301,0x00000000,0x00000000,0x00000000, -0x00002725,0x000a8c40,0x000000ae,0x00000000, -0x000d8630,0x00001008,0x00000000,0x000c74e0, -0x0007d182,0x0002d640,0x000a8630,0x00001008, -0x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5, -0x0007420a,0x000c0000,0x00062208,0x000c4117, -0x00070630,0x00001009,0x00000000,0x000c0000, -0x0001022e,0x00000000,0x0003a630,0x00001009, -0x00000000,0x000c0000,0x00000036,0x00001000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x0002a730,0x00001008,0x0007f801,0x000c0000, -0x00000037,0x00001000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x0002a730,0x00001008, -0x00000033,0x00001000,0x0002a705,0x00001008, -0x00007a01,0x000c0000,0x000e6288,0x000d550a, -0x0006428a,0x00000000,0x00060730,0x0000100a, -0x00000000,0x000c0000,0x00000000,0x00000000, -0x0007aab0,0x00034880,0x00078fb0,0x0000100b, -0x00057488,0x00000000,0x00033b94,0x00081140, -0x000183ae,0x00000000,0x000786b0,0x0000100b, -0x00022f05,0x000c3545,0x0000eb8a,0x00000000, -0x00042731,0x00001003,0x0007aab0,0x00034880, -0x00048fb0,0x0000100a,0x00057488,0x00000000, -0x00033b94,0x00081140,0x000183ae,0x00000000, -0x000806b0,0x0000100b,0x00022f05,0x00000000, -0x00007401,0x00091140,0x00048f05,0x000951c0, -0x00042731,0x00001003,0x0000473d,0x00001000, -0x000f19b0,0x000bbc47,0x00080000,0x000bffc7, -0x000fe19e,0x00001003,0x00000000,0x00000000, -0x0008e19c,0x00001003,0x000083c1,0x00093040, -0x00000f41,0x00097140,0x0000a841,0x0009b240, -0x0000a0c1,0x0009f040,0x0001c641,0x00093540, -0x0001cec1,0x0009b5c0,0x00000000,0x000fdc44, -0x00055208,0x00000000,0x00010705,0x000a2880, -0x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5, -0x0004ef0a,0x000c0000,0x00012f05,0x00036880, -0x00065308,0x000c2997,0x000d86b0,0x0000100a, -0x0004410a,0x000d40c7,0x00000000,0x00000000, -0x00080730,0x00001004,0x00056f0a,0x000ea105, -0x00000000,0x00000000,0x0000473d,0x00001000, -0x000f19b0,0x000bbc47,0x00080000,0x000bffc7, -0x0000273d,0x00001000,0x00000000,0x000eba44, -0x00048f05,0x0000f440,0x00007401,0x0000f7c0, -0x00000734,0x00001000,0x00010705,0x000a6880, -0x00006a88,0x000c75c4,0x00000000,0x000e5084, -0x00000000,0x000eba44,0x00087401,0x000e4782, -0x00000734,0x00001000,0x00010705,0x000a6880, -0x00006a88,0x000c75c4,0x0007c108,0x000c0000, -0x0007e721,0x000bed40,0x00005f25,0x000badc0, -0x0003ba97,0x000beb80,0x00065590,0x000b2e00, -0x00033217,0x00003ec0,0x00065590,0x000b8e40, -0x0003ed80,0x000491c0,0x00073fb0,0x00074c80, -0x000283a0,0x0000100c,0x000ee388,0x00042970, -0x00008301,0x00021ef2,0x000b8f14,0x0000000f, -0x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6, -0x000032ac,0x000c3916,0x0004edc2,0x00074c80, -0x00078898,0x00001000,0x00038894,0x00000032, -0x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6, -0x0004edc2,0x000c1956,0x0000722c,0x00034a00, -0x00041705,0x0009ed40,0x00058730,0x00001400, -0x000d7488,0x000c3a00,0x00048f05,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000, -0x00000000,0x00000000,0x00000000,0x00000000} - }; diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 1b66efd9b728..f18e5878f58b 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -54,7 +54,9 @@ #include #include #include - +#include +#include +#include #include #include @@ -330,13 +332,146 @@ int snd_cs46xx_download(struct snd_cs46xx *chip, return 0; } +static inline void memcpy_le32(void *dst, const void *src, unsigned int len) +{ +#ifdef __LITTLE_ENDIAN + memcpy(dst, src, len); +#else + u32 *_dst = dst; + const __le32 *_src = src; + len /= 4; + while (len-- > 0) + *_dst++ = le32_to_cpu(*_src++); +#endif +} + #ifdef CONFIG_SND_CS46XX_NEW_DSP -#include "imgs/cwc4630.h" -#include "imgs/cwcasync.h" -#include "imgs/cwcsnoop.h" -#include "imgs/cwcbinhack.h" -#include "imgs/cwcdma.h" +static const char *module_names[CS46XX_DSP_MODULES] = { + "cwc4630", "cwcasync", "cwcsnoop", "cwcbinhack", "cwcdma" +}; + +MODULE_FIRMWARE("cs46xx/cwc4630"); +MODULE_FIRMWARE("cs46xx/cwcasync"); +MODULE_FIRMWARE("cs46xx/cwcsnoop"); +MODULE_FIRMWARE("cs46xx/cwcbinhack"); +MODULE_FIRMWARE("cs46xx/cwcdma"); + +static void free_module_desc(struct dsp_module_desc *module) +{ + if (!module) + return; + kfree(module->module_name); + kfree(module->symbol_table.symbols); + if (module->segments) { + int i; + for (i = 0; i < module->nsegments; i++) + kfree(module->segments[i].data); + kfree(module->segments); + } +} + +/* firmware binary format: + * le32 nsymbols; + * struct { + * le32 address; + * char symbol_name[DSP_MAX_SYMBOL_NAME]; + * le32 symbol_type; + * } symbols[nsymbols]; + * le32 nsegments; + * struct { + * le32 segment_type; + * le32 offset; + * le32 size; + * le32 data[size]; + * } segments[nsegments]; + */ + +static int load_firmware(struct snd_cs46xx *chip, + struct dsp_module_desc **module_ret, + const char *fw_name) +{ + int i, err; + unsigned int nums, fwlen, fwsize; + const __le32 *fwdat; + struct dsp_module_desc *module = NULL; + const struct firmware *fw; + char fw_path[32]; + + sprintf(fw_path, "cs46xx/%s", fw_name); + err = request_firmware(&fw, fw_path, &chip->pci->dev); + if (err < 0) + return err; + fwsize = fw->size / 4; + if (fwsize < 2) { + err = -EINVAL; + goto error; + } + + err = -ENOMEM; + module = kzalloc(sizeof(*module), GFP_KERNEL); + if (!module) + goto error; + module->module_name = kstrdup(fw_name, GFP_KERNEL); + if (!module->module_name) + goto error; + + fwlen = 0; + fwdat = (const __le32 *)fw->data; + nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]); + if (nums >= 40) + goto error_inval; + module->symbol_table.symbols = + kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL); + if (!module->symbol_table.symbols) + goto error; + for (i = 0; i < nums; i++) { + struct dsp_symbol_entry *entry = + &module->symbol_table.symbols[i]; + if (fwlen + 2 + DSP_MAX_SYMBOL_NAME / 4 > fwsize) + goto error_inval; + entry->address = le32_to_cpu(fwdat[fwlen++]); + memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1); + fwlen += DSP_MAX_SYMBOL_NAME / 4; + entry->symbol_type = le32_to_cpu(fwdat[fwlen++]); + } + + if (fwlen >= fwsize) + goto error_inval; + nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]); + if (nums > 10) + goto error_inval; + module->segments = + kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL); + if (!module->segments) + goto error; + for (i = 0; i < nums; i++) { + struct dsp_segment_desc *entry = &module->segments[i]; + if (fwlen + 3 > fwsize) + goto error_inval; + entry->segment_type = le32_to_cpu(fwdat[fwlen++]); + entry->offset = le32_to_cpu(fwdat[fwlen++]); + entry->size = le32_to_cpu(fwdat[fwlen++]); + if (fwlen + entry->size > fwsize) + goto error_inval; + entry->data = kmalloc(entry->size * 4, GFP_KERNEL); + if (!entry->data) + goto error; + memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4); + fwlen += entry->size; + } + + *module_ret = module; + release_firmware(fw); + return 0; + + error_inval: + err = -EINVAL; + error: + free_module_desc(module); + release_firmware(fw); + return err; +} int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, unsigned long offset, @@ -361,20 +496,63 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, #else /* old DSP image */ -#include "cs46xx_image.h" +struct ba1_struct { + struct { + u32 offset; + u32 size; + } memory[BA1_MEMORY_COUNT]; + u32 map[BA1_DWORD_SIZE]; +}; + +MODULE_FIRMWARE("cs46xx/ba1"); + +static int load_firmware(struct snd_cs46xx *chip) +{ + const struct firmware *fw; + int i, size, err; + + err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev); + if (err < 0) + return err; + if (fw->size != sizeof(*chip->ba1)) { + err = -EINVAL; + goto error; + } + + chip->ba1 = vmalloc(sizeof(*chip->ba1)); + if (!chip->ba1) { + err = -ENOMEM; + goto error; + } + + memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1)); + + /* sanity check */ + size = 0; + for (i = 0; i < BA1_MEMORY_COUNT; i++) + size += chip->ba1->memory[i].size; + if (size > BA1_DWORD_SIZE * 4) + err = -EINVAL; + + error: + release_firmware(fw); + return err; +} int snd_cs46xx_download_image(struct snd_cs46xx *chip) { int idx, err; - unsigned long offset = 0; + unsigned int offset = 0; + struct ba1_struct *ba1 = chip->ba1; for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) { - if ((err = snd_cs46xx_download(chip, - &BA1Struct.map[offset], - BA1Struct.memory[idx].offset, - BA1Struct.memory[idx].size)) < 0) + err = snd_cs46xx_download(chip, + &ba1->map[offset], + ba1->memory[idx].offset, + ba1->memory[idx].size); + if (err < 0) return err; - offset += BA1Struct.memory[idx].size >> 2; + offset += ba1->memory[idx].size >> 2; } return 0; } @@ -2798,6 +2976,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) cs46xx_dsp_spos_destroy(chip); chip->dsp_spos_instance = NULL; } + for (idx = 0; idx < CS46XX_DSP_MODULES; idx++) + free_module_desc(chip->modules[idx]); +#else + vfree(chip->ba1); #endif #ifdef CONFIG_PM_SLEEP @@ -3067,6 +3249,11 @@ static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip) int snd_cs46xx_start_dsp(struct snd_cs46xx *chip) { unsigned int tmp; +#ifdef CONFIG_SND_CS46XX_NEW_DSP + int i; +#endif + int err; + /* * Reset the processor. */ @@ -3075,45 +3262,33 @@ int snd_cs46xx_start_dsp(struct snd_cs46xx *chip) * Download the image to the processor. */ #ifdef CONFIG_SND_CS46XX_NEW_DSP -#if 0 - if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) { - snd_printk(KERN_ERR "image download error\n"); - return -EIO; - } -#endif - - if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) { - snd_printk(KERN_ERR "image download error [cwc4630]\n"); - return -EIO; - } - - if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) { - snd_printk(KERN_ERR "image download error [cwcasync]\n"); - return -EIO; - } - - if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) { - snd_printk(KERN_ERR "image download error [cwcsnoop]\n"); - return -EIO; - } - - if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) { - snd_printk(KERN_ERR "image download error [cwcbinhack]\n"); - return -EIO; - } - - if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) { - snd_printk(KERN_ERR "image download error [cwcdma]\n"); - return -EIO; + for (i = 0; i < CS46XX_DSP_MODULES; i++) { + err = load_firmware(chip, &chip->modules[i], module_names[i]); + if (err < 0) { + snd_printk(KERN_ERR "firmware load error [%s]\n", + module_names[i]); + return err; + } + err = cs46xx_dsp_load_module(chip, chip->modules[i]); + if (err < 0) { + snd_printk(KERN_ERR "image download error [%s]\n", + module_names[i]); + return err; + } } if (cs46xx_dsp_scb_and_task_init(chip) < 0) return -EIO; #else + err = load_firmware(chip); + if (err < 0) + return err; + /* old image */ - if (snd_cs46xx_download_image(chip) < 0) { + err = snd_cs46xx_download_image(chip); + if (err < 0) { snd_printk(KERN_ERR "image download error\n"); - return -EIO; + return err; } /* diff --git a/sound/pci/cs46xx/imgs/cwc4630.h b/sound/pci/cs46xx/imgs/cwc4630.h deleted file mode 100644 index 37c4f1318dc5..000000000000 --- a/sound/pci/cs46xx/imgs/cwc4630.h +++ /dev/null @@ -1,320 +0,0 @@ -/* generated from cwc4630.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwc4630_H__ -#define __HEADER_cwc4630_H__ - -static struct dsp_symbol_entry cwc4630_symbols[] = { - { 0x0000, "BEGINADDRESS",0x00 }, - { 0x8000, "EXECCHILD",0x03 }, - { 0x8001, "EXECCHILD_98",0x03 }, - { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, - { 0x8008, "EXECSIBLING",0x03 }, - { 0x800a, "EXECSIBLING_298",0x03 }, - { 0x800b, "EXECSIBLING_2IND1",0x03 }, - { 0x8010, "TIMINGMASTER",0x03 }, - { 0x804f, "S16_CODECINPUTTASK",0x03 }, - { 0x805e, "PCMSERIALINPUTTASK",0x03 }, - { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, - { 0x809a, "S16_MIX",0x03 }, - { 0x80bb, "S16_UPSRC",0x03 }, - { 0x813b, "MIX3_EXP",0x03 }, - { 0x8164, "DECIMATEBYPOW2",0x03 }, - { 0x8197, "VARIDECIMATE",0x03 }, - { 0x81f2, "_3DINPUTTASK",0x03 }, - { 0x820a, "_3DPRLGCINPTASK",0x03 }, - { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, - { 0x8242, "_3DOUTPUTTASK",0x03 }, - { 0x82c4, "HRTF_MORPH_TASK",0x03 }, - { 0x82c6, "WAIT4DATA",0x03 }, - { 0x82fa, "PROLOGIC",0x03 }, - { 0x8496, "DECORRELATOR",0x03 }, - { 0x84a4, "STEREO2MONO",0x03 }, - { 0x0070, "SPOSCB",0x02 }, - { 0x0107, "TASKTREETHREAD",0x03 }, - { 0x013c, "TASKTREEHEADERCODE",0x03 }, - { 0x0145, "FGTASKTREEHEADERCODE",0x03 }, - { 0x0169, "NULLALGORITHM",0x03 }, - { 0x016d, "HFGEXECCHILD",0x03 }, - { 0x016e, "HFGEXECCHILD_98",0x03 }, - { 0x0170, "HFGEXECCHILD_PUSH1IND",0x03 }, - { 0x0173, "HFGEXECSIBLING",0x03 }, - { 0x0175, "HFGEXECSIBLING_298",0x03 }, - { 0x0176, "HFGEXECSIBLING_2IND1",0x03 }, - { 0x0179, "S16_CODECOUTPUTTASK",0x03 }, - { 0x0194, "#CODE_END",0x00 }, -}; /* cwc4630 symbols */ - -static u32 cwc4630_code[] = { -/* BEGINADDRESS */ -/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003, -/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003, -/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003, -/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003, -/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003, -/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003, -/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003, -/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003, -/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003, -/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040, -/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003, -/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003, -/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003, -/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003, -/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003, -/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003, -/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003, -/* 0040 */ 0x0001a730,0x00001008,0x000e2730,0x00001002, -/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003, -/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000, -/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000, -/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000, -/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000, -/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003, -/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003, -/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000, -/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003, -/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000, -/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000, -/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000, -/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140, -/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40, -/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00, -/* 007C */ 0x0000002e,0x0009d6c0,0x0002ef8a,0x00000000, -/* 007E */ 0x00040630,0x00001004,0x0004ef0a,0x000eb785, -/* 0080 */ 0x0003fc8a,0x00000000,0x00000000,0x000c70e0, -/* 0082 */ 0x0007d182,0x0002c640,0x00008630,0x00001004, -/* 0084 */ 0x000799b8,0x0002c6c0,0x00031705,0x00092240, -/* 0086 */ 0x00039f05,0x000932c0,0x0003520a,0x00000000, -/* 0088 */ 0x00070731,0x0000100b,0x00010705,0x000b20c0, -/* 008A */ 0x00000000,0x000eba44,0x00032108,0x000c60c4, -/* 008C */ 0x00065208,0x000c2917,0x000486b0,0x00001007, -/* 008E */ 0x00012f05,0x00036880,0x0002818e,0x000c0000, -/* 0090 */ 0x0004410a,0x00000000,0x00048630,0x00001007, -/* 0092 */ 0x00029705,0x000c0000,0x00000000,0x00000000, -/* 0094 */ 0x00003fc1,0x0003fc40,0x000037c1,0x00091b40, -/* 0096 */ 0x00003fc1,0x000911c0,0x000037c1,0x000957c0, -/* 0098 */ 0x00003fc1,0x000951c0,0x000037c1,0x00000000, -/* 009A */ 0x00003fc1,0x000991c0,0x000037c1,0x00000000, -/* 009C */ 0x00003fc1,0x0009d1c0,0x000037c1,0x00000000, -/* 009E */ 0x0001ccc1,0x000915c0,0x0001c441,0x0009d800, -/* 00A0 */ 0x0009cdc1,0x00091240,0x0001c541,0x00091d00, -/* 00A2 */ 0x0009cfc1,0x00095240,0x0001c741,0x00095c80, -/* 00A4 */ 0x000e8ca9,0x00099240,0x000e85ad,0x00095640, -/* 00A6 */ 0x00069ca9,0x00099d80,0x000e952d,0x00099640, -/* 00A8 */ 0x000eaca9,0x0009d6c0,0x000ea5ad,0x00091a40, -/* 00AA */ 0x0006bca9,0x0009de80,0x000eb52d,0x00095a40, -/* 00AC */ 0x000ecca9,0x00099ac0,0x000ec5ad,0x0009da40, -/* 00AE */ 0x000edca9,0x0009d300,0x000a6e0a,0x00001000, -/* 00B0 */ 0x000ed52d,0x00091e40,0x000eeca9,0x00095ec0, -/* 00B2 */ 0x000ee5ad,0x00099e40,0x0006fca9,0x00002500, -/* 00B4 */ 0x000fb208,0x000c59a0,0x000ef52d,0x0009de40, -/* 00B6 */ 0x00068ca9,0x000912c1,0x000683ad,0x00095241, -/* 00B8 */ 0x00020f05,0x000991c1,0x00000000,0x00000000, -/* 00BA */ 0x00086f88,0x00001000,0x0009cf81,0x000b5340, -/* 00BC */ 0x0009c701,0x000b92c0,0x0009de81,0x000bd300, -/* 00BE */ 0x0009d601,0x000b1700,0x0001fd81,0x000b9d80, -/* 00C0 */ 0x0009f501,0x000b57c0,0x000a0f81,0x000bd740, -/* 00C2 */ 0x00020701,0x000b5c80,0x000a1681,0x000b97c0, -/* 00C4 */ 0x00021601,0x00002500,0x000a0701,0x000b9b40, -/* 00C6 */ 0x000a0f81,0x000b1bc0,0x00021681,0x00002d00, -/* 00C8 */ 0x00020f81,0x000bd800,0x000a0701,0x000b5bc0, -/* 00CA */ 0x00021601,0x00003500,0x000a0f81,0x000b5f40, -/* 00CC */ 0x000a0701,0x000bdbc0,0x00021681,0x00003d00, -/* 00CE */ 0x00020f81,0x000b1d00,0x000a0701,0x000b1fc0, -/* 00D0 */ 0x00021601,0x00020500,0x00020f81,0x000b1341, -/* 00D2 */ 0x000a0701,0x000b9fc0,0x00021681,0x00020d00, -/* 00D4 */ 0x00020f81,0x000bde80,0x000a0701,0x000bdfc0, -/* 00D6 */ 0x00021601,0x00021500,0x00020f81,0x000b9341, -/* 00D8 */ 0x00020701,0x000b53c1,0x00021681,0x00021d00, -/* 00DA */ 0x000a0f81,0x000d0380,0x0000b601,0x000b15c0, -/* 00DC */ 0x00007b01,0x00000000,0x00007b81,0x000bd1c0, -/* 00DE */ 0x00007b01,0x00000000,0x00007b81,0x000b91c0, -/* 00E0 */ 0x00007b01,0x000b57c0,0x00007b81,0x000b51c0, -/* 00E2 */ 0x00007b01,0x000b1b40,0x00007b81,0x000b11c0, -/* 00E4 */ 0x00087b01,0x000c3dc0,0x0007e488,0x000d7e45, -/* 00E6 */ 0x00000000,0x000d7a44,0x0007e48a,0x00000000, -/* 00E8 */ 0x00011f05,0x00084080,0x00000000,0x00000000, -/* 00EA */ 0x00001705,0x000b3540,0x00008a01,0x000bf040, -/* 00EC */ 0x00007081,0x000bb5c0,0x00055488,0x00000000, -/* 00EE */ 0x0000d482,0x0003fc40,0x0003fc88,0x00000000, -/* 00F0 */ 0x0001e401,0x000b3a00,0x0001ec81,0x000bd6c0, -/* 00F2 */ 0x0002ef88,0x000e7784,0x00056f08,0x00000000, -/* 00F4 */ 0x000d86b0,0x00001007,0x00008281,0x000bb240, -/* 00F6 */ 0x0000b801,0x000b7140,0x00007888,0x00000000, -/* 00F8 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000, -/* 00FA */ 0x00000000,0x00000000,0x00055288,0x000c555c, -/* 00FC */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00, -/* 00FE */ 0x0000fa88,0x00000000,0x00000032,0x00001000, -/* 0100 */ 0x0000073d,0x00001000,0x0007f188,0x000c0000, -/* 0102 */ 0x00000000,0x00000000,0x0008c01c,0x00001003, -/* 0104 */ 0x00002705,0x00001008,0x0008b201,0x000c1392, -/* 0106 */ 0x0000ba01,0x00000000, -/* TASKTREETHREAD */ -/* 0107 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4, -/* 0109 */ 0x00057488,0x00000000,0x000a6388,0x00001001, -/* 010B */ 0x0008b334,0x000bc141,0x0003020e,0x00000000, -/* 010D */ 0x000986b0,0x00001008,0x00003625,0x000c5dfa, -/* 010F */ 0x000a638a,0x00001001,0x0008020e,0x00001002, -/* 0111 */ 0x0009a6b0,0x00001008,0x0007f301,0x00000000, -/* 0113 */ 0x00000000,0x00000000,0x00002725,0x000a8c40, -/* 0115 */ 0x000000ae,0x00000000,0x000e8630,0x00001008, -/* 0117 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640, -/* 0119 */ 0x000b8630,0x00001008,0x000799b8,0x0002d6c0, -/* 011B */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000, -/* 011D */ 0x00062208,0x000c4117,0x000a0630,0x00001009, -/* 011F */ 0x00000000,0x000c0000,0x0001022e,0x00000000, -/* 0121 */ 0x0006a630,0x00001009,0x00000032,0x00001000, -/* 0123 */ 0x000ca21c,0x00001003,0x00005a02,0x00000000, -/* 0125 */ 0x0001a630,0x00001009,0x00000000,0x000c0000, -/* 0127 */ 0x00000036,0x00001000,0x00000000,0x00000000, -/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012B */ 0x00000000,0x00000000,0x0003a730,0x00001008, -/* 012D */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 012F */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0131 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0133 */ 0x0003a730,0x00001008,0x00000033,0x00001000, -/* 0135 */ 0x0003a705,0x00001008,0x00007a01,0x000c0000, -/* 0137 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000, -/* 0139 */ 0x00090730,0x0000100a,0x00000000,0x000c0000, -/* 013B */ 0x00000000,0x00000000, -/* TASKTREEHEADERCODE */ -/* 013C */ 0x0007aab0,0x00034880,0x000a8fb0,0x0000100b, -/* 013E */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 0140 */ 0x000183ae,0x00000000,0x000a86b0,0x0000100b, -/* 0142 */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000, -/* 0144 */ 0x00042731,0x00001003, -/* FGTASKTREEHEADERCODE */ -/* 0145 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100a, -/* 0147 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 0149 */ 0x000183ae,0x00000000,0x000b06b0,0x0000100b, -/* 014B */ 0x00022f05,0x00000000,0x00007401,0x00091140, -/* 014D */ 0x00048f05,0x000951c0,0x00042731,0x00001003, -/* 014F */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 0151 */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003, -/* 0153 */ 0x00000000,0x00000000,0x0008e19c,0x00001003, -/* 0155 */ 0x000083c1,0x00093040,0x00000f41,0x00097140, -/* 0157 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0159 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 015B */ 0x00000000,0x000fdc44,0x00055208,0x00000000, -/* 015D */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00, -/* 015F */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000, -/* 0161 */ 0x00012f05,0x00036880,0x00065308,0x000c2997, -/* 0163 */ 0x000086b0,0x0000100b,0x0004410a,0x000d40c7, -/* 0165 */ 0x00000000,0x00000000,0x00088730,0x00001004, -/* 0167 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000, -/* NULLALGORITHM */ -/* 0169 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 016B */ 0x00080000,0x000bffc7,0x0000273d,0x00001000, -/* HFGEXECCHILD */ -/* 016D */ 0x00000000,0x000eba44, -/* HFGEXECCHILD_98 */ -/* 016E */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0, -/* HFGEXECCHILD_PUSH1IND */ -/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 0172 */ 0x00006a88,0x000c75c4, -/* HFGEXECSIBLING */ -/* 0173 */ 0x00000000,0x000e5084,0x00000000,0x000eba44, -/* HFGEXECSIBLING_298 */ -/* 0175 */ 0x00087401,0x000e4782, -/* HFGEXECSIBLING_2IND1 */ -/* 0176 */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 0178 */ 0x00006a88,0x000c75c4, -/* S16_CODECOUTPUTTASK */ -/* 0179 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40, -/* 017B */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80, -/* 017D */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0, -/* 017F */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0, -/* 0181 */ 0x00073fb0,0x00074c80,0x000583a0,0x0000100c, -/* 0183 */ 0x000ee388,0x00042970,0x00008301,0x00021ef2, -/* 0185 */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b, -/* 0187 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916, -/* 0189 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000, -/* 018B */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b, -/* 018D */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956, -/* 018F */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40, -/* 0191 */ 0x00058730,0x00001400,0x000d7488,0x000c3a00, -/* 0193 */ 0x00048f05,0x00000000 -}; -/* #CODE_END */ - -static u32 cwc4630_parameter[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000 -}; /* #PARAMETER_END */ - - -static struct dsp_segment_desc cwc4630_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000328, cwc4630_code }, - { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000080, cwc4630_parameter }, -}; - -static struct dsp_module_desc cwc4630_module = { - "cwc4630", - { - 38, - cwc4630_symbols - }, - 2, - cwc4630_segments, -}; - -#endif /* __HEADER_cwc4630_H__ */ diff --git a/sound/pci/cs46xx/imgs/cwcasync.h b/sound/pci/cs46xx/imgs/cwcasync.h deleted file mode 100644 index 70e63e13c2b3..000000000000 --- a/sound/pci/cs46xx/imgs/cwcasync.h +++ /dev/null @@ -1,176 +0,0 @@ -/* generated from cwcasync.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwcasync_H__ -#define __HEADER_cwcasync_H__ - -static struct dsp_symbol_entry cwcasync_symbols[] = { - { 0x8000, "EXECCHILD",0x03 }, - { 0x8001, "EXECCHILD_98",0x03 }, - { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, - { 0x8008, "EXECSIBLING",0x03 }, - { 0x800a, "EXECSIBLING_298",0x03 }, - { 0x800b, "EXECSIBLING_2IND1",0x03 }, - { 0x8010, "TIMINGMASTER",0x03 }, - { 0x804f, "S16_CODECINPUTTASK",0x03 }, - { 0x805e, "PCMSERIALINPUTTASK",0x03 }, - { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, - { 0x809a, "S16_MIX",0x03 }, - { 0x80bb, "S16_UPSRC",0x03 }, - { 0x813b, "MIX3_EXP",0x03 }, - { 0x8164, "DECIMATEBYPOW2",0x03 }, - { 0x8197, "VARIDECIMATE",0x03 }, - { 0x81f2, "_3DINPUTTASK",0x03 }, - { 0x820a, "_3DPRLGCINPTASK",0x03 }, - { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, - { 0x8242, "_3DOUTPUTTASK",0x03 }, - { 0x82c4, "HRTF_MORPH_TASK",0x03 }, - { 0x82c6, "WAIT4DATA",0x03 }, - { 0x82fa, "PROLOGIC",0x03 }, - { 0x8496, "DECORRELATOR",0x03 }, - { 0x84a4, "STEREO2MONO",0x03 }, - { 0x0000, "OVERLAYBEGINADDRESS",0x00 }, - { 0x0000, "SPIOWRITE",0x03 }, - { 0x000d, "S16_ASYNCCODECINPUTTASK",0x03 }, - { 0x0043, "SPDIFITASK",0x03 }, - { 0x007b, "SPDIFOTASK",0x03 }, - { 0x0097, "ASYNCHFGTXCODE",0x03 }, - { 0x00be, "ASYNCHFGRXCODE",0x03 }, - { 0x00db, "#CODE_END",0x00 }, -}; /* cwcasync symbols */ - -static u32 cwcasync_code[] = { -/* OVERLAYBEGINADDRESS */ -/* 0000 */ 0x00002731,0x00001400,0x00003725,0x000a8440, -/* 0002 */ 0x000000ae,0x00000000,0x00060630,0x00001000, -/* 0004 */ 0x00000000,0x000c7560,0x00075282,0x0002d640, -/* 0006 */ 0x00021705,0x00000000,0x00072ab8,0x0002d6c0, -/* 0008 */ 0x00020630,0x00001000,0x000c74c2,0x000d4b82, -/* 000A */ 0x000475c2,0x00000000,0x0003430a,0x000c0000, -/* 000C */ 0x00042730,0x00001400, -/* S16_ASYNCCODECINPUTTASK */ -/* 000D */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x00000000, -/* 000F */ 0x000fa418,0x0000101f,0x0005d402,0x0001c500, -/* 0011 */ 0x000f0630,0x00001000,0x00004418,0x00001380, -/* 0013 */ 0x000e243d,0x000d394a,0x00049705,0x00000000, -/* 0015 */ 0x0007d530,0x000b4240,0x000e00f2,0x00001000, -/* 0017 */ 0x00009134,0x000ca20a,0x00004c90,0x00001000, -/* 0019 */ 0x0005d705,0x00000000,0x00004f25,0x00098240, -/* 001B */ 0x00004725,0x00000000,0x0000e48a,0x00000000, -/* 001D */ 0x00027295,0x0009c2c0,0x0003df25,0x00000000, -/* 001F */ 0x000e8030,0x00001001,0x0005f718,0x000ac600, -/* 0021 */ 0x0007cf30,0x000c2a01,0x00082630,0x00001001, -/* 0023 */ 0x000504a0,0x00001001,0x00029314,0x000bcb80, -/* 0025 */ 0x0003cf25,0x000b0e00,0x0004f5c0,0x00000000, -/* 0027 */ 0x00049118,0x000d888a,0x0007dd02,0x000c6efa, -/* 0029 */ 0x00000000,0x00000000,0x0004f5c0,0x00069c80, -/* 002B */ 0x0000d402,0x00000000,0x000e8630,0x00001001, -/* 002D */ 0x00079130,0x00000000,0x00049118,0x00090e00, -/* 002F */ 0x0006c10a,0x00000000,0x00000000,0x000c0000, -/* 0031 */ 0x0007cf30,0x00030580,0x00005725,0x00000000, -/* 0033 */ 0x000d84a0,0x00001001,0x00029314,0x000b4780, -/* 0035 */ 0x0003cf25,0x000b8600,0x00000000,0x00000000, -/* 0037 */ 0x00000000,0x000c0000,0x00000000,0x00042c80, -/* 0039 */ 0x0001dec1,0x000e488c,0x00031114,0x00000000, -/* 003B */ 0x0004f5c2,0x00000000,0x0003640a,0x00000000, -/* 003D */ 0x00000000,0x000e5084,0x00000000,0x000eb844, -/* 003F */ 0x00007001,0x00000000,0x00000734,0x00001000, -/* 0041 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4, -/* SPDIFITASK */ -/* 0043 */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x000d5384, -/* 0045 */ 0x0007e48a,0x00000000,0x00067718,0x00001000, -/* 0047 */ 0x0007a418,0x00001000,0x0007221a,0x00000000, -/* 0049 */ 0x0005d402,0x00014500,0x000b8630,0x00001002, -/* 004B */ 0x00004418,0x00001780,0x000e243d,0x000d394a, -/* 004D */ 0x00049705,0x00000000,0x0007d530,0x000b4240, -/* 004F */ 0x000ac0f2,0x00001002,0x00014414,0x00000000, -/* 0051 */ 0x00004c90,0x00001000,0x0005d705,0x00000000, -/* 0053 */ 0x00004f25,0x00098240,0x00004725,0x00000000, -/* 0055 */ 0x0000e48a,0x00000000,0x00027295,0x0009c2c0, -/* 0057 */ 0x0007df25,0x00000000,0x000ac030,0x00001003, -/* 0059 */ 0x0005f718,0x000fe798,0x00029314,0x000bcb80, -/* 005B */ 0x00000930,0x000b0e00,0x0004f5c0,0x000de204, -/* 005D */ 0x000884a0,0x00001003,0x0007cf25,0x000e3560, -/* 005F */ 0x00049118,0x00000000,0x00049118,0x000d888a, -/* 0061 */ 0x0007dd02,0x000c6efa,0x0000c434,0x00030040, -/* 0063 */ 0x000fda82,0x000c2312,0x000fdc0e,0x00001001, -/* 0065 */ 0x00083402,0x000c2b92,0x000706b0,0x00001003, -/* 0067 */ 0x00075a82,0x00000000,0x0000d625,0x000b0940, -/* 0069 */ 0x0000840e,0x00001002,0x0000aabc,0x000c511e, -/* 006B */ 0x00078730,0x00001003,0x0000aaf4,0x000e910a, -/* 006D */ 0x0004628a,0x00000000,0x00006aca,0x00000000, -/* 006F */ 0x00000930,0x00000000,0x0004f5c0,0x00069c80, -/* 0071 */ 0x00046ac0,0x00000000,0x0003c40a,0x000fc898, -/* 0073 */ 0x00049118,0x00090e00,0x0006c10a,0x00000000, -/* 0075 */ 0x00000000,0x000e5084,0x00000000,0x000eb844, -/* 0077 */ 0x00007001,0x00000000,0x00000734,0x00001000, -/* 0079 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4, -/* SPDIFOTASK */ -/* 007B */ 0x0006a108,0x000c0000,0x0004f4c0,0x000c3245, -/* 007D */ 0x0000a418,0x00001000,0x0003a20a,0x00000000, -/* 007F */ 0x00004418,0x00001380,0x000e243d,0x000d394a, -/* 0081 */ 0x000c9705,0x000def92,0x0008c030,0x00001004, -/* 0083 */ 0x0005f718,0x000fe798,0x00000000,0x000c0000, -/* 0085 */ 0x00005725,0x00000000,0x000704a0,0x00001004, -/* 0087 */ 0x00029314,0x000b4780,0x0003cf25,0x000b8600, -/* 0089 */ 0x00000000,0x00000000,0x00000000,0x000c0000, -/* 008B */ 0x00000000,0x00042c80,0x0001dec1,0x000e488c, -/* 008D */ 0x00031114,0x00000000,0x0004f5c2,0x00000000, -/* 008F */ 0x0004a918,0x00098600,0x0006c28a,0x00000000, -/* 0091 */ 0x00000000,0x000e5084,0x00000000,0x000eb844, -/* 0093 */ 0x00007001,0x00000000,0x00000734,0x00001000, -/* 0095 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4, -/* ASYNCHFGTXCODE */ -/* 0097 */ 0x0002a880,0x000b4e40,0x00042214,0x000e5548, -/* 0099 */ 0x000542bf,0x00000000,0x00000000,0x000481c0, -/* 009B */ 0x00000000,0x00000000,0x00000000,0x00000030, -/* 009D */ 0x0000072d,0x000fbf8a,0x00077f94,0x000ea7df, -/* 009F */ 0x0002ac95,0x000d3145,0x00002731,0x00001400, -/* 00A1 */ 0x00006288,0x000c71c4,0x00014108,0x000e6044, -/* 00A3 */ 0x00035408,0x00000000,0x00025418,0x000a0ec0, -/* 00A5 */ 0x0001443d,0x000ca21e,0x00046595,0x000d730c, -/* 00A7 */ 0x0006538e,0x00000000,0x00064630,0x00001005, -/* 00A9 */ 0x000e7b0e,0x000df782,0x000746b0,0x00001005, -/* 00AB */ 0x00036f05,0x000c0000,0x00043695,0x000d598c, -/* 00AD */ 0x0005331a,0x000f2185,0x00000000,0x00000000, -/* 00AF */ 0x000007ae,0x000bdb00,0x00040630,0x00001400, -/* 00B1 */ 0x0005e708,0x000c0000,0x0007ef30,0x000b1c00, -/* 00B3 */ 0x000d86a0,0x00001005,0x00066408,0x000c0000, -/* 00B5 */ 0x00000000,0x00000000,0x00021843,0x00000000, -/* 00B7 */ 0x00000cac,0x00062c00,0x00001dac,0x00063400, -/* 00B9 */ 0x00002cac,0x0006cc80,0x000db943,0x000e5ca1, -/* 00BB */ 0x00000000,0x00000000,0x0006680a,0x000f3205, -/* 00BD */ 0x00042730,0x00001400, -/* ASYNCHFGRXCODE */ -/* 00BE */ 0x00014108,0x000f2204,0x00025418,0x000a2ec0, -/* 00C0 */ 0x00015dbd,0x00038100,0x00015dbc,0x00000000, -/* 00C2 */ 0x0005e415,0x00034880,0x0001258a,0x000d730c, -/* 00C4 */ 0x0006538e,0x000baa40,0x00060630,0x00001006, -/* 00C6 */ 0x00067b0e,0x000ac380,0x0003ef05,0x00000000, -/* 00C8 */ 0x0000f734,0x0001c300,0x000586b0,0x00001400, -/* 00CA */ 0x000b6f05,0x000c3a00,0x00048f05,0x00000000, -/* 00CC */ 0x0005b695,0x0008c380,0x0002058e,0x00000000, -/* 00CE */ 0x000500b0,0x00001400,0x0002b318,0x000e998d, -/* 00D0 */ 0x0006430a,0x00000000,0x00000000,0x000ef384, -/* 00D2 */ 0x00004725,0x000c0000,0x00000000,0x000f3204, -/* 00D4 */ 0x00004f25,0x000c0000,0x00080000,0x000e5ca1, -/* 00D6 */ 0x000cb943,0x000e5ca1,0x0004b943,0x00000000, -/* 00D8 */ 0x00040730,0x00001400,0x000cb943,0x000e5ca1, -/* 00DA */ 0x0004b943,0x00000000 -}; -/* #CODE_END */ - -static struct dsp_segment_desc cwcasync_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x000001b6, cwcasync_code }, -}; - -static struct dsp_module_desc cwcasync_module = { - "cwcasync", - { - 32, - cwcasync_symbols - }, - 1, - cwcasync_segments, -}; - -#endif /* __HEADER_cwcasync_H__ */ diff --git a/sound/pci/cs46xx/imgs/cwcbinhack.h b/sound/pci/cs46xx/imgs/cwcbinhack.h deleted file mode 100644 index f4d93689cd49..000000000000 --- a/sound/pci/cs46xx/imgs/cwcbinhack.h +++ /dev/null @@ -1,48 +0,0 @@ -/* generated by Benny - MODIFY ON YOUR OWN RISK */ - -#ifndef __HEADER_cwcbinhack_H__ -#define __HEADER_cwcbinhack_H__ - -static struct dsp_symbol_entry cwcbinhack_symbols[] = { - { 0x02c8, "OVERLAYBEGINADDRESS",0x00 }, - { 0x02c8, "MAGICSNOOPTASK",0x03 }, - { 0x0308, "#CODE_END",0x00 }, -}; /* cwcbinhack symbols */ - -static u32 cwcbinhack_code[] = { - /* 0x02c8 */ - 0x0007bfb0,0x000bc240,0x00000c2e,0x000c6084, /* 1 */ - 0x000b8630,0x00001016,0x00006408,0x000efb84, /* 2 */ - 0x00016008,0x00000000,0x0001c088,0x000c0000, /* 3 */ - 0x000fc908,0x000e3392,0x0005f488,0x000efb84, /* 4 */ - 0x0001d402,0x000b2e00,0x0003d418,0x00001000, /* 5 */ - 0x0008d574,0x000c4293,0x00065625,0x000ea30e, /* 6 */ - 0x00096c01,0x000c6f92,0x0001a58a,0x000c6085, /* 7 */ - 0x00002f43,0x00000000,0x000e03a0,0x00001016, /* 8 */ - 0x0005e608,0x000c0000,0x00000000,0x00000000, /* 9 */ - 0x000ca108,0x000dcca1,0x00003bac,0x000c3205, /* 10 */ - 0x00073843,0x00000000,0x00010730,0x00001017, /* 11 */ - 0x0001600a,0x000c0000,0x00057488,0x00000000, /* 12 */ - 0x00000000,0x000e5084,0x00000000,0x000eba44, /* 13 */ - 0x00087401,0x000e4782,0x00000734,0x00001000, /* 14 */ - 0x00010705,0x000a6880,0x00006a88,0x000c75c4, /* 15 */ - 0x00000000,0x00000000,0x00000000,0x00000000, /* 16 */ -}; -/* #CODE_END */ - -static struct dsp_segment_desc cwcbinhack_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 64, cwcbinhack_code }, -}; - -static struct dsp_module_desc cwcbinhack_module = { - "cwcbinhack", - { - 3, - cwcbinhack_symbols - }, - 1, - cwcbinhack_segments, -}; - -#endif /* __HEADER_cwcbinhack_H__ */ diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp deleted file mode 100644 index a65e1193c89a..000000000000 --- a/sound/pci/cs46xx/imgs/cwcdma.asp +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright(c) by Benny Sjostrand (benny@hostmobility.com) -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// - - -// -// This code runs inside the DSP (cs4610, cs4612, cs4624, or cs4630), -// to compile it you need a tool named SPASM 3.0 and DSP code owned by -// Cirrus Logic(R). The SPASM program will generate a object file (cwcdma.osp), -// the "ospparser" tool will genereate the cwcdma.h file it's included from -// the cs46xx_lib.c file. -// -// -// The purpose of this code is very simple: make it possible to tranfser -// the samples 'as they are' with no alteration from a PCMreader -// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF. -// SRC (source rate converters) task always alters the samples in somehow, -// however it's from 48khz -> 48khz. -// The alterations are not audible, but AC3 wont work. -// -// ... -// | -// +---------------+ -// | AsynchFGTxSCB | -// +---------------+ -// | -// subListPtr -// | -// +--------------+ -// | DMAReader | -// +--------------+ -// | -// subListPtr -// | -// +-------------+ -// | PCMReader | -// +-------------+ -// (DMA from host) -// - -struct dmaSCB - { - long dma_reserved1[3]; - - short dma_reserved2:dma_outBufPtr; - - short dma_unused1:dma_unused2; - - long dma_reserved3[4]; - - short dma_subListPtr:dma_nextSCB; - short dma_SPBptr:dma_entryPoint; - - long dma_strmRsConfig; - long dma_strmBufPtr; - - long dma_reserved4; - - VolumeControl s2m_volume; - }; - -#export DMAReader -void DMAReader() -{ - execChild(); - r2 = r0->dma_subListPtr; - r1 = r0->nextSCB; - - rsConfig01 = r2->strmRsConfig; - // Load rsConfig for input buffer - - rsDMA01 = r2->basicReq.daw, , tb = Z(0 - rf); - // Load rsDMA in case input buffer is a DMA buffer Test to see if there is any data to transfer - - if (tb) goto execSibling_2ind1 after { - r5 = rf + (-1); - r6 = r1->dma_entryPoint; // r6 = entry point of sibling task - r1 = r1->dma_SPBptr, // r1 = pointer to sibling task's SPB - , ind = r6; // Load entry point of sibling task - } - - rsConfig23 = r0->dma_strmRsConfig; - // Load rsConfig for output buffer (never a DMA buffer) - - r4 = r0->dma_outBufPtr; - - rsa0 = r2->strmBufPtr; - // rsa0 = input buffer pointer - - for (i = r5; i >= 0; --i) - after { - rsa2 = r4; - // rsa2 = output buffer pointer - - nop; - nop; - } - //***************************** - // TODO: cycles to this point * - //***************************** - { - acc0 = (rsd0 = *rsa0++1); - // get sample - - nop; // Those "nop"'s are really uggly, but there's - nop; // something with DSP's pipelines which I don't - nop; // understand, resulting this code to fail without - // having those "nop"'s (Benny) - - rsa0?reqDMA = r2; - // Trigger DMA transfer on input stream, - // if needed to replenish input buffer - - nop; - // Yet another magic "nop" to make stuff work - - ,,r98 = acc0 $+>> 0; - // store sample in ALU - - nop; - // latency on load register. - // (this one is understandable) - - *rsa2++1 = r98; - // store sample in output buffer - - nop; // The same story - nop; // as above again ... - nop; - } - // TODO: cycles per loop iteration - - r2->strmBufPtr = rsa0,, ; - // Update the modified buffer pointers - - r4 = rsa2; - // Load output pointer position into r4 - - r2 = r0->nextSCB; - // Sibling task - - goto execSibling_2ind1 // takes 6 cycles - after { - r98 = r2->thisSPB:entryPoint; - // Load child routine entry and data address - - r1 = r9; - // r9 is r2->thisSPB - - r0->dma_outBufPtr = r4,, - // Store updated output buffer pointer - - ind = r8; - // r8 is r2->entryPoint - } -} diff --git a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h deleted file mode 100644 index 7ff0d4587161..000000000000 --- a/sound/pci/cs46xx/imgs/cwcdma.h +++ /dev/null @@ -1,68 +0,0 @@ -/* generated from cwcdma.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwcdma_H__ -#define __HEADER_cwcdma_H__ - -static struct dsp_symbol_entry cwcdma_symbols[] = { - { 0x8000, "EXECCHILD",0x03 }, - { 0x8001, "EXECCHILD_98",0x03 }, - { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, - { 0x8008, "EXECSIBLING",0x03 }, - { 0x800a, "EXECSIBLING_298",0x03 }, - { 0x800b, "EXECSIBLING_2IND1",0x03 }, - { 0x8010, "TIMINGMASTER",0x03 }, - { 0x804f, "S16_CODECINPUTTASK",0x03 }, - { 0x805e, "PCMSERIALINPUTTASK",0x03 }, - { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, - { 0x809a, "S16_MIX",0x03 }, - { 0x80bb, "S16_UPSRC",0x03 }, - { 0x813b, "MIX3_EXP",0x03 }, - { 0x8164, "DECIMATEBYPOW2",0x03 }, - { 0x8197, "VARIDECIMATE",0x03 }, - { 0x81f2, "_3DINPUTTASK",0x03 }, - { 0x820a, "_3DPRLGCINPTASK",0x03 }, - { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, - { 0x8242, "_3DOUTPUTTASK",0x03 }, - { 0x82c4, "HRTF_MORPH_TASK",0x03 }, - { 0x82c6, "WAIT4DATA",0x03 }, - { 0x82fa, "PROLOGIC",0x03 }, - { 0x8496, "DECORRELATOR",0x03 }, - { 0x84a4, "STEREO2MONO",0x03 }, - { 0x0000, "OVERLAYBEGINADDRESS",0x00 }, - { 0x0000, "DMAREADER",0x03 }, - { 0x0018, "#CODE_END",0x00 }, -}; /* cwcdma symbols */ - -static u32 cwcdma_code[] = { -/* OVERLAYBEGINADDRESS */ -/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044, -/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300, -/* 0004 */ 0x00058630,0x00001400,0x0007afb0,0x000e9584, -/* 0006 */ 0x00007301,0x000a9840,0x0005e708,0x000cd104, -/* 0008 */ 0x00067008,0x00000000,0x000902a0,0x00001000, -/* 000A */ 0x00012a01,0x000c0000,0x00000000,0x00000000, -/* 000C */ 0x00021843,0x000c0000,0x00000000,0x000c0000, -/* 000E */ 0x0000e101,0x000c0000,0x00000cac,0x00000000, -/* 0010 */ 0x00080000,0x000e5ca1,0x00000000,0x000c0000, -/* 0012 */ 0x00000000,0x00000000,0x00000000,0x00092c00, -/* 0014 */ 0x000122c1,0x000e5084,0x00058730,0x00001400, -/* 0016 */ 0x000d7488,0x000e4782,0x00007401,0x0001c100 -}; - -/* #CODE_END */ - -static struct dsp_segment_desc cwcdma_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code }, -}; - -static struct dsp_module_desc cwcdma_module = { - "cwcdma", - { - 27, - cwcdma_symbols - }, - 1, - cwcdma_segments, -}; - -#endif /* __HEADER_cwcdma_H__ */ diff --git a/sound/pci/cs46xx/imgs/cwcsnoop.h b/sound/pci/cs46xx/imgs/cwcsnoop.h deleted file mode 100644 index 6929d0a5a3f3..000000000000 --- a/sound/pci/cs46xx/imgs/cwcsnoop.h +++ /dev/null @@ -1,46 +0,0 @@ -/* generated from cwcsnoop.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwcsnoop_H__ -#define __HEADER_cwcsnoop_H__ - -static struct dsp_symbol_entry cwcsnoop_symbols[] = { - { 0x0500, "OVERLAYBEGINADDRESS",0x00 }, - { 0x0500, "OUTPUTSNOOP",0x03 }, - { 0x051f, "#CODE_END",0x00 }, -}; /* cwcsnoop symbols */ - -static u32 cwcsnoop_code[] = { -/* 0000 */ 0x0007bfb0,0x000b4e40,0x0007c088,0x000c0617, -/* 0002 */ 0x00049705,0x00000000,0x00080630,0x00001028, -/* 0004 */ 0x00076408,0x000efb84,0x00066008,0x00000000, -/* 0006 */ 0x0007c908,0x000c0000,0x00046725,0x000efa44, -/* 0008 */ 0x0005f708,0x00000000,0x0001d402,0x000b2e00, -/* 000A */ 0x0003d418,0x00001000,0x0008d574,0x000c4293, -/* 000C */ 0x00065625,0x000ea30e,0x00096c01,0x000c6f92, -/* 000E */ 0x0006a58a,0x000f6085,0x00002f43,0x00000000, -/* 0010 */ 0x000a83a0,0x00001028,0x0005e608,0x000c0000, -/* 0012 */ 0x00000000,0x00000000,0x000ca108,0x000dcca1, -/* 0014 */ 0x00003bac,0x000fb205,0x00073843,0x00000000, -/* 0016 */ 0x000d8730,0x00001028,0x0006600a,0x000c0000, -/* 0018 */ 0x00057488,0x00000000,0x00000000,0x000e5084, -/* 001A */ 0x00000000,0x000eba44,0x00087401,0x000e4782, -/* 001C */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 001E */ 0x00006a88,0x000c75c4 -}; -/* #CODE_END */ - -static struct dsp_segment_desc cwcsnoop_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000003e, cwcsnoop_code }, -}; - -static struct dsp_module_desc cwcsnoop_module = { - "cwcsnoop", - { - 3, - cwcsnoop_symbols - }, - 1, - cwcsnoop_segments, -}; - -#endif /* __HEADER_cwcsnoop_H__ */ diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index 902bebd3b3fb..c0d2835344da 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -253,7 +253,7 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) static int snd_cs5535audio_free(struct cs5535audio *cs5535au) { synchronize_irq(cs5535au->irq); - pci_set_power_state(cs5535au->pci, 3); + pci_set_power_state(cs5535au->pci, PCI_D3hot); if (cs5535au->irq >= 0) free_irq(cs5535au->irq, cs5535au); diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index b5fa583a239a..eb86829529eb 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -435,6 +435,11 @@ atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm) return 0; position = src->ops->get_ca(src); + if (position < apcm->vm_block->addr) { + snd_printdd("ctxfi: bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", position, apcm->vm_block->addr, apcm->vm_block->size); + position = apcm->vm_block->addr; + } + size = apcm->vm_block->size; max_cisz = src->multi * src->rsc.msr; max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8); diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index b0e3d92c4656..772cc36f951d 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1422,7 +1422,7 @@ static void snd_es1968_free_dmabuf(struct es1968 *chip) if (! chip->dma.area) return; - snd_dma_reserve_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci)); + snd_dma_free_pages(&chip->dma); while ((p = chip->buf_list.next) != &chip->buf_list) { struct esm_memory *chunk = list_entry(p, struct esm_memory, list); list_del(p); @@ -1438,20 +1438,18 @@ snd_es1968_init_dmabuf(struct es1968 *chip) chip->dma.dev.type = SNDRV_DMA_TYPE_DEV; chip->dma.dev.dev = snd_dma_pci_data(chip->pci); - if (! snd_dma_get_reserved_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci))) { - err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - chip->total_bufsize, &chip->dma); - if (err < 0 || ! chip->dma.area) { - snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n", - chip->total_bufsize); - return -ENOMEM; - } - if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) { - snd_dma_free_pages(&chip->dma); - snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n"); - return -ENOMEM; - } + err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + chip->total_bufsize, &chip->dma); + if (err < 0 || ! chip->dma.area) { + snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n", + chip->total_bufsize); + return -ENOMEM; + } + if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) { + snd_dma_free_pages(&chip->dma); + snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n"); + return -ENOMEM; } INIT_LIST_HEAD(&chip->buf_list); diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 4cdd9ded4563..0e53634dbbd8 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -87,69 +87,54 @@ config SND_HDA_PATCH_LOADER This option turns on hwdep and reconfig features automatically. config SND_HDA_CODEC_REALTEK - bool "Build Realtek HD-audio codec support" - default y + tristate "Build Realtek HD-audio codec support" select SND_HDA_GENERIC help - Say Y here to include Realtek HD-audio codec support in + Say Y or M here to include Realtek HD-audio codec support in snd-hda-intel driver, such as ALC880. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-realtek. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_REALTEK=m config SND_HDA_CODEC_ANALOG - bool "Build Analog Device HD-audio codec support" - default y + tristate "Build Analog Device HD-audio codec support" select SND_HDA_GENERIC help - Say Y here to include Analog Device HD-audio codec support in + Say Y or M here to include Analog Device HD-audio codec support in snd-hda-intel driver, such as AD1986A. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-analog. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_ANALOG=m config SND_HDA_CODEC_SIGMATEL - bool "Build IDT/Sigmatel HD-audio codec support" - default y + tristate "Build IDT/Sigmatel HD-audio codec support" select SND_HDA_GENERIC help - Say Y here to include IDT (Sigmatel) HD-audio codec support in + Say Y or M here to include IDT (Sigmatel) HD-audio codec support in snd-hda-intel driver, such as STAC9200. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-idt. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_SIGMATEL=m config SND_HDA_CODEC_VIA - bool "Build VIA HD-audio codec support" - default y + tristate "Build VIA HD-audio codec support" select SND_HDA_GENERIC help - Say Y here to include VIA HD-audio codec support in + Say Y or M here to include VIA HD-audio codec support in snd-hda-intel driver, such as VT1708. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-via. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_VIA=m config SND_HDA_CODEC_HDMI - bool "Build HDMI/DisplayPort HD-audio codec support" - default y + tristate "Build HDMI/DisplayPort HD-audio codec support" help - Say Y here to include HDMI and DisplayPort HD-audio codec + Say Y or M here to include HDMI and DisplayPort HD-audio codec support in snd-hda-intel driver. This includes all AMD/ATI, Intel and Nvidia HDMI/DisplayPort codecs. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-hdmi. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_HDMI=m config SND_HDA_I915 bool @@ -157,55 +142,43 @@ config SND_HDA_I915 depends on DRM_I915 config SND_HDA_CODEC_CIRRUS - bool "Build Cirrus Logic codec support" - default y + tristate "Build Cirrus Logic codec support" select SND_HDA_GENERIC help - Say Y here to include Cirrus Logic codec support in + Say Y or M here to include Cirrus Logic codec support in snd-hda-intel driver, such as CS4206. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-cirrus. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CIRRUS=m config SND_HDA_CODEC_CONEXANT - bool "Build Conexant HD-audio codec support" - default y + tristate "Build Conexant HD-audio codec support" select SND_HDA_GENERIC help - Say Y here to include Conexant HD-audio codec support in + Say Y or M here to include Conexant HD-audio codec support in snd-hda-intel driver, such as CX20549. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-conexant. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CONEXANT=m config SND_HDA_CODEC_CA0110 - bool "Build Creative CA0110-IBG codec support" - default y + tristate "Build Creative CA0110-IBG codec support" select SND_HDA_GENERIC help - Say Y here to include Creative CA0110-IBG codec support in + Say Y or M here to include Creative CA0110-IBG codec support in snd-hda-intel driver, found on some Creative X-Fi cards. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-ca0110. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CA0110=m config SND_HDA_CODEC_CA0132 - bool "Build Creative CA0132 codec support" - default y + tristate "Build Creative CA0132 codec support" help - Say Y here to include Creative CA0132 codec support in + Say Y or M here to include Creative CA0132 codec support in snd-hda-intel driver. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-ca0132. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CA0132=m config SND_HDA_CODEC_CA0132_DSP bool "Support new DSP code for CA0132 codec" @@ -220,37 +193,33 @@ config SND_HDA_CODEC_CA0132_DSP (ctefx.bin). config SND_HDA_CODEC_CMEDIA - bool "Build C-Media HD-audio codec support" - default y + tristate "Build C-Media HD-audio codec support" select SND_HDA_GENERIC help - Say Y here to include C-Media HD-audio codec support in + Say Y or M here to include C-Media HD-audio codec support in snd-hda-intel driver, such as CMI9880. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-cmedia. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CMEDIA=m config SND_HDA_CODEC_SI3054 - bool "Build Silicon Labs 3054 HD-modem codec support" - default y + tristate "Build Silicon Labs 3054 HD-modem codec support" help - Say Y here to include Silicon Labs 3054 HD-modem codec + Say Y or M here to include Silicon Labs 3054 HD-modem codec (and compatibles) support in snd-hda-intel driver. - When the HD-audio driver is built as a module, the codec - support code is also built as another module, - snd-hda-codec-si3054. - This module is automatically loaded at probing. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_CODEC_SI3054=m config SND_HDA_GENERIC - bool "Enable generic HD-audio codec parser" - default y + tristate "Enable generic HD-audio codec parser" help - Say Y here to enable the generic HD-audio codec parser + Say Y or M here to enable the generic HD-audio codec parser in snd-hda-intel driver. +comment "Set to Y if you want auto-loading the codec driver" + depends on SND_HDA_INTEL=y && SND_HDA_GENERIC=m + config SND_HDA_POWER_SAVE_DEFAULT int "Default time-out for HD-audio power-save mode" depends on PM diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index c091438286a3..1fcb118e480a 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o snd-hda-codec-y := hda_codec.o hda_jack.o hda_auto_parser.o -snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o @@ -12,6 +11,7 @@ snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o CFLAGS_hda_codec.o := -I$(src) CFLAGS_hda_intel.o := -I$(src) +snd-hda-codec-generic-objs := hda_generic.o snd-hda-codec-realtek-objs := patch_realtek.o snd-hda-codec-cmedia-objs := patch_cmedia.o snd-hda-codec-analog-objs := patch_analog.o @@ -27,40 +27,19 @@ snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o # common driver obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o -# codec drivers (note: CONFIG_SND_HDA_CODEC_XXX are booleans) -ifdef CONFIG_SND_HDA_CODEC_REALTEK -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-realtek.o -endif -ifdef CONFIG_SND_HDA_CODEC_CMEDIA -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cmedia.o -endif -ifdef CONFIG_SND_HDA_CODEC_ANALOG -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-analog.o -endif -ifdef CONFIG_SND_HDA_CODEC_SIGMATEL -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-idt.o -endif -ifdef CONFIG_SND_HDA_CODEC_SI3054 -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o -endif -ifdef CONFIG_SND_HDA_CODEC_CIRRUS -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o -endif -ifdef CONFIG_SND_HDA_CODEC_CA0110 -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o -endif -ifdef CONFIG_SND_HDA_CODEC_CA0132 -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0132.o -endif -ifdef CONFIG_SND_HDA_CODEC_CONEXANT -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o -endif -ifdef CONFIG_SND_HDA_CODEC_VIA -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o -endif -ifdef CONFIG_SND_HDA_CODEC_HDMI -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-hdmi.o -endif +# codec drivers +obj-$(CONFIG_SND_HDA_GENERIC) += snd-hda-codec-generic.o +obj-$(CONFIG_SND_HDA_CODEC_REALTEK) += snd-hda-codec-realtek.o +obj-$(CONFIG_SND_HDA_CODEC_CMEDIA) += snd-hda-codec-cmedia.o +obj-$(CONFIG_SND_HDA_CODEC_ANALOG) += snd-hda-codec-analog.o +obj-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += snd-hda-codec-idt.o +obj-$(CONFIG_SND_HDA_CODEC_SI3054) += snd-hda-codec-si3054.o +obj-$(CONFIG_SND_HDA_CODEC_CIRRUS) += snd-hda-codec-cirrus.o +obj-$(CONFIG_SND_HDA_CODEC_CA0110) += snd-hda-codec-ca0110.o +obj-$(CONFIG_SND_HDA_CODEC_CA0132) += snd-hda-codec-ca0132.o +obj-$(CONFIG_SND_HDA_CODEC_CONEXANT) += snd-hda-codec-conexant.o +obj-$(CONFIG_SND_HDA_CODEC_VIA) += snd-hda-codec-via.o +obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o # this must be the last entry after codec drivers; # otherwise the codec patches won't be hooked before the PCI probe diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 853c6a69e29e..47ad31c6aa70 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c @@ -414,7 +414,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, return 0; } -EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg); +EXPORT_SYMBOL_GPL(snd_hda_parse_pin_defcfg); int snd_hda_get_input_pin_attr(unsigned int def_conf) { @@ -435,7 +435,7 @@ int snd_hda_get_input_pin_attr(unsigned int def_conf) return INPUT_PIN_ATTR_FRONT; return INPUT_PIN_ATTR_NORMAL; } -EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); +EXPORT_SYMBOL_GPL(snd_hda_get_input_pin_attr); /** * hda_get_input_pin_label - Give a label for the given input pin @@ -547,7 +547,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec, cfg->inputs[input].pin, has_multiple_pins); } -EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); +EXPORT_SYMBOL_GPL(hda_get_autocfg_input_label); /* return the position of NID in the list, or -1 if not found */ static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) @@ -721,7 +721,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, strlcpy(label, name, maxlen); return 1; } -EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); +EXPORT_SYMBOL_GPL(snd_hda_get_pin_label); int snd_hda_add_verbs(struct hda_codec *codec, const struct hda_verb *list) @@ -733,7 +733,7 @@ int snd_hda_add_verbs(struct hda_codec *codec, *v = list; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_add_verbs); +EXPORT_SYMBOL_GPL(snd_hda_add_verbs); void snd_hda_apply_verbs(struct hda_codec *codec) { @@ -743,7 +743,7 @@ void snd_hda_apply_verbs(struct hda_codec *codec) snd_hda_sequence_write(codec, *v); } } -EXPORT_SYMBOL_HDA(snd_hda_apply_verbs); +EXPORT_SYMBOL_GPL(snd_hda_apply_verbs); void snd_hda_apply_pincfgs(struct hda_codec *codec, const struct hda_pintbl *cfg) @@ -751,7 +751,7 @@ void snd_hda_apply_pincfgs(struct hda_codec *codec, for (; cfg->nid; cfg++) snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); } -EXPORT_SYMBOL_HDA(snd_hda_apply_pincfgs); +EXPORT_SYMBOL_GPL(snd_hda_apply_pincfgs); static void set_pin_targets(struct hda_codec *codec, const struct hda_pintbl *cfg) @@ -822,7 +822,7 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action) if (codec->fixup_list) apply_fixup(codec, codec->fixup_id, action, 0); } -EXPORT_SYMBOL_HDA(snd_hda_apply_fixup); +EXPORT_SYMBOL_GPL(snd_hda_apply_fixup); void snd_hda_pick_fixup(struct hda_codec *codec, const struct hda_model_fixup *models, @@ -880,4 +880,4 @@ void snd_hda_pick_fixup(struct hda_codec *codec, codec->fixup_name = name; } } -EXPORT_SYMBOL_HDA(snd_hda_pick_fixup); +EXPORT_SYMBOL_GPL(snd_hda_pick_fixup); diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 98bce9830be0..0589b39cda6e 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -194,7 +194,7 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device); +EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device); int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) { @@ -231,7 +231,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) return 0; } -EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device); +EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device); void snd_hda_detach_beep_device(struct hda_codec *codec) { @@ -243,7 +243,7 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) kfree(beep); } } -EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); +EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device); static bool ctl_has_mute(struct snd_kcontrol *kcontrol) { @@ -265,7 +265,7 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, } return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get_beep); int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -288,4 +288,4 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, return 0; return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put_beep); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 69178c4f4113..ec4536c8d8d4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "hda_codec.h" #include @@ -83,7 +84,7 @@ int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset) mutex_unlock(&preset_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_add_codec_preset); +EXPORT_SYMBOL_GPL(snd_hda_add_codec_preset); int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) { @@ -92,23 +93,31 @@ int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset) mutex_unlock(&preset_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset); +EXPORT_SYMBOL_GPL(snd_hda_delete_codec_preset); #ifdef CONFIG_PM #define codec_in_pm(codec) ((codec)->in_pm) static void hda_power_work(struct work_struct *work); static void hda_keep_power_on(struct hda_codec *codec); #define hda_codec_is_power_on(codec) ((codec)->power_on) -static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up) + +static void hda_call_pm_notify(struct hda_codec *codec, bool power_up) { + struct hda_bus *bus = codec->bus; + + if ((power_up && codec->pm_up_notified) || + (!power_up && !codec->pm_up_notified)) + return; if (bus->ops.pm_notify) bus->ops.pm_notify(bus, power_up); + codec->pm_up_notified = power_up; } + #else #define codec_in_pm(codec) 0 static inline void hda_keep_power_on(struct hda_codec *codec) {} #define hda_codec_is_power_on(codec) 1 -#define hda_call_pm_notify(bus, state) {} +#define hda_call_pm_notify(codec, state) {} #endif /** @@ -143,7 +152,7 @@ const char *snd_hda_get_jack_location(u32 cfg) } return "UNKNOWN"; } -EXPORT_SYMBOL_HDA(snd_hda_get_jack_location); +EXPORT_SYMBOL_GPL(snd_hda_get_jack_location); /** * snd_hda_get_jack_connectivity - Give a connectivity string of the jack @@ -158,7 +167,7 @@ const char *snd_hda_get_jack_connectivity(u32 cfg) return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3]; } -EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity); +EXPORT_SYMBOL_GPL(snd_hda_get_jack_connectivity); /** * snd_hda_get_jack_type - Give a type string of the jack @@ -179,7 +188,7 @@ const char *snd_hda_get_jack_type(u32 cfg) return jack_types[(cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT]; } -EXPORT_SYMBOL_HDA(snd_hda_get_jack_type); +EXPORT_SYMBOL_GPL(snd_hda_get_jack_type); /* * Compose a 32bit command word to be sent to the HD-audio controller @@ -275,7 +284,7 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, return -1; return res; } -EXPORT_SYMBOL_HDA(snd_hda_codec_read); +EXPORT_SYMBOL_GPL(snd_hda_codec_read); /** * snd_hda_codec_write - send a single command without waiting for response @@ -297,7 +306,7 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags, return codec_exec_verb(codec, cmd, flags, codec->bus->sync_write ? &res : NULL); } -EXPORT_SYMBOL_HDA(snd_hda_codec_write); +EXPORT_SYMBOL_GPL(snd_hda_codec_write); /** * snd_hda_sequence_write - sequence writes @@ -312,7 +321,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) for (; seq->nid; seq++) snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); } -EXPORT_SYMBOL_HDA(snd_hda_sequence_write); +EXPORT_SYMBOL_GPL(snd_hda_sequence_write); /** * snd_hda_get_sub_nodes - get the range of sub nodes @@ -334,7 +343,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, *start_id = (parm >> 16) & 0x7fff; return (int)(parm & 0x7fff); } -EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); +EXPORT_SYMBOL_GPL(snd_hda_get_sub_nodes); /* connection list element */ struct hda_conn_list { @@ -444,7 +453,7 @@ int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, added = true; } } -EXPORT_SYMBOL_HDA(snd_hda_get_conn_list); +EXPORT_SYMBOL_GPL(snd_hda_get_conn_list); /** * snd_hda_get_connections - copy connection list @@ -476,7 +485,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, return len; } -EXPORT_SYMBOL_HDA(snd_hda_get_connections); +EXPORT_SYMBOL_GPL(snd_hda_get_connections); /* return CONNLIST_LEN parameter of the given widget */ static unsigned int get_num_conns(struct hda_codec *codec, hda_nid_t nid) @@ -625,7 +634,7 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, return add_conn_list(codec, nid, len, list); } -EXPORT_SYMBOL_HDA(snd_hda_override_conn_list); +EXPORT_SYMBOL_GPL(snd_hda_override_conn_list); /** * snd_hda_get_conn_index - get the connection index of the given NID @@ -664,7 +673,7 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, } return -1; } -EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); +EXPORT_SYMBOL_GPL(snd_hda_get_conn_index); /* return DEVLIST_LEN parameter of the given widget */ @@ -760,7 +769,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) return 0; } -EXPORT_SYMBOL_HDA(snd_hda_queue_unsol_event); +EXPORT_SYMBOL_GPL(snd_hda_queue_unsol_event); /* * process queued unsolicited events @@ -831,6 +840,7 @@ static int snd_hda_bus_free(struct hda_bus *bus) bus->ops.private_free(bus); if (bus->workq) destroy_workqueue(bus->workq); + kfree(bus); return 0; } @@ -920,7 +930,7 @@ int snd_hda_bus_new(struct snd_card *card, *busp = bus; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_bus_new); +EXPORT_SYMBOL_GPL(snd_hda_bus_new); #ifdef CONFIG_SND_HDA_GENERIC #define is_generic_config(codec) \ @@ -945,9 +955,6 @@ find_codec_preset(struct hda_codec *codec) const struct hda_codec_preset *preset; unsigned int mod_requested = 0; - if (is_generic_config(codec)) - return NULL; /* use the generic parser */ - again: mutex_lock(&preset_mutex); list_for_each_entry(tbl, &hda_preset_tables, list) { @@ -1163,7 +1170,7 @@ int snd_hda_codec_set_pincfg(struct hda_codec *codec, { return snd_hda_add_pincfg(codec, &codec->driver_pins, nid, cfg); } -EXPORT_SYMBOL_HDA(snd_hda_codec_set_pincfg); +EXPORT_SYMBOL_GPL(snd_hda_codec_set_pincfg); /** * snd_hda_codec_get_pincfg - Obtain a pin-default configuration @@ -1198,7 +1205,7 @@ unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid) return pin->cfg; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_codec_get_pincfg); +EXPORT_SYMBOL_GPL(snd_hda_codec_get_pincfg); /* remember the current pinctl target value */ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, @@ -1212,7 +1219,7 @@ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid, pin->target = val; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_codec_set_pin_target); +EXPORT_SYMBOL_GPL(snd_hda_codec_set_pin_target); /* return the current pinctl target value */ int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid) @@ -1224,7 +1231,7 @@ int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid) return 0; return pin->target; } -EXPORT_SYMBOL_HDA(snd_hda_codec_get_pin_target); +EXPORT_SYMBOL_GPL(snd_hda_codec_get_pin_target); /** * snd_hda_shutup_pins - Shut up all pins @@ -1249,7 +1256,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec) } codec->pins_shutup = 1; } -EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); +EXPORT_SYMBOL_GPL(snd_hda_shutup_pins); #ifdef CONFIG_PM /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ @@ -1329,6 +1336,28 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) return p; } +/* + * Dynamic symbol binding for the codec parsers + */ +#ifdef MODULE +#define load_parser_sym(sym) ((int (*)(struct hda_codec *))symbol_request(sym)) +#define unload_parser_addr(addr) symbol_put_addr(addr) +#else +#define load_parser_sym(sym) (sym) +#define unload_parser_addr(addr) do {} while (0) +#endif + +#define load_parser(codec, sym) \ + ((codec)->parser = load_parser_sym(sym)) + +static void unload_parser(struct hda_codec *codec) +{ + if (codec->parser) { + unload_parser_addr(codec->parser); + codec->parser = NULL; + } +} + /* * codec destructor */ @@ -1352,10 +1381,8 @@ static void snd_hda_codec_free(struct hda_codec *codec) codec->bus->caddr_tbl[codec->addr] = NULL; if (codec->patch_ops.free) codec->patch_ops.free(codec); -#ifdef CONFIG_PM - if (!codec->pm_down_notified) /* cancel leftover refcounts */ - hda_call_pm_notify(codec->bus, false); -#endif + hda_call_pm_notify(codec, false); /* cancel leftover refcounts */ + unload_parser(codec); module_put(codec->owner); free_hda_cache(&codec->amp_cache); free_hda_cache(&codec->cmd_cache); @@ -1363,6 +1390,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) kfree(codec->chip_name); kfree(codec->modelname); kfree(codec->wcaps); + codec->bus->num_codecs--; kfree(codec); } @@ -1424,6 +1452,7 @@ int snd_hda_codec_new(struct hda_bus *bus, INIT_LIST_HEAD(&codec->conn_list); INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); + codec->depop_delay = -1; #ifdef CONFIG_PM spin_lock_init(&codec->power_lock); @@ -1433,7 +1462,6 @@ int snd_hda_codec_new(struct hda_bus *bus, * phase. */ hda_keep_power_on(codec); - hda_call_pm_notify(bus, true); #endif if (codec->bus->modelname) { @@ -1445,6 +1473,8 @@ int snd_hda_codec_new(struct hda_bus *bus, } list_add_tail(&codec->list, &bus->codec_list); + bus->num_codecs++; + bus->caddr_tbl[codec_addr] = codec; codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, @@ -1486,11 +1516,14 @@ int snd_hda_codec_new(struct hda_bus *bus, #ifdef CONFIG_PM codec->d3_stop_clk = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_CLKSTOP); - if (!codec->d3_stop_clk) - bus->power_keep_link_on = 1; #endif codec->epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS); +#ifdef CONFIG_PM + if (!codec->d3_stop_clk || !codec->epss) + bus->power_keep_link_on = 1; +#endif + /* power-up all before initialization */ hda_set_power_state(codec, AC_PWRST_D0); @@ -1511,7 +1544,7 @@ int snd_hda_codec_new(struct hda_bus *bus, snd_hda_codec_free(codec); return err; } -EXPORT_SYMBOL_HDA(snd_hda_codec_new); +EXPORT_SYMBOL_GPL(snd_hda_codec_new); int snd_hda_codec_update_widgets(struct hda_codec *codec) { @@ -1534,9 +1567,34 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec) return err; } -EXPORT_SYMBOL_HDA(snd_hda_codec_update_widgets); +EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets); +#ifdef CONFIG_SND_HDA_CODEC_HDMI +/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */ +static bool is_likely_hdmi_codec(struct hda_codec *codec) +{ + hda_nid_t nid = codec->start_nid; + int i; + + for (i = 0; i < codec->num_nodes; i++, nid++) { + unsigned int wcaps = get_wcaps(codec, nid); + switch (get_wcaps_type(wcaps)) { + case AC_WID_AUD_IN: + return false; /* HDMI parser supports only HDMI out */ + case AC_WID_AUD_OUT: + if (!(wcaps & AC_WCAP_DIGITAL)) + return false; + break; + } + } + return true; +} +#else +/* no HDMI codec parser support */ +#define is_likely_hdmi_codec(codec) false +#endif /* CONFIG_SND_HDA_CODEC_HDMI */ + /** * snd_hda_codec_configure - (Re-)configure the HD-audio codec * @codec: the HDA codec @@ -1548,6 +1606,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_update_widgets); */ int snd_hda_codec_configure(struct hda_codec *codec) { + int (*patch)(struct hda_codec *) = NULL; int err; codec->preset = find_codec_preset(codec); @@ -1557,31 +1616,42 @@ int snd_hda_codec_configure(struct hda_codec *codec) return err; } - if (is_generic_config(codec)) { - err = snd_hda_parse_generic_codec(codec); - goto patched; - } - if (codec->preset && codec->preset->patch) { - err = codec->preset->patch(codec); - goto patched; + if (!is_generic_config(codec) && codec->preset) + patch = codec->preset->patch; + if (!patch) { + unload_parser(codec); /* to be sure */ + if (is_likely_hdmi_codec(codec)) + patch = load_parser(codec, snd_hda_parse_hdmi_codec); +#ifdef CONFIG_SND_HDA_GENERIC + if (!patch) + patch = load_parser(codec, snd_hda_parse_generic_codec); +#endif + if (!patch) { + printk(KERN_ERR "hda-codec: No codec parser is available\n"); + return -ENODEV; + } } - /* call the default parser */ - err = snd_hda_parse_generic_codec(codec); - if (err < 0) - printk(KERN_ERR "hda-codec: No codec parser is available\n"); + err = patch(codec); + if (err < 0) { + unload_parser(codec); + return err; + } - patched: - if (!err && codec->patch_ops.unsol_event) + if (codec->patch_ops.unsol_event) { err = init_unsol_queue(codec->bus); + if (err < 0) + return err; + } + /* audio codec should override the mixer name */ - if (!err && (codec->afg || !*codec->bus->card->mixername)) + if (codec->afg || !*codec->bus->card->mixername) snprintf(codec->bus->card->mixername, sizeof(codec->bus->card->mixername), "%s %s", codec->vendor_name, codec->chip_name); - return err; + return 0; } -EXPORT_SYMBOL_HDA(snd_hda_codec_configure); +EXPORT_SYMBOL_GPL(snd_hda_codec_configure); /* update the stream-id if changed */ static void update_pcm_stream_id(struct hda_codec *codec, @@ -1668,7 +1738,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, } } } -EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream); +EXPORT_SYMBOL_GPL(snd_hda_codec_setup_stream); static void really_cleanup_stream(struct hda_codec *codec, struct hda_cvt_setup *q); @@ -1703,7 +1773,7 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid, p->active = 0; } } -EXPORT_SYMBOL_HDA(__snd_hda_codec_cleanup_stream); +EXPORT_SYMBOL_GPL(__snd_hda_codec_cleanup_stream); static void really_cleanup_stream(struct hda_codec *codec, struct hda_cvt_setup *q) @@ -1891,7 +1961,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) HDA_HASH_KEY(nid, direction, 0), read_amp_cap); } -EXPORT_SYMBOL_HDA(query_amp_caps); +EXPORT_SYMBOL_GPL(query_amp_caps); /** * snd_hda_override_amp_caps - Override the AMP capabilities @@ -1911,7 +1981,7 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, { return write_caps_hash(codec, HDA_HASH_KEY(nid, dir, 0), caps); } -EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); +EXPORT_SYMBOL_GPL(snd_hda_override_amp_caps); static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid, int dir) @@ -1935,7 +2005,7 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) return query_caps_hash(codec, nid, 0, HDA_HASH_PINCAP_KEY(nid), read_pin_cap); } -EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); +EXPORT_SYMBOL_GPL(snd_hda_query_pin_caps); /** * snd_hda_override_pin_caps - Override the pin capabilities @@ -1952,7 +2022,7 @@ int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, { return write_caps_hash(codec, HDA_HASH_PINCAP_KEY(nid), caps); } -EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); +EXPORT_SYMBOL_GPL(snd_hda_override_pin_caps); /* read or sync the hash value with the current value; * call within hash_mutex @@ -2033,7 +2103,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, mutex_unlock(&codec->hash_mutex); return val; } -EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read); +EXPORT_SYMBOL_GPL(snd_hda_codec_amp_read); static int codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val, @@ -2085,7 +2155,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, { return codec_amp_update(codec, nid, ch, direction, idx, mask, val, false); } -EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update); +EXPORT_SYMBOL_GPL(snd_hda_codec_amp_update); /** * snd_hda_codec_amp_stereo - update the AMP stereo values @@ -2111,7 +2181,7 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, idx, mask, val); return ret; } -EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); +EXPORT_SYMBOL_GPL(snd_hda_codec_amp_stereo); /* Works like snd_hda_codec_amp_update() but it writes the value only at * the first access. If the amp was already initialized / updated beforehand, @@ -2122,7 +2192,7 @@ int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch, { return codec_amp_update(codec, nid, ch, dir, idx, mask, val, true); } -EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init); +EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init); int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, int dir, int idx, int mask, int val) @@ -2136,7 +2206,7 @@ int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid, idx, mask, val); return ret; } -EXPORT_SYMBOL_HDA(snd_hda_codec_amp_init_stereo); +EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init_stereo); /** * snd_hda_codec_resume_amp - Resume all AMP commands from the cache @@ -2179,7 +2249,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) } mutex_unlock(&codec->hash_mutex); } -EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); +EXPORT_SYMBOL_GPL(snd_hda_codec_resume_amp); static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int ofs) @@ -2219,7 +2289,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_info); static inline unsigned int @@ -2276,7 +2346,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, *valp = read_amp_value(codec, nid, 1, dir, idx, ofs); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_get); /** * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume @@ -2306,7 +2376,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, snd_hda_power_down(codec); return change; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put); /** * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume @@ -2344,7 +2414,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, return -EFAULT; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_tlv); /** * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control @@ -2372,7 +2442,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, tlv[2] = -nums * step; tlv[3] = step; } -EXPORT_SYMBOL_HDA(snd_hda_set_vmaster_tlv); +EXPORT_SYMBOL_GPL(snd_hda_set_vmaster_tlv); /* find a mixer control element with the given name */ static struct snd_kcontrol * @@ -2401,7 +2471,7 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, { return find_mixer_ctl(codec, name, 0, 0); } -EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); +EXPORT_SYMBOL_GPL(snd_hda_find_mixer_ctl); static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name, int start_idx) @@ -2461,7 +2531,7 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid, item->flags = flags; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_ctl_add); +EXPORT_SYMBOL_GPL(snd_hda_ctl_add); /** * snd_hda_add_nid - Assign a NID to a control element @@ -2492,7 +2562,7 @@ int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, kctl->id.name, kctl->id.index, index); return -EINVAL; } -EXPORT_SYMBOL_HDA(snd_hda_add_nid); +EXPORT_SYMBOL_GPL(snd_hda_add_nid); /** * snd_hda_ctls_clear - Clear all controls assigned to the given codec @@ -2543,7 +2613,7 @@ int snd_hda_lock_devices(struct hda_bus *bus) spin_unlock(&card->files_lock); return -EINVAL; } -EXPORT_SYMBOL_HDA(snd_hda_lock_devices); +EXPORT_SYMBOL_GPL(snd_hda_lock_devices); void snd_hda_unlock_devices(struct hda_bus *bus) { @@ -2554,7 +2624,7 @@ void snd_hda_unlock_devices(struct hda_bus *bus) card->shutdown = 0; spin_unlock(&card->files_lock); } -EXPORT_SYMBOL_HDA(snd_hda_unlock_devices); +EXPORT_SYMBOL_GPL(snd_hda_unlock_devices); /** * snd_hda_codec_reset - Clear all objects assigned to the codec @@ -2610,6 +2680,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) codec->preset = NULL; codec->slave_dig_outs = NULL; codec->spdif_status_reset = 0; + unload_parser(codec); module_put(codec->owner); codec->owner = NULL; @@ -2777,7 +2848,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, *ctl_ret = kctl; return 0; } -EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster); +EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster); /* * mute-LED control using vmaster @@ -2854,7 +2925,7 @@ int snd_hda_add_vmaster_hook(struct hda_codec *codec, return -ENOMEM; return snd_hda_ctl_add(codec, 0, kctl); } -EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook); +EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook); /* * Call the hook with the current value for synchronization @@ -2878,7 +2949,7 @@ void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook) break; } } -EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook); +EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook); /** @@ -2898,7 +2969,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_info); /** * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch @@ -2924,7 +2995,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, HDA_AMP_MUTE) ? 0 : 1; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get); /** * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch @@ -2958,7 +3029,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, snd_hda_power_down(codec); return change; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); +EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put); /* * bound volume controls @@ -2990,7 +3061,7 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, mutex_unlock(&codec->control_mutex); return err; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get); +EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_get); /** * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control @@ -3020,7 +3091,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, mutex_unlock(&codec->control_mutex); return err < 0 ? err : change; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put); +EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_switch_put); /** * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control @@ -3043,7 +3114,7 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, mutex_unlock(&codec->control_mutex); return err; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info); +EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_info); /** * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control @@ -3066,7 +3137,7 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, mutex_unlock(&codec->control_mutex); return err; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get); +EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_get); /** * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control @@ -3095,7 +3166,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, mutex_unlock(&codec->control_mutex); return err < 0 ? err : change; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put); +EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_ctls_put); /** * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control @@ -3118,7 +3189,7 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, mutex_unlock(&codec->control_mutex); return err; } -EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv); +EXPORT_SYMBOL_GPL(snd_hda_mixer_bind_tlv); struct hda_ctl_ops snd_hda_bind_vol = { .info = snd_hda_mixer_amp_volume_info, @@ -3126,7 +3197,7 @@ struct hda_ctl_ops snd_hda_bind_vol = { .put = snd_hda_mixer_amp_volume_put, .tlv = snd_hda_mixer_amp_tlv }; -EXPORT_SYMBOL_HDA(snd_hda_bind_vol); +EXPORT_SYMBOL_GPL(snd_hda_bind_vol); struct hda_ctl_ops snd_hda_bind_sw = { .info = snd_hda_mixer_amp_switch_info, @@ -3134,7 +3205,7 @@ struct hda_ctl_ops snd_hda_bind_sw = { .put = snd_hda_mixer_amp_switch_put, .tlv = snd_hda_mixer_amp_tlv }; -EXPORT_SYMBOL_HDA(snd_hda_bind_sw); +EXPORT_SYMBOL_GPL(snd_hda_bind_sw); /* * SPDIF out controls @@ -3438,7 +3509,7 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec, spdif->status = convert_to_spdif_status(spdif->ctls); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_create_dig_out_ctls); +EXPORT_SYMBOL_GPL(snd_hda_create_dig_out_ctls); /* get the hda_spdif_out entry from the given NID * call within spdif_mutex lock @@ -3455,7 +3526,7 @@ struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec, } return NULL; } -EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid); +EXPORT_SYMBOL_GPL(snd_hda_spdif_out_of_nid); void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) { @@ -3466,7 +3537,7 @@ void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx) spdif->nid = (u16)-1; mutex_unlock(&codec->spdif_mutex); } -EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign); +EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign); void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) { @@ -3482,7 +3553,7 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid) } mutex_unlock(&codec->spdif_mutex); } -EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_assign); +EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_assign); /* * SPDIF sharing with analog output @@ -3530,7 +3601,7 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec, /* ATTENTION: here mout is passed as private_data, instead of codec */ return snd_hda_ctl_add(codec, mout->dig_out_nid, kctl); } -EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw); +EXPORT_SYMBOL_GPL(snd_hda_create_spdif_share_sw); /* * SPDIF input @@ -3638,7 +3709,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) AC_DIG1_ENABLE; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); +EXPORT_SYMBOL_GPL(snd_hda_create_spdif_in_ctls); /* * command cache @@ -3689,7 +3760,7 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, mutex_unlock(&codec->bus->cmd_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache); +EXPORT_SYMBOL_GPL(snd_hda_codec_write_cache); /** * snd_hda_codec_update_cache - check cache and write the cmd only when needed @@ -3724,7 +3795,7 @@ int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, mutex_unlock(&codec->bus->cmd_mutex); return snd_hda_codec_write_cache(codec, nid, flags, verb, parm); } -EXPORT_SYMBOL_HDA(snd_hda_codec_update_cache); +EXPORT_SYMBOL_GPL(snd_hda_codec_update_cache); /** * snd_hda_codec_resume_cache - Resume the all commands from the cache @@ -3756,7 +3827,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec) } mutex_unlock(&codec->hash_mutex); } -EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache); +EXPORT_SYMBOL_GPL(snd_hda_codec_resume_cache); /** * snd_hda_sequence_write_cache - sequence writes with caching @@ -3774,7 +3845,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, seq->param); } -EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache); +EXPORT_SYMBOL_GPL(snd_hda_sequence_write_cache); /** * snd_hda_codec_flush_cache - Execute all pending (cached) amps / verbs @@ -3785,7 +3856,7 @@ void snd_hda_codec_flush_cache(struct hda_codec *codec) snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); } -EXPORT_SYMBOL_HDA(snd_hda_codec_flush_cache); +EXPORT_SYMBOL_GPL(snd_hda_codec_flush_cache); void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) @@ -3807,7 +3878,7 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, state); } } -EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); +EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); /* * supported power states check @@ -3856,6 +3927,8 @@ unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state) { + if (nid == codec->afg || nid == codec->mfg) + return power_state; if (power_state == AC_PWRST_D3 && get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN && (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) { @@ -3866,7 +3939,7 @@ unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec, } return power_state; } -EXPORT_SYMBOL_HDA(snd_hda_codec_eapd_power_filter); +EXPORT_SYMBOL_GPL(snd_hda_codec_eapd_power_filter); /* * set power state of the codec, and return the power state @@ -3881,8 +3954,10 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, /* this delay seems necessary to avoid click noise at power-down */ if (power_state == AC_PWRST_D3) { - /* transition time less than 10ms for power down */ - msleep(codec->epss ? 10 : 100); + if (codec->depop_delay < 0) + msleep(codec->epss ? 10 : 100); + else if (codec->depop_delay > 0) + msleep(codec->depop_delay); flags = HDA_RW_NO_RESPONSE_FALLBACK; } @@ -3892,9 +3967,13 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, codec->patch_ops.set_power_state(codec, fg, power_state); else { - snd_hda_codec_read(codec, fg, flags, - AC_VERB_SET_POWER_STATE, - power_state); + state = power_state; + if (codec->power_filter) + state = codec->power_filter(codec, fg, state); + if (state == power_state || power_state != AC_PWRST_D3) + snd_hda_codec_read(codec, fg, flags, + AC_VERB_SET_POWER_STATE, + state); snd_hda_codec_set_power_to_all(codec, fg, power_state); } state = hda_sync_power_state(codec, fg, power_state); @@ -4000,10 +4079,6 @@ static void hda_call_codec_resume(struct hda_codec *codec) * in the resume / power-save sequence */ hda_keep_power_on(codec); - if (codec->pm_down_notified) { - codec->pm_down_notified = 0; - hda_call_pm_notify(codec->bus, true); - } hda_set_power_state(codec, AC_PWRST_D0); restore_shutup_pins(codec); hda_exec_init_verbs(codec); @@ -4055,7 +4130,7 @@ int snd_hda_build_controls(struct hda_bus *bus) } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_build_controls); +EXPORT_SYMBOL_GPL(snd_hda_build_controls); /* * add standard channel maps if not specified @@ -4228,7 +4303,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, return val; } -EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); +EXPORT_SYMBOL_GPL(snd_hda_calc_stream_format); static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid, int dir) @@ -4374,7 +4449,7 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, return 0; } -EXPORT_SYMBOL_HDA(snd_hda_query_supported_pcm); +EXPORT_SYMBOL_GPL(snd_hda_query_supported_pcm); /** * snd_hda_is_supported_format - Check the validity of the format @@ -4441,7 +4516,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, return 1; } -EXPORT_SYMBOL_HDA(snd_hda_is_supported_format); +EXPORT_SYMBOL_GPL(snd_hda_is_supported_format); /* * PCM stuff @@ -4519,7 +4594,7 @@ int snd_hda_codec_prepare(struct hda_codec *codec, mutex_unlock(&codec->bus->prepare_mutex); return ret; } -EXPORT_SYMBOL_HDA(snd_hda_codec_prepare); +EXPORT_SYMBOL_GPL(snd_hda_codec_prepare); void snd_hda_codec_cleanup(struct hda_codec *codec, struct hda_pcm_stream *hinfo, @@ -4529,7 +4604,7 @@ void snd_hda_codec_cleanup(struct hda_codec *codec, hinfo->ops.cleanup(hinfo, codec, substream); mutex_unlock(&codec->bus->prepare_mutex); } -EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup); +EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup); /* global */ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = { @@ -4687,7 +4762,7 @@ int snd_hda_build_pcms(struct hda_bus *bus) } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_build_pcms); +EXPORT_SYMBOL_GPL(snd_hda_build_pcms); /** * snd_hda_check_board_config - compare the current codec with the config table @@ -4743,7 +4818,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, } return -1; } -EXPORT_SYMBOL_HDA(snd_hda_check_board_config); +EXPORT_SYMBOL_GPL(snd_hda_check_board_config); /** * snd_hda_check_board_codec_sid_config - compare the current codec @@ -4804,7 +4879,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, } return -1; } -EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); +EXPORT_SYMBOL_GPL(snd_hda_check_board_codec_sid_config); /** * snd_hda_add_new_ctls - create controls from the array @@ -4854,7 +4929,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); +EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls); #ifdef CONFIG_PM static void hda_power_work(struct work_struct *work) @@ -4877,11 +4952,8 @@ static void hda_power_work(struct work_struct *work) spin_unlock(&codec->power_lock); state = hda_call_codec_suspend(codec, true); - if (!codec->pm_down_notified && - !bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) { - codec->pm_down_notified = 1; - hda_call_pm_notify(bus, false); - } + if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) + hda_call_pm_notify(codec, false); } static void hda_keep_power_on(struct hda_codec *codec) @@ -4891,6 +4963,7 @@ static void hda_keep_power_on(struct hda_codec *codec) codec->power_on = 1; codec->power_jiffies = jiffies; spin_unlock(&codec->power_lock); + hda_call_pm_notify(codec, true); } /* update the power on/off account with the current jiffies */ @@ -4910,8 +4983,6 @@ void snd_hda_update_power_acct(struct hda_codec *codec) /* call this with codec->power_lock held! */ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) { - struct hda_bus *bus = codec->bus; - /* Return if power_on or transitioning to power_on, unless currently * powering down. */ if ((codec->power_on || codec->power_transition > 0) && @@ -4938,11 +5009,6 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) codec->power_transition = 1; /* avoid reentrance */ spin_unlock(&codec->power_lock); - if (codec->pm_down_notified) { - codec->pm_down_notified = 0; - hda_call_pm_notify(bus, true); - } - hda_call_codec_resume(codec); spin_lock(&codec->power_lock); @@ -4985,7 +5051,7 @@ void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait) __snd_hda_power_down(codec); spin_unlock(&codec->power_lock); } -EXPORT_SYMBOL_HDA(snd_hda_power_save); +EXPORT_SYMBOL_GPL(snd_hda_power_save); /** * snd_hda_check_amp_list_power - Check the amp list and update the power @@ -5035,7 +5101,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power); +EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power); #endif /* @@ -5059,7 +5125,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, chmode[uinfo->value.enumerated.item].channels); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info); +EXPORT_SYMBOL_GPL(snd_hda_ch_mode_info); /** * snd_hda_ch_mode_get - Get callback helper for the channel mode enum @@ -5080,7 +5146,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get); +EXPORT_SYMBOL_GPL(snd_hda_ch_mode_get); /** * snd_hda_ch_mode_put - Put callback helper for the channel mode enum @@ -5104,7 +5170,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, snd_hda_sequence_write_cache(codec, chmode[mode].sequence); return 1; } -EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put); +EXPORT_SYMBOL_GPL(snd_hda_ch_mode_put); /* * input MUX helper @@ -5129,7 +5195,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, strcpy(uinfo->value.enumerated.name, imux->items[index].label); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_input_mux_info); +EXPORT_SYMBOL_GPL(snd_hda_input_mux_info); /** * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum @@ -5154,7 +5220,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, *cur_val = idx; return 1; } -EXPORT_SYMBOL_HDA(snd_hda_input_mux_put); +EXPORT_SYMBOL_GPL(snd_hda_input_mux_put); /* @@ -5183,7 +5249,7 @@ int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol, texts[uinfo->value.enumerated.item]); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_enum_helper_info); +EXPORT_SYMBOL_GPL(snd_hda_enum_helper_info); /* * Multi-channel / digital-out PCM helper functions @@ -5249,7 +5315,7 @@ void snd_hda_bus_reboot_notify(struct hda_bus *bus) codec->patch_ops.reboot_notify(codec); } } -EXPORT_SYMBOL_HDA(snd_hda_bus_reboot_notify); +EXPORT_SYMBOL_GPL(snd_hda_bus_reboot_notify); /** * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode @@ -5265,7 +5331,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_open); /** * snd_hda_multi_out_dig_prepare - prepare the digital out stream @@ -5281,7 +5347,7 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare); /** * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream @@ -5294,7 +5360,7 @@ int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup); /** * snd_hda_multi_out_dig_close - release the digital out stream @@ -5307,7 +5373,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_close); /** * snd_hda_multi_out_analog_open - open analog outputs @@ -5357,7 +5423,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, return snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_open); /** * snd_hda_multi_out_analog_prepare - Preapre the analog outputs. @@ -5434,7 +5500,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, return 0; } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_prepare); /** * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out @@ -5465,7 +5531,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); +EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_cleanup); /** * snd_hda_get_default_vref - Get the default (mic) VREF pin bits @@ -5492,7 +5558,7 @@ unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin) return AC_PINCTL_VREF_GRD; return AC_PINCTL_VREF_HIZ; } -EXPORT_SYMBOL_HDA(snd_hda_get_default_vref); +EXPORT_SYMBOL_GPL(snd_hda_get_default_vref); /* correct the pin ctl value for matching with the pin cap */ unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, @@ -5543,7 +5609,7 @@ unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec, return val; } -EXPORT_SYMBOL_HDA(snd_hda_correct_pin_ctl); +EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl); int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val, bool cached) @@ -5557,7 +5623,7 @@ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, return snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); } -EXPORT_SYMBOL_HDA(_snd_hda_set_pin_ctl); +EXPORT_SYMBOL_GPL(_snd_hda_set_pin_ctl); /** * snd_hda_add_imux_item - Add an item to input_mux @@ -5591,7 +5657,7 @@ int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, imux->num_items++; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_add_imux_item); +EXPORT_SYMBOL_GPL(snd_hda_add_imux_item); #ifdef CONFIG_PM @@ -5599,6 +5665,17 @@ EXPORT_SYMBOL_HDA(snd_hda_add_imux_item); * power management */ + +static void hda_async_suspend(void *data, async_cookie_t cookie) +{ + hda_call_codec_suspend(data, false); +} + +static void hda_async_resume(void *data, async_cookie_t cookie) +{ + hda_call_codec_resume(data); +} + /** * snd_hda_suspend - suspend the codecs * @bus: the HDA bus @@ -5608,15 +5685,25 @@ EXPORT_SYMBOL_HDA(snd_hda_add_imux_item); int snd_hda_suspend(struct hda_bus *bus) { struct hda_codec *codec; + ASYNC_DOMAIN_EXCLUSIVE(domain); list_for_each_entry(codec, &bus->codec_list, list) { cancel_delayed_work_sync(&codec->jackpoll_work); - if (hda_codec_is_power_on(codec)) - hda_call_codec_suspend(codec, false); + if (hda_codec_is_power_on(codec)) { + if (bus->num_codecs > 1) + async_schedule_domain(hda_async_suspend, codec, + &domain); + else + hda_call_codec_suspend(codec, false); + } } + + if (bus->num_codecs > 1) + async_synchronize_full_domain(&domain); + return 0; } -EXPORT_SYMBOL_HDA(snd_hda_suspend); +EXPORT_SYMBOL_GPL(snd_hda_suspend); /** * snd_hda_resume - resume the codecs @@ -5627,13 +5714,21 @@ EXPORT_SYMBOL_HDA(snd_hda_suspend); int snd_hda_resume(struct hda_bus *bus) { struct hda_codec *codec; + ASYNC_DOMAIN_EXCLUSIVE(domain); list_for_each_entry(codec, &bus->codec_list, list) { - hda_call_codec_resume(codec); + if (bus->num_codecs > 1) + async_schedule_domain(hda_async_resume, codec, &domain); + else + hda_call_codec_resume(codec); } + + if (bus->num_codecs > 1) + async_synchronize_full_domain(&domain); + return 0; } -EXPORT_SYMBOL_HDA(snd_hda_resume); +EXPORT_SYMBOL_GPL(snd_hda_resume); #endif /* CONFIG_PM */ /* @@ -5667,7 +5762,7 @@ void *snd_array_new(struct snd_array *array) } return snd_array_elem(array, array->used++); } -EXPORT_SYMBOL_HDA(snd_array_new); +EXPORT_SYMBOL_GPL(snd_array_new); /** * snd_array_free - free the given array elements @@ -5680,7 +5775,7 @@ void snd_array_free(struct snd_array *array) array->alloced = 0; array->list = NULL; } -EXPORT_SYMBOL_HDA(snd_array_free); +EXPORT_SYMBOL_GPL(snd_array_free); /** * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer @@ -5701,7 +5796,7 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) buf[j] = '\0'; /* necessary when j == 0 */ } -EXPORT_SYMBOL_HDA(snd_print_pcm_bits); +EXPORT_SYMBOL_GPL(snd_print_pcm_bits); MODULE_DESCRIPTION("HDA codec core"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 7aa9870040c1..2b5d19e48a27 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -25,552 +25,7 @@ #include #include #include - -/* - * nodes - */ -#define AC_NODE_ROOT 0x00 - -/* - * function group types - */ -enum { - AC_GRP_AUDIO_FUNCTION = 0x01, - AC_GRP_MODEM_FUNCTION = 0x02, -}; - -/* - * widget types - */ -enum { - AC_WID_AUD_OUT, /* Audio Out */ - AC_WID_AUD_IN, /* Audio In */ - AC_WID_AUD_MIX, /* Audio Mixer */ - AC_WID_AUD_SEL, /* Audio Selector */ - AC_WID_PIN, /* Pin Complex */ - AC_WID_POWER, /* Power */ - AC_WID_VOL_KNB, /* Volume Knob */ - AC_WID_BEEP, /* Beep Generator */ - AC_WID_VENDOR = 0x0f /* Vendor specific */ -}; - -/* - * GET verbs - */ -#define AC_VERB_GET_STREAM_FORMAT 0x0a00 -#define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00 -#define AC_VERB_GET_PROC_COEF 0x0c00 -#define AC_VERB_GET_COEF_INDEX 0x0d00 -#define AC_VERB_PARAMETERS 0x0f00 -#define AC_VERB_GET_CONNECT_SEL 0x0f01 -#define AC_VERB_GET_CONNECT_LIST 0x0f02 -#define AC_VERB_GET_PROC_STATE 0x0f03 -#define AC_VERB_GET_SDI_SELECT 0x0f04 -#define AC_VERB_GET_POWER_STATE 0x0f05 -#define AC_VERB_GET_CONV 0x0f06 -#define AC_VERB_GET_PIN_WIDGET_CONTROL 0x0f07 -#define AC_VERB_GET_UNSOLICITED_RESPONSE 0x0f08 -#define AC_VERB_GET_PIN_SENSE 0x0f09 -#define AC_VERB_GET_BEEP_CONTROL 0x0f0a -#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c -#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d -#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */ -#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f -/* f10-f1a: GPIO */ -#define AC_VERB_GET_GPIO_DATA 0x0f15 -#define AC_VERB_GET_GPIO_MASK 0x0f16 -#define AC_VERB_GET_GPIO_DIRECTION 0x0f17 -#define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18 -#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19 -#define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a -#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c -/* f20: AFG/MFG */ -#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 -#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d -#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e -#define AC_VERB_GET_HDMI_ELDD 0x0f2f -#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30 -#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31 -#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 -#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 -#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34 -#define AC_VERB_GET_DEVICE_SEL 0xf35 -#define AC_VERB_GET_DEVICE_LIST 0xf36 - -/* - * SET verbs - */ -#define AC_VERB_SET_STREAM_FORMAT 0x200 -#define AC_VERB_SET_AMP_GAIN_MUTE 0x300 -#define AC_VERB_SET_PROC_COEF 0x400 -#define AC_VERB_SET_COEF_INDEX 0x500 -#define AC_VERB_SET_CONNECT_SEL 0x701 -#define AC_VERB_SET_PROC_STATE 0x703 -#define AC_VERB_SET_SDI_SELECT 0x704 -#define AC_VERB_SET_POWER_STATE 0x705 -#define AC_VERB_SET_CHANNEL_STREAMID 0x706 -#define AC_VERB_SET_PIN_WIDGET_CONTROL 0x707 -#define AC_VERB_SET_UNSOLICITED_ENABLE 0x708 -#define AC_VERB_SET_PIN_SENSE 0x709 -#define AC_VERB_SET_BEEP_CONTROL 0x70a -#define AC_VERB_SET_EAPD_BTLENABLE 0x70c -#define AC_VERB_SET_DIGI_CONVERT_1 0x70d -#define AC_VERB_SET_DIGI_CONVERT_2 0x70e -#define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f -#define AC_VERB_SET_GPIO_DATA 0x715 -#define AC_VERB_SET_GPIO_MASK 0x716 -#define AC_VERB_SET_GPIO_DIRECTION 0x717 -#define AC_VERB_SET_GPIO_WAKE_MASK 0x718 -#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719 -#define AC_VERB_SET_GPIO_STICKY_MASK 0x71a -#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c -#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d -#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e -#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f -#define AC_VERB_SET_EAPD 0x788 -#define AC_VERB_SET_CODEC_RESET 0x7ff -#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d -#define AC_VERB_SET_HDMI_DIP_INDEX 0x730 -#define AC_VERB_SET_HDMI_DIP_DATA 0x731 -#define AC_VERB_SET_HDMI_DIP_XMIT 0x732 -#define AC_VERB_SET_HDMI_CP_CTRL 0x733 -#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 -#define AC_VERB_SET_DEVICE_SEL 0x735 - -/* - * Parameter IDs - */ -#define AC_PAR_VENDOR_ID 0x00 -#define AC_PAR_SUBSYSTEM_ID 0x01 -#define AC_PAR_REV_ID 0x02 -#define AC_PAR_NODE_COUNT 0x04 -#define AC_PAR_FUNCTION_TYPE 0x05 -#define AC_PAR_AUDIO_FG_CAP 0x08 -#define AC_PAR_AUDIO_WIDGET_CAP 0x09 -#define AC_PAR_PCM 0x0a -#define AC_PAR_STREAM 0x0b -#define AC_PAR_PIN_CAP 0x0c -#define AC_PAR_AMP_IN_CAP 0x0d -#define AC_PAR_CONNLIST_LEN 0x0e -#define AC_PAR_POWER_STATE 0x0f -#define AC_PAR_PROC_CAP 0x10 -#define AC_PAR_GPIO_CAP 0x11 -#define AC_PAR_AMP_OUT_CAP 0x12 -#define AC_PAR_VOL_KNB_CAP 0x13 -#define AC_PAR_DEVLIST_LEN 0x15 -#define AC_PAR_HDMI_LPCM_CAP 0x20 - -/* - * AC_VERB_PARAMETERS results (32bit) - */ - -/* Function Group Type */ -#define AC_FGT_TYPE (0xff<<0) -#define AC_FGT_TYPE_SHIFT 0 -#define AC_FGT_UNSOL_CAP (1<<8) - -/* Audio Function Group Capabilities */ -#define AC_AFG_OUT_DELAY (0xf<<0) -#define AC_AFG_IN_DELAY (0xf<<8) -#define AC_AFG_BEEP_GEN (1<<16) - -/* Audio Widget Capabilities */ -#define AC_WCAP_STEREO (1<<0) /* stereo I/O */ -#define AC_WCAP_IN_AMP (1<<1) /* AMP-in present */ -#define AC_WCAP_OUT_AMP (1<<2) /* AMP-out present */ -#define AC_WCAP_AMP_OVRD (1<<3) /* AMP-parameter override */ -#define AC_WCAP_FORMAT_OVRD (1<<4) /* format override */ -#define AC_WCAP_STRIPE (1<<5) /* stripe */ -#define AC_WCAP_PROC_WID (1<<6) /* Proc Widget */ -#define AC_WCAP_UNSOL_CAP (1<<7) /* Unsol capable */ -#define AC_WCAP_CONN_LIST (1<<8) /* connection list */ -#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */ -#define AC_WCAP_POWER (1<<10) /* power control */ -#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */ -#define AC_WCAP_CP_CAPS (1<<12) /* content protection */ -#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */ -#define AC_WCAP_DELAY (0xf<<16) -#define AC_WCAP_DELAY_SHIFT 16 -#define AC_WCAP_TYPE (0xf<<20) -#define AC_WCAP_TYPE_SHIFT 20 - -/* supported PCM rates and bits */ -#define AC_SUPPCM_RATES (0xfff << 0) -#define AC_SUPPCM_BITS_8 (1<<16) -#define AC_SUPPCM_BITS_16 (1<<17) -#define AC_SUPPCM_BITS_20 (1<<18) -#define AC_SUPPCM_BITS_24 (1<<19) -#define AC_SUPPCM_BITS_32 (1<<20) - -/* supported PCM stream format */ -#define AC_SUPFMT_PCM (1<<0) -#define AC_SUPFMT_FLOAT32 (1<<1) -#define AC_SUPFMT_AC3 (1<<2) - -/* GP I/O count */ -#define AC_GPIO_IO_COUNT (0xff<<0) -#define AC_GPIO_O_COUNT (0xff<<8) -#define AC_GPIO_O_COUNT_SHIFT 8 -#define AC_GPIO_I_COUNT (0xff<<16) -#define AC_GPIO_I_COUNT_SHIFT 16 -#define AC_GPIO_UNSOLICITED (1<<30) -#define AC_GPIO_WAKE (1<<31) - -/* Converter stream, channel */ -#define AC_CONV_CHANNEL (0xf<<0) -#define AC_CONV_STREAM (0xf<<4) -#define AC_CONV_STREAM_SHIFT 4 - -/* Input converter SDI select */ -#define AC_SDI_SELECT (0xf<<0) - -/* stream format id */ -#define AC_FMT_CHAN_SHIFT 0 -#define AC_FMT_CHAN_MASK (0x0f << 0) -#define AC_FMT_BITS_SHIFT 4 -#define AC_FMT_BITS_MASK (7 << 4) -#define AC_FMT_BITS_8 (0 << 4) -#define AC_FMT_BITS_16 (1 << 4) -#define AC_FMT_BITS_20 (2 << 4) -#define AC_FMT_BITS_24 (3 << 4) -#define AC_FMT_BITS_32 (4 << 4) -#define AC_FMT_DIV_SHIFT 8 -#define AC_FMT_DIV_MASK (7 << 8) -#define AC_FMT_MULT_SHIFT 11 -#define AC_FMT_MULT_MASK (7 << 11) -#define AC_FMT_BASE_SHIFT 14 -#define AC_FMT_BASE_48K (0 << 14) -#define AC_FMT_BASE_44K (1 << 14) -#define AC_FMT_TYPE_SHIFT 15 -#define AC_FMT_TYPE_PCM (0 << 15) -#define AC_FMT_TYPE_NON_PCM (1 << 15) - -/* Unsolicited response control */ -#define AC_UNSOL_TAG (0x3f<<0) -#define AC_UNSOL_ENABLED (1<<7) -#define AC_USRSP_EN AC_UNSOL_ENABLED - -/* Unsolicited responses */ -#define AC_UNSOL_RES_TAG (0x3f<<26) -#define AC_UNSOL_RES_TAG_SHIFT 26 -#define AC_UNSOL_RES_SUBTAG (0x1f<<21) -#define AC_UNSOL_RES_SUBTAG_SHIFT 21 -#define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry - * (for DP1.2 MST) - */ -#define AC_UNSOL_RES_DE_SHIFT 15 -#define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */ -#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */ -#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */ -#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */ -#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */ - -/* Pin widget capabilies */ -#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */ -#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */ -#define AC_PINCAP_PRES_DETECT (1<<2) /* presence detect capable */ -#define AC_PINCAP_HP_DRV (1<<3) /* headphone drive capable */ -#define AC_PINCAP_OUT (1<<4) /* output capable */ -#define AC_PINCAP_IN (1<<5) /* input capable */ -#define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */ -/* Note: This LR_SWAP pincap is defined in the Realtek ALC883 specification, - * but is marked reserved in the Intel HDA specification. - */ -#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */ -/* Note: The same bit as LR_SWAP is newly defined as HDMI capability - * in HD-audio specification - */ -#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ -#define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can - * coexist with AC_PINCAP_HDMI - */ -#define AC_PINCAP_VREF (0x37<<8) -#define AC_PINCAP_VREF_SHIFT 8 -#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ -#define AC_PINCAP_HBR (1<<27) /* High Bit Rate */ -/* Vref status (used in pin cap) */ -#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ -#define AC_PINCAP_VREF_50 (1<<1) /* 50% */ -#define AC_PINCAP_VREF_GRD (1<<2) /* ground */ -#define AC_PINCAP_VREF_80 (1<<4) /* 80% */ -#define AC_PINCAP_VREF_100 (1<<5) /* 100% */ - -/* Amplifier capabilities */ -#define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */ -#define AC_AMPCAP_OFFSET_SHIFT 0 -#define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */ -#define AC_AMPCAP_NUM_STEPS_SHIFT 8 -#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB - * in 0.25dB - */ -#define AC_AMPCAP_STEP_SIZE_SHIFT 16 -#define AC_AMPCAP_MUTE (1<<31) /* mute capable */ -#define AC_AMPCAP_MUTE_SHIFT 31 - -/* driver-specific amp-caps: using bits 24-30 */ -#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */ - -/* Connection list */ -#define AC_CLIST_LENGTH (0x7f<<0) -#define AC_CLIST_LONG (1<<7) - -/* Supported power status */ -#define AC_PWRST_D0SUP (1<<0) -#define AC_PWRST_D1SUP (1<<1) -#define AC_PWRST_D2SUP (1<<2) -#define AC_PWRST_D3SUP (1<<3) -#define AC_PWRST_D3COLDSUP (1<<4) -#define AC_PWRST_S3D3COLDSUP (1<<29) -#define AC_PWRST_CLKSTOP (1<<30) -#define AC_PWRST_EPSS (1U<<31) - -/* Power state values */ -#define AC_PWRST_SETTING (0xf<<0) -#define AC_PWRST_ACTUAL (0xf<<4) -#define AC_PWRST_ACTUAL_SHIFT 4 -#define AC_PWRST_D0 0x00 -#define AC_PWRST_D1 0x01 -#define AC_PWRST_D2 0x02 -#define AC_PWRST_D3 0x03 -#define AC_PWRST_ERROR (1<<8) -#define AC_PWRST_CLK_STOP_OK (1<<9) -#define AC_PWRST_SETTING_RESET (1<<10) - -/* Processing capabilies */ -#define AC_PCAP_BENIGN (1<<0) -#define AC_PCAP_NUM_COEF (0xff<<8) -#define AC_PCAP_NUM_COEF_SHIFT 8 - -/* Volume knobs capabilities */ -#define AC_KNBCAP_NUM_STEPS (0x7f<<0) -#define AC_KNBCAP_DELTA (1<<7) - -/* HDMI LPCM capabilities */ -#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */ -#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */ -#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */ -#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */ -#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */ -#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */ -#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */ -#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */ -#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */ -#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */ -#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */ -#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */ -#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ -#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ - -/* Display pin's device list length */ -#define AC_DEV_LIST_LEN_MASK 0x3f -#define AC_MAX_DEV_LIST_LEN 64 - -/* - * Control Parameters - */ - -/* Amp gain/mute */ -#define AC_AMP_MUTE (1<<7) -#define AC_AMP_GAIN (0x7f) -#define AC_AMP_GET_INDEX (0xf<<0) - -#define AC_AMP_GET_LEFT (1<<13) -#define AC_AMP_GET_RIGHT (0<<13) -#define AC_AMP_GET_OUTPUT (1<<15) -#define AC_AMP_GET_INPUT (0<<15) - -#define AC_AMP_SET_INDEX (0xf<<8) -#define AC_AMP_SET_INDEX_SHIFT 8 -#define AC_AMP_SET_RIGHT (1<<12) -#define AC_AMP_SET_LEFT (1<<13) -#define AC_AMP_SET_INPUT (1<<14) -#define AC_AMP_SET_OUTPUT (1<<15) - -/* DIGITAL1 bits */ -#define AC_DIG1_ENABLE (1<<0) -#define AC_DIG1_V (1<<1) -#define AC_DIG1_VCFG (1<<2) -#define AC_DIG1_EMPHASIS (1<<3) -#define AC_DIG1_COPYRIGHT (1<<4) -#define AC_DIG1_NONAUDIO (1<<5) -#define AC_DIG1_PROFESSIONAL (1<<6) -#define AC_DIG1_LEVEL (1<<7) - -/* DIGITAL2 bits */ -#define AC_DIG2_CC (0x7f<<0) - -/* DIGITAL3 bits */ -#define AC_DIG3_ICT (0xf<<0) -#define AC_DIG3_KAE (1<<7) - -/* Pin widget control - 8bit */ -#define AC_PINCTL_EPT (0x3<<0) -#define AC_PINCTL_EPT_NATIVE 0 -#define AC_PINCTL_EPT_HBR 3 -#define AC_PINCTL_VREFEN (0x7<<0) -#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ -#define AC_PINCTL_VREF_50 1 /* 50% */ -#define AC_PINCTL_VREF_GRD 2 /* ground */ -#define AC_PINCTL_VREF_80 4 /* 80% */ -#define AC_PINCTL_VREF_100 5 /* 100% */ -#define AC_PINCTL_IN_EN (1<<5) -#define AC_PINCTL_OUT_EN (1<<6) -#define AC_PINCTL_HP_EN (1<<7) - -/* Pin sense - 32bit */ -#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff) -#define AC_PINSENSE_PRESENCE (1<<31) -#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */ - -/* EAPD/BTL enable - 32bit */ -#define AC_EAPDBTL_BALANCED (1<<0) -#define AC_EAPDBTL_EAPD (1<<1) -#define AC_EAPDBTL_LR_SWAP (1<<2) - -/* HDMI ELD data */ -#define AC_ELDD_ELD_VALID (1<<31) -#define AC_ELDD_ELD_DATA 0xff - -/* HDMI DIP size */ -#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */ -#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */ - -/* HDMI DIP index */ -#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */ -#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */ - -/* HDMI DIP xmit (transmit) control */ -#define AC_DIPXMIT_MASK (0x3<<6) -#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */ -#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */ -#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */ - -/* HDMI content protection (CP) control */ -#define AC_CPCTRL_CES (1<<9) /* current encryption state */ -#define AC_CPCTRL_READY (1<<8) /* ready bit */ -#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */ -#define AC_CPCTRL_STATE (3<<0) /* current CP request state */ - -/* Converter channel <-> HDMI slot mapping */ -#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */ -#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */ - -/* configuration default - 32bit */ -#define AC_DEFCFG_SEQUENCE (0xf<<0) -#define AC_DEFCFG_DEF_ASSOC (0xf<<4) -#define AC_DEFCFG_ASSOC_SHIFT 4 -#define AC_DEFCFG_MISC (0xf<<8) -#define AC_DEFCFG_MISC_SHIFT 8 -#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0) -#define AC_DEFCFG_COLOR (0xf<<12) -#define AC_DEFCFG_COLOR_SHIFT 12 -#define AC_DEFCFG_CONN_TYPE (0xf<<16) -#define AC_DEFCFG_CONN_TYPE_SHIFT 16 -#define AC_DEFCFG_DEVICE (0xf<<20) -#define AC_DEFCFG_DEVICE_SHIFT 20 -#define AC_DEFCFG_LOCATION (0x3f<<24) -#define AC_DEFCFG_LOCATION_SHIFT 24 -#define AC_DEFCFG_PORT_CONN (0x3<<30) -#define AC_DEFCFG_PORT_CONN_SHIFT 30 - -/* Display pin's device list entry */ -#define AC_DE_PD (1<<0) -#define AC_DE_ELDV (1<<1) -#define AC_DE_IA (1<<2) - -/* device device types (0x0-0xf) */ -enum { - AC_JACK_LINE_OUT, - AC_JACK_SPEAKER, - AC_JACK_HP_OUT, - AC_JACK_CD, - AC_JACK_SPDIF_OUT, - AC_JACK_DIG_OTHER_OUT, - AC_JACK_MODEM_LINE_SIDE, - AC_JACK_MODEM_HAND_SIDE, - AC_JACK_LINE_IN, - AC_JACK_AUX, - AC_JACK_MIC_IN, - AC_JACK_TELEPHONY, - AC_JACK_SPDIF_IN, - AC_JACK_DIG_OTHER_IN, - AC_JACK_OTHER = 0xf, -}; - -/* jack connection types (0x0-0xf) */ -enum { - AC_JACK_CONN_UNKNOWN, - AC_JACK_CONN_1_8, - AC_JACK_CONN_1_4, - AC_JACK_CONN_ATAPI, - AC_JACK_CONN_RCA, - AC_JACK_CONN_OPTICAL, - AC_JACK_CONN_OTHER_DIGITAL, - AC_JACK_CONN_OTHER_ANALOG, - AC_JACK_CONN_DIN, - AC_JACK_CONN_XLR, - AC_JACK_CONN_RJ11, - AC_JACK_CONN_COMB, - AC_JACK_CONN_OTHER = 0xf, -}; - -/* jack colors (0x0-0xf) */ -enum { - AC_JACK_COLOR_UNKNOWN, - AC_JACK_COLOR_BLACK, - AC_JACK_COLOR_GREY, - AC_JACK_COLOR_BLUE, - AC_JACK_COLOR_GREEN, - AC_JACK_COLOR_RED, - AC_JACK_COLOR_ORANGE, - AC_JACK_COLOR_YELLOW, - AC_JACK_COLOR_PURPLE, - AC_JACK_COLOR_PINK, - AC_JACK_COLOR_WHITE = 0xe, - AC_JACK_COLOR_OTHER, -}; - -/* Jack location (0x0-0x3f) */ -/* common case */ -enum { - AC_JACK_LOC_NONE, - AC_JACK_LOC_REAR, - AC_JACK_LOC_FRONT, - AC_JACK_LOC_LEFT, - AC_JACK_LOC_RIGHT, - AC_JACK_LOC_TOP, - AC_JACK_LOC_BOTTOM, -}; -/* bits 4-5 */ -enum { - AC_JACK_LOC_EXTERNAL = 0x00, - AC_JACK_LOC_INTERNAL = 0x10, - AC_JACK_LOC_SEPARATE = 0x20, - AC_JACK_LOC_OTHER = 0x30, -}; -enum { - /* external on primary chasis */ - AC_JACK_LOC_REAR_PANEL = 0x07, - AC_JACK_LOC_DRIVE_BAY, - /* internal */ - AC_JACK_LOC_RISER = 0x17, - AC_JACK_LOC_HDMI, - AC_JACK_LOC_ATAPI, - /* others */ - AC_JACK_LOC_MOBILE_IN = 0x37, - AC_JACK_LOC_MOBILE_OUT, -}; - -/* Port connectivity (0-3) */ -enum { - AC_JACK_PORT_COMPLEX, - AC_JACK_PORT_NONE, - AC_JACK_PORT_FIXED, - AC_JACK_PORT_BOTH, -}; - -/* max. codec address */ -#define HDA_MAX_CODEC_ADDRESS 0x0f +#include /* * generic arrays @@ -673,6 +128,7 @@ struct hda_bus { /* codec linked list */ struct list_head codec_list; + unsigned int num_codecs; /* link caddr -> codec */ struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; @@ -834,6 +290,7 @@ struct hda_codec { /* detected preset */ const struct hda_codec_preset *preset; struct module *owner; + int (*parser)(struct hda_codec *codec); const char *vendor_name; /* codec vendor name */ const char *chip_name; /* codec chip name */ const char *modelname; /* model name for preset */ @@ -907,7 +364,7 @@ struct hda_codec { #ifdef CONFIG_PM unsigned int power_on :1; /* current (global) power-state */ unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ - unsigned int pm_down_notified:1; /* PM notified to controller */ + unsigned int pm_up_notified:1; /* PM notified to controller */ unsigned int in_pm:1; /* suspend/resume being performed */ int power_transition; /* power-state in transition */ int power_count; /* current (global) power refcount */ @@ -936,6 +393,8 @@ struct hda_codec { struct snd_array jacks; #endif + int depop_delay; /* depop delay in ms, -1 for default delay time */ + /* fix-up list */ int fixup_id; const struct hda_fixup *fixup_list; @@ -1222,19 +681,6 @@ snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec, struct snd_dma_buffer *dmab) {} #endif -/* - * Codec modularization - */ - -/* Export symbols only for communication with codec drivers; - * When built in kernel, all HD-audio drivers are supposed to be statically - * linked to the kernel. Thus, the symbols don't have to (or shouldn't) be - * exported unless it's built as a module. - */ -#ifdef MODULE #define EXPORT_SYMBOL_HDA(sym) EXPORT_SYMBOL_GPL(sym) -#else -#define EXPORT_SYMBOL_HDA(sym) -#endif #endif /* __SOUND_HDA_CODEC_H */ diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index c7f6d1cab606..8321a97d5c05 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include "hda_codec.h" @@ -47,7 +48,7 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec) mutex_init(&spec->pcm_mutex); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_gen_spec_init); +EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); struct snd_kcontrol_new * snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, @@ -65,7 +66,7 @@ snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, return NULL; return knew; } -EXPORT_SYMBOL_HDA(snd_hda_gen_add_kctl); +EXPORT_SYMBOL_GPL(snd_hda_gen_add_kctl); static void free_kctls(struct hda_gen_spec *spec) { @@ -86,7 +87,7 @@ void snd_hda_gen_spec_free(struct hda_gen_spec *spec) snd_array_free(&spec->paths); snd_array_free(&spec->loopback_list); } -EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free); +EXPORT_SYMBOL_GPL(snd_hda_gen_spec_free); /* * store user hints @@ -266,7 +267,7 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, { return get_nid_path(codec, from_nid, to_nid, 0); } -EXPORT_SYMBOL_HDA(snd_hda_get_nid_path); +EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); /* get the index number corresponding to the path instance; * the index starts from 1, for easier checking the invalid value @@ -284,7 +285,7 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) return 0; return idx + 1; } -EXPORT_SYMBOL_HDA(snd_hda_get_path_idx); +EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); /* get the path instance corresponding to the given index number */ struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) @@ -295,7 +296,7 @@ struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) return NULL; return snd_array_elem(&spec->paths, idx - 1); } -EXPORT_SYMBOL_HDA(snd_hda_get_path_from_idx); +EXPORT_SYMBOL_GPL(snd_hda_get_path_from_idx); /* check whether the given DAC is already found in any existing paths */ static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid) @@ -432,7 +433,7 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, } return false; } -EXPORT_SYMBOL_HDA(snd_hda_parse_nid_path); +EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); /* * parse the path between the given NIDs and add to the path list. @@ -463,7 +464,7 @@ snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, spec->paths.used--; return NULL; } -EXPORT_SYMBOL_HDA(snd_hda_add_new_path); +EXPORT_SYMBOL_GPL(snd_hda_add_new_path); /* clear the given path as invalid so that it won't be picked up later */ static void invalidate_nid_path(struct hda_codec *codec, int idx) @@ -773,7 +774,7 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, if (enable) path->active = true; } -EXPORT_SYMBOL_HDA(snd_hda_activate_path); +EXPORT_SYMBOL_GPL(snd_hda_activate_path); /* if the given path is inactive, put widgets into D3 (only if suitable) */ static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path) @@ -1149,7 +1150,7 @@ const struct badness_table hda_main_out_badness = { .shared_clfe = BAD_SHARED_CLFE, .shared_surr_main = BAD_SHARED_SURROUND, }; -EXPORT_SYMBOL_HDA(hda_main_out_badness); +EXPORT_SYMBOL_GPL(hda_main_out_badness); const struct badness_table hda_extra_out_badness = { .no_primary_dac = BAD_NO_DAC, @@ -1159,7 +1160,7 @@ const struct badness_table hda_extra_out_badness = { .shared_clfe = BAD_SHARED_EXTRA_SURROUND, .shared_surr_main = BAD_NO_EXTRA_SURR_DAC, }; -EXPORT_SYMBOL_HDA(hda_extra_out_badness); +EXPORT_SYMBOL_GPL(hda_extra_out_badness); /* get the DAC of the primary output corresponding to the given array index */ static hda_nid_t get_primary_out(struct hda_codec *codec, int idx) @@ -2857,9 +2858,11 @@ static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid, if (num_conns < idx) return false; nid = list[idx]; - if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT)) + if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT) && + !is_ctl_associated(codec, nid, HDA_OUTPUT, 0, NID_PATH_VOL_CTL)) *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); - if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT)) + if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT) && + !is_ctl_associated(codec, nid, HDA_OUTPUT, 0, NID_PATH_MUTE_CTL)) *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); return *mix_val || *mute_val; @@ -3053,6 +3056,8 @@ static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin, spec->imux_pins[imux->num_items] = pin; snd_hda_add_imux_item(imux, label, cfg_idx, NULL); imux_added = true; + if (spec->dyn_adc_switch) + spec->dyn_adc_idx[imux_idx] = c; } } @@ -3150,7 +3155,9 @@ static int create_input_ctls(struct hda_codec *codec) } } - if (mixer && spec->add_stereo_mix_input) { + /* add stereo mix when explicitly enabled via hint */ + if (mixer && spec->add_stereo_mix_input && + snd_hda_get_bool_hint(codec, "add_stereo_mix_input") > 0) { err = parse_capture_source(codec, mixer, CFG_IDX_MIX, num_adcs, "Stereo Mix", 0); if (err < 0) @@ -3916,7 +3923,7 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec) do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), spec->autocfg.line_out_pins, paths, on); } -EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); +EXPORT_SYMBOL_GPL(snd_hda_gen_update_outputs); static void call_update_outputs(struct hda_codec *codec) { @@ -3949,7 +3956,7 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) return; call_update_outputs(codec); } -EXPORT_SYMBOL_HDA(snd_hda_gen_hp_automute); +EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); /* standard line-out-automute helper */ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) @@ -3969,7 +3976,7 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jac return; call_update_outputs(codec); } -EXPORT_SYMBOL_HDA(snd_hda_gen_line_automute); +EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); /* standard mic auto-switch helper */ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack) @@ -3992,7 +3999,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja } mux_select(codec, 0, spec->am_entry[0].idx); } -EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch); +EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch); /* call appropriate hooks */ static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack) @@ -4305,11 +4312,11 @@ static int check_auto_mic_availability(struct hda_codec *codec) } /* power_filter hook; make inactive widgets into power down */ -static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, +unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, hda_nid_t nid, unsigned int power_state) { - if (power_state != AC_PWRST_D0) + if (power_state != AC_PWRST_D0 || nid == codec->afg) return power_state; if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER) return power_state; @@ -4317,6 +4324,7 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, return power_state; return AC_PWRST_D3; } +EXPORT_SYMBOL_GPL(snd_hda_gen_path_power_filter); /* mute all aamix inputs initially; parse up to the first leaves */ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) @@ -4374,7 +4382,8 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, spec->no_analog = 1; goto dig_only; } - return 0; /* can't find valid BIOS pin config */ + if (!cfg->num_inputs && !cfg->dig_in_pin) + return 0; /* can't find valid BIOS pin config */ } if (!spec->no_primary_hp && @@ -4442,6 +4451,19 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, if (err < 0) return err; + /* add stereo mix if available and not enabled yet */ + if (!spec->auto_mic && spec->mixer_nid && + spec->add_stereo_mix_input && + spec->input_mux.num_items > 1 && + snd_hda_get_bool_hint(codec, "add_stereo_mix_input") < 0) { + err = parse_capture_source(codec, spec->mixer_nid, + CFG_IDX_MIX, spec->num_all_adcs, + "Stereo Mix", 0); + if (err < 0) + return err; + } + + err = create_capture_mixers(codec); if (err < 0) return err; @@ -4494,7 +4516,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, return 1; } -EXPORT_SYMBOL_HDA(snd_hda_gen_parse_auto_config); +EXPORT_SYMBOL_GPL(snd_hda_gen_parse_auto_config); /* @@ -4576,7 +4598,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec) return 0; } -EXPORT_SYMBOL_HDA(snd_hda_gen_build_controls); +EXPORT_SYMBOL_GPL(snd_hda_gen_build_controls); /* @@ -5109,7 +5131,7 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec) return 0; } -EXPORT_SYMBOL_HDA(snd_hda_gen_build_pcms); +EXPORT_SYMBOL_GPL(snd_hda_gen_build_pcms); /* @@ -5183,6 +5205,23 @@ static void init_multi_io(struct hda_codec *codec) } } +static void init_aamix_paths(struct hda_codec *codec) +{ + struct hda_gen_spec *spec = codec->spec; + + if (!spec->have_aamix_ctl) + return; + update_aamix_paths(codec, spec->aamix_mode, spec->out_paths[0], + spec->aamix_out_paths[0], + spec->autocfg.line_out_type); + update_aamix_paths(codec, spec->aamix_mode, spec->hp_paths[0], + spec->aamix_out_paths[1], + AUTO_PIN_HP_OUT); + update_aamix_paths(codec, spec->aamix_mode, spec->speaker_paths[0], + spec->aamix_out_paths[2], + AUTO_PIN_SPEAKER_OUT); +} + /* set up input pins and loopback paths */ static void init_analog_input(struct hda_codec *codec) { @@ -5285,6 +5324,7 @@ int snd_hda_gen_init(struct hda_codec *codec) init_multi_out(codec); init_extra_out(codec); init_multi_io(codec); + init_aamix_paths(codec); init_analog_input(codec); init_input_src(codec); init_digital(codec); @@ -5302,7 +5342,7 @@ int snd_hda_gen_init(struct hda_codec *codec) hda_call_check_power_status(codec, 0x01); return 0; } -EXPORT_SYMBOL_HDA(snd_hda_gen_init); +EXPORT_SYMBOL_GPL(snd_hda_gen_init); /* * free the generic spec; @@ -5315,7 +5355,7 @@ void snd_hda_gen_free(struct hda_codec *codec) kfree(codec->spec); codec->spec = NULL; } -EXPORT_SYMBOL_HDA(snd_hda_gen_free); +EXPORT_SYMBOL_GPL(snd_hda_gen_free); #ifdef CONFIG_PM /* @@ -5327,7 +5367,7 @@ int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) struct hda_gen_spec *spec = codec->spec; return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); } -EXPORT_SYMBOL_HDA(snd_hda_gen_check_power_status); +EXPORT_SYMBOL_GPL(snd_hda_gen_check_power_status); #endif @@ -5372,4 +5412,7 @@ error: snd_hda_gen_free(codec); return err; } -EXPORT_SYMBOL_HDA(snd_hda_parse_generic_codec); +EXPORT_SYMBOL_GPL(snd_hda_parse_generic_codec); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Generic HD-audio codec parser"); diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 0929a06df812..07f767231c9f 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -335,5 +335,8 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec); #ifdef CONFIG_PM int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid); #endif +unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, + hda_nid_t nid, + unsigned int power_state); #endif /* __SOUND_HDA_GENERIC_H */ diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index fe0bda19de15..72d8389fb399 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c @@ -616,7 +616,7 @@ const char *snd_hda_get_hint(struct hda_codec *codec, const char *key) struct hda_hint *hint = get_hint(codec, key); return hint ? hint->val : NULL; } -EXPORT_SYMBOL_HDA(snd_hda_get_hint); +EXPORT_SYMBOL_GPL(snd_hda_get_hint); int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) { @@ -642,7 +642,7 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) mutex_unlock(&codec->user_mutex); return ret; } -EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); +EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint); int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) { @@ -663,7 +663,7 @@ int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp) mutex_unlock(&codec->user_mutex); return ret; } -EXPORT_SYMBOL_HDA(snd_hda_get_int_hint); +EXPORT_SYMBOL_GPL(snd_hda_get_int_hint); #endif /* CONFIG_SND_HDA_RECONFIG */ #ifdef CONFIG_SND_HDA_PATCH_LOADER @@ -762,20 +762,50 @@ DEFINE_PARSE_ID_MODE(revision_id); struct hda_patch_item { const char *tag; + const char *alias; void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); - int need_codec; }; static struct hda_patch_item patch_items[NUM_LINE_MODES] = { - [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 }, - [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 }, - [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 }, - [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 }, - [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 }, - [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 }, - [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 }, - [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 }, - [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 }, + [LINE_MODE_CODEC] = { + .tag = "[codec]", + .parser = parse_codec_mode, + }, + [LINE_MODE_MODEL] = { + .tag = "[model]", + .parser = parse_model_mode, + }, + [LINE_MODE_VERB] = { + .tag = "[verb]", + .alias = "[init_verbs]", + .parser = parse_verb_mode, + }, + [LINE_MODE_PINCFG] = { + .tag = "[pincfg]", + .alias = "[user_pin_configs]", + .parser = parse_pincfg_mode, + }, + [LINE_MODE_HINT] = { + .tag = "[hint]", + .alias = "[hints]", + .parser = parse_hint_mode + }, + [LINE_MODE_VENDOR_ID] = { + .tag = "[vendor_id]", + .parser = parse_vendor_id_mode, + }, + [LINE_MODE_SUBSYSTEM_ID] = { + .tag = "[subsystem_id]", + .parser = parse_subsystem_id_mode, + }, + [LINE_MODE_REVISION_ID] = { + .tag = "[revision_id]", + .parser = parse_revision_id_mode, + }, + [LINE_MODE_CHIP_NAME] = { + .tag = "[chip_name]", + .parser = parse_chip_name_mode, + }, }; /* check the line starting with '[' -- change the parser mode accodingly */ @@ -787,6 +817,8 @@ static int parse_line_mode(char *buf, struct hda_bus *bus) continue; if (strmatch(buf, patch_items[i].tag)) return i; + if (patch_items[i].alias && strmatch(buf, patch_items[i].alias)) + return i; } return LINE_MODE_NONE; } @@ -846,10 +878,10 @@ int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf) if (*buf == '[') line_mode = parse_line_mode(buf, bus); else if (patch_items[line_mode].parser && - (codec || !patch_items[line_mode].need_codec)) + (codec || line_mode <= LINE_MODE_CODEC)) patch_items[line_mode].parser(buf, bus, &codec); } return 0; } -EXPORT_SYMBOL_HDA(snd_hda_load_patch); +EXPORT_SYMBOL_GPL(snd_hda_load_patch); #endif /* CONFIG_SND_HDA_PATCH_LOADER */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 956871d8b3d2..fa2879a21a50 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -297,9 +297,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define ULI_NUM_CAPTURE 5 #define ULI_NUM_PLAYBACK 6 -/* ATI HDMI has 1 playback and 0 capture */ +/* ATI HDMI may have up to 8 playbacks and 0 capture */ #define ATIHDMI_NUM_CAPTURE 0 -#define ATIHDMI_NUM_PLAYBACK 1 +#define ATIHDMI_NUM_PLAYBACK 8 /* TERA has 4 playback and 3 capture */ #define TERA_NUM_CAPTURE 3 @@ -431,6 +431,8 @@ struct azx_dev { struct timecounter azx_tc; struct cyclecounter azx_cc; + int delay_negative_threshold; + #ifdef CONFIG_SND_HDA_DSP_LOADER struct mutex dsp_mutex; #endif @@ -543,9 +545,7 @@ struct azx { /* for pending irqs */ struct work_struct irq_pending_work; -#ifdef CONFIG_SND_HDA_I915 struct work_struct probe_work; -#endif /* reboot notifier (for mysterious hangup problem at power-down) */ struct notifier_block reboot_notifier; @@ -2197,6 +2197,15 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) goto unlock; } + /* when LPIB delay correction gives a small negative value, + * we ignore it; currently set the threshold statically to + * 64 frames + */ + if (runtime->period_size > 64) + azx_dev->delay_negative_threshold = -frames_to_bytes(runtime, 64); + else + azx_dev->delay_negative_threshold = 0; + /* wallclk has 24Mhz clock source */ azx_dev->period_wallclk = (((runtime->period_size * 24000) / runtime->rate) * 1000); @@ -2449,8 +2458,12 @@ static unsigned int azx_get_position(struct azx *chip, delay = pos - lpib_pos; else delay = lpib_pos - pos; - if (delay < 0) - delay += azx_dev->bufsize; + if (delay < 0) { + if (delay >= azx_dev->delay_negative_threshold) + delay = 0; + else + delay += azx_dev->bufsize; + } if (delay >= azx_dev->period_bytes) { snd_printk(KERN_WARNING SFX "%s: Unstable LPIB (%d >= %d); " @@ -3504,12 +3517,10 @@ static void azx_check_snoop_available(struct azx *chip) } } -#ifdef CONFIG_SND_HDA_I915 static void azx_probe_work(struct work_struct *work) { azx_probe_continue(container_of(work, struct azx, probe_work)); } -#endif /* * constructor @@ -3586,10 +3597,8 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, return err; } -#ifdef CONFIG_SND_HDA_I915 /* continue probing in work context as may trigger request module */ INIT_WORK(&chip->probe_work, azx_probe_work); -#endif *rchip = chip; @@ -3809,7 +3818,7 @@ static int azx_probe(struct pci_dev *pci, static int dev; struct snd_card *card; struct azx *chip; - bool probe_now; + bool schedule_probe; int err; if (dev >= SNDRV_CARDS) @@ -3848,7 +3857,7 @@ static int azx_probe(struct pci_dev *pci, chip->disabled = true; } - probe_now = !chip->disabled; + schedule_probe = !chip->disabled; #ifdef CONFIG_SND_HDA_PATCH_LOADER if (patch[dev] && *patch[dev]) { @@ -3859,25 +3868,17 @@ static int azx_probe(struct pci_dev *pci, azx_firmware_cb); if (err < 0) goto out_free; - probe_now = false; /* continued in azx_firmware_cb() */ + schedule_probe = false; /* continued in azx_firmware_cb() */ } #endif /* CONFIG_SND_HDA_PATCH_LOADER */ - /* continue probing in work context, avoid request_module deadlock */ - if (probe_now && (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)) { -#ifdef CONFIG_SND_HDA_I915 - probe_now = false; - schedule_work(&chip->probe_work); -#else +#ifndef CONFIG_SND_HDA_I915 + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) snd_printk(KERN_ERR SFX "Haswell must build in CONFIG_SND_HDA_I915\n"); #endif - } - if (probe_now) { - err = azx_probe_continue(chip); - if (err < 0) - goto out_free; - } + if (schedule_probe) + schedule_work(&chip->probe_work); dev++; if (chip->disabled) @@ -3983,7 +3984,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, /* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point */ { PCI_DEVICE(0x8086, 0x8c20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, @@ -4008,6 +4009,9 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, { PCI_DEVICE(0x8086, 0x0d0c), .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, + /* Broadwell */ + { PCI_DEVICE(0x8086, 0x160c), + .driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL }, /* 5 Series/3400 */ { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index afe594411a56..9746d73cec52 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -34,7 +34,7 @@ bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) return false; return true; } -EXPORT_SYMBOL_HDA(is_jack_detectable); +EXPORT_SYMBOL_GPL(is_jack_detectable); /* execute pin sense measurement */ static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) @@ -71,7 +71,7 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) return jack; return NULL; } -EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); +EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get); /** * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag @@ -89,7 +89,7 @@ snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) return jack; return NULL; } -EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag); +EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag); /** * snd_hda_jack_tbl_new - create a jack-table entry for the given NID @@ -108,7 +108,7 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) jack->tag = codec->jacktbl.used; return jack; } -EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new); +EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_new); void snd_hda_jack_tbl_clear(struct hda_codec *codec) { @@ -172,7 +172,7 @@ void snd_hda_jack_set_dirty_all(struct hda_codec *codec) if (jack->nid) jack->jack_dirty = 1; } -EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all); +EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all); /** * snd_hda_pin_sense - execute pin sense measurement @@ -191,7 +191,7 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) } return read_pin_sense(codec, nid); } -EXPORT_SYMBOL_HDA(snd_hda_pin_sense); +EXPORT_SYMBOL_GPL(snd_hda_pin_sense); /** * snd_hda_jack_detect_state - query pin Presence Detect status @@ -211,7 +211,7 @@ int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid) else return HDA_JACK_NOT_PRESENT; } -EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state); +EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state); /** * snd_hda_jack_detect_enable - enable the jack-detection @@ -236,14 +236,14 @@ int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | jack->tag); } -EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable_callback); +EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback); int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, unsigned char action) { return snd_hda_jack_detect_enable_callback(codec, nid, action, NULL); } -EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); +EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable); /** * snd_hda_jack_set_gating_jack - Set gating jack. @@ -264,7 +264,7 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, return 0; } -EXPORT_SYMBOL_HDA(snd_hda_jack_set_gating_jack); +EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack); /** * snd_hda_jack_report_sync - sync the states of all jacks and report if changed @@ -297,7 +297,7 @@ void snd_hda_jack_report_sync(struct hda_codec *codec) #endif } } -EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync); +EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync); #ifdef CONFIG_SND_HDA_INPUT_JACK /* guess the jack type from the pin-config */ @@ -377,7 +377,7 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, { return __snd_hda_jack_add_kctl(codec, nid, name, idx, false); } -EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); +EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl); /* get the unique index number for the given kctl name */ static int get_unique_index(struct hda_codec *codec, const char *name, int idx) @@ -493,7 +493,7 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, return err; return 0; } -EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls); +EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctls); static void call_jack_callback(struct hda_codec *codec, struct hda_jack_tbl *jack) @@ -521,7 +521,7 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res) call_jack_callback(codec, event); snd_hda_jack_report_sync(codec); } -EXPORT_SYMBOL_HDA(snd_hda_jack_unsol_event); +EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event); void snd_hda_jack_poll_all(struct hda_codec *codec) { @@ -542,5 +542,5 @@ void snd_hda_jack_poll_all(struct hda_codec *codec) if (changes) snd_hda_jack_report_sync(codec); } -EXPORT_SYMBOL_HDA(snd_hda_jack_poll_all); +EXPORT_SYMBOL_GPL(snd_hda_jack_poll_all); diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d398b648bb5d..da80c5bd7fd4 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -352,14 +352,8 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, /* * generic codec parser */ -#ifdef CONFIG_SND_HDA_GENERIC int snd_hda_parse_generic_codec(struct hda_codec *codec); -#else -static inline int snd_hda_parse_generic_codec(struct hda_codec *codec) -{ - return -ENODEV; -} -#endif +int snd_hda_parse_hdmi_codec(struct hda_codec *codec); /* * generic proc interface diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 699262a3e07a..7a426ed491f2 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -185,7 +185,7 @@ static const struct hda_codec_ops ad198x_auto_patch_ops = { }; -static int ad198x_parse_auto_config(struct hda_codec *codec) +static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp) { struct ad198x_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->gen.autocfg; @@ -195,7 +195,8 @@ static int ad198x_parse_auto_config(struct hda_codec *codec) codec->no_trigger_sense = 1; codec->no_sticky_stream = 1; - spec->gen.indep_hp = 1; + spec->gen.indep_hp = indep_hp; + spec->gen.add_stereo_mix_input = 1; err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); if (err < 0) @@ -280,11 +281,11 @@ static const struct hda_fixup ad1986a_fixups[] = { .v.pins = (const struct hda_pintbl[]) { { 0x1a, 0x02214021 }, /* headphone */ { 0x1b, 0x01014011 }, /* front */ - { 0x1c, 0x01013012 }, /* surround */ - { 0x1d, 0x01019015 }, /* clfe */ + { 0x1c, 0x01813030 }, /* line-in */ + { 0x1d, 0x01a19020 }, /* rear mic */ { 0x1e, 0x411111f0 }, /* N/A */ { 0x1f, 0x02a190f0 }, /* mic */ - { 0x20, 0x018130f0 }, /* line-in */ + { 0x20, 0x411111f0 }, /* N/A */ {} }, }, @@ -378,7 +379,7 @@ static int patch_ad1986a(struct hda_codec *codec) ad1986a_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - err = ad198x_parse_auto_config(codec); + err = ad198x_parse_auto_config(codec, false); if (err < 0) { snd_hda_gen_free(codec); return err; @@ -480,7 +481,7 @@ static int patch_ad1983(struct hda_codec *codec) spec->gen.beep_nid = 0x10; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); - err = ad198x_parse_auto_config(codec); + err = ad198x_parse_auto_config(codec, false); if (err < 0) goto error; err = ad1983_add_spdif_mux_ctl(codec); @@ -567,7 +568,7 @@ static int patch_ad1981(struct hda_codec *codec) snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - err = ad198x_parse_auto_config(codec); + err = ad198x_parse_auto_config(codec, false); if (err < 0) goto error; err = ad1983_add_spdif_mux_ctl(codec); @@ -893,7 +894,7 @@ static int patch_ad1988(struct hda_codec *codec) snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - err = ad198x_parse_auto_config(codec); + err = ad198x_parse_auto_config(codec, true); if (err < 0) goto error; err = ad1988_add_spdif_mux_ctl(codec); @@ -1070,7 +1071,7 @@ static int patch_ad1884(struct hda_codec *codec) snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - err = ad198x_parse_auto_config(codec); + err = ad198x_parse_auto_config(codec, true); if (err < 0) goto error; err = ad1983_add_spdif_mux_ctl(codec); @@ -1112,7 +1113,7 @@ static int patch_ad1882(struct hda_codec *codec) spec->gen.mixer_merge_nid = 0x21; spec->gen.beep_nid = 0x10; set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); - err = ad198x_parse_auto_config(codec); + err = ad198x_parse_auto_config(codec, true); if (err < 0) goto error; err = ad1988_add_spdif_mux_ctl(codec); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 3fbf2883e06e..4e0ec146553d 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3240,102 +3240,8 @@ enum { CXT_FIXUP_THINKPAD_ACPI, }; -#if IS_ENABLED(CONFIG_THINKPAD_ACPI) - -#include -#include - -static int (*led_set_func)(int, bool); - -static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context, - void **rv) -{ - bool *found = context; - *found = true; - return AE_OK; -} - -static bool is_thinkpad(struct hda_codec *codec) -{ - bool found = false; - if (codec->subsystem_id >> 16 != 0x17aa) - return false; - if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found) - return true; - found = false; - return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found; -} - -static void update_tpacpi_mute_led(void *private_data, int enabled) -{ - struct hda_codec *codec = private_data; - struct conexant_spec *spec = codec->spec; - - if (spec->dynamic_eapd) - cx_auto_vmaster_hook(private_data, enabled); - - if (led_set_func) - led_set_func(TPACPI_LED_MUTE, !enabled); -} - -static void update_tpacpi_micmute_led(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) -{ - if (!ucontrol || !led_set_func) - return; - if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { - /* TODO: How do I verify if it's a mono or stereo here? */ - bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; - led_set_func(TPACPI_LED_MICMUTE, !val); - } -} - -static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, - const struct hda_fixup *fix, int action) -{ - struct conexant_spec *spec = codec->spec; - - bool removefunc = false; - - if (action == HDA_FIXUP_ACT_PROBE) { - if (!is_thinkpad(codec)) - return; - if (!led_set_func) - led_set_func = symbol_request(tpacpi_led_set); - if (!led_set_func) { - snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n"); - return; - } - - removefunc = true; - if (led_set_func(TPACPI_LED_MUTE, false) >= 0) { - spec->gen.vmaster_mute.hook = update_tpacpi_mute_led; - removefunc = false; - } - if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { - if (spec->gen.num_adc_nids > 1) - snd_printdd("Skipping micmute LED control due to several ADCs"); - else { - spec->gen.cap_sync_hook = update_tpacpi_micmute_led; - removefunc = false; - } - } - } - - if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { - symbol_put(tpacpi_led_set); - led_set_func = NULL; - } -} - -#else - -static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, - const struct hda_fixup *fix, int action) -{ -} - -#endif +/* for hda_fixup_thinkpad_acpi() */ +#include "thinkpad_helper.c" static void cxt_fixup_stereo_dmic(struct hda_codec *codec, const struct hda_fixup *fix, int action) @@ -3492,7 +3398,7 @@ static const struct hda_fixup cxt_fixups[] = { }, [CXT_FIXUP_THINKPAD_ACPI] = { .type = HDA_FIXUP_FUNC, - .v.func = cxt_fixup_thinkpad_acpi, + .v.func = hda_fixup_thinkpad_acpi, }, }; diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index f281c8068557..64f0a5e73a25 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -46,6 +46,9 @@ module_param(static_hdmi_pcm, bool, 0644); MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); #define is_haswell(codec) ((codec)->vendor_id == 0x80862807) +#define is_broadwell(codec) ((codec)->vendor_id == 0x80862808) +#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec)) + #define is_valleyview(codec) ((codec)->vendor_id == 0x80862882) struct hdmi_spec_per_cvt { @@ -1101,7 +1104,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, if (!channels) return; - if (is_haswell(codec)) + if (is_haswell_plus(codec)) snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); @@ -1280,7 +1283,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, struct hdmi_spec *spec = codec->spec; int err; - if (is_haswell(codec)) + if (is_haswell_plus(codec)) haswell_verify_D0(codec, cvt_nid, pin_nid); err = spec->ops.pin_hbr_setup(codec, pin_nid, is_hbr_format(format)); @@ -1421,7 +1424,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, mux_idx); /* configure unused pins to choose other converters */ - if (is_haswell(codec) || is_valleyview(codec)) + if (is_haswell_plus(codec) || is_valleyview(codec)) intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx); snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); @@ -1496,11 +1499,14 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) * specification worked this way. Hence, we just ignore the data in * the unsolicited response to avoid custom WARs. */ - int present = snd_hda_pin_sense(codec, pin_nid); + int present; bool update_eld = false; bool eld_changed = false; bool ret; + snd_hda_power_up(codec); + present = snd_hda_pin_sense(codec, pin_nid); + mutex_lock(&per_pin->lock); pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); if (pin_eld->monitor_present) @@ -1573,6 +1579,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) jack->block_report = !ret; mutex_unlock(&per_pin->lock); + snd_hda_power_down(codec); return ret; } @@ -1607,7 +1614,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) return 0; - if (is_haswell(codec)) + if (is_haswell_plus(codec)) intel_haswell_fixup_connect_list(codec, pin_nid); pin_idx = spec->num_pins; @@ -1694,21 +1701,6 @@ static int hdmi_parse_codec(struct hda_codec *codec) } } -#ifdef CONFIG_PM - /* We're seeing some problems with unsolicited hot plug events on - * PantherPoint after S3, if this is not enabled */ - if (codec->vendor_id == 0x80862806) - codec->bus->power_keep_link_on = 1; - /* - * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event - * can be lost and presence sense verb will become inaccurate if the - * HDA link is powered off at hot plug or hw initialization time. - */ - else if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & - AC_PWRST_EPSS)) - codec->bus->power_keep_link_on = 1; -#endif - return 0; } @@ -2260,18 +2252,22 @@ static int patch_generic_hdmi(struct hda_codec *codec) codec->spec = spec; hdmi_array_init(spec, 4); - if (is_haswell(codec)) { + if (is_haswell_plus(codec)) { intel_haswell_enable_all_pins(codec, true); intel_haswell_fixup_enable_dp12(codec); } + if (is_haswell(codec) || is_valleyview(codec)) { + codec->depop_delay = 0; + } + if (hdmi_parse_codec(codec) < 0) { codec->spec = NULL; kfree(spec); return -EINVAL; } codec->patch_ops = generic_hdmi_patch_ops; - if (is_haswell(codec)) { + if (is_haswell_plus(codec)) { codec->patch_ops.set_power_state = haswell_set_power_state; codec->dp_mst = true; } @@ -3217,6 +3213,15 @@ static int patch_via_hdmi(struct hda_codec *codec) return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID); } +/* + * called from hda_codec.c for generic HDMI support + */ +int snd_hda_parse_hdmi_codec(struct hda_codec *codec) +{ + return patch_generic_hdmi(codec); +} +EXPORT_SYMBOL_GPL(snd_hda_parse_hdmi_codec); + /* * patch entries */ @@ -3271,6 +3276,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi }, +{ .id = 0x80862808, .name = "Broadwell HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862882, .name = "Valleyview2 HDMI", .patch = patch_generic_hdmi }, { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, @@ -3326,6 +3332,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862804"); MODULE_ALIAS("snd-hda-codec-id:80862805"); MODULE_ALIAS("snd-hda-codec-id:80862806"); MODULE_ALIAS("snd-hda-codec-id:80862807"); +MODULE_ALIAS("snd-hda-codec-id:80862808"); MODULE_ALIAS("snd-hda-codec-id:80862880"); MODULE_ALIAS("snd-hda-codec-id:80862882"); MODULE_ALIAS("snd-hda-codec-id:808629fb"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c5646941539a..f9b22fb6dd0b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -118,7 +118,8 @@ struct alc_spec { int init_amp; int codec_variant; /* flag for other variants */ - bool has_alc5505_dsp; + unsigned int has_alc5505_dsp:1; + unsigned int no_depop_delay:1; /* for PLL fix */ hda_nid_t pll_nid; @@ -280,8 +281,11 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) */ static void alc_eapd_shutup(struct hda_codec *codec) { + struct alc_spec *spec = codec->spec; + alc_auto_setup_eapd(codec, false); - msleep(200); + if (!spec->no_depop_delay) + msleep(200); snd_hda_shutup_pins(codec); } @@ -365,6 +369,17 @@ static void alc_fixup_sku_ignore(struct hda_codec *codec, } } +static void alc_fixup_no_depop_delay(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PROBE) { + spec->no_depop_delay = 1; + codec->depop_delay = 0; + } +} + static int alc_auto_parse_customize_define(struct hda_codec *codec) { unsigned int ass, tmp, i; @@ -454,9 +469,7 @@ static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) * 7 ~ 0 : Assembly ID * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 */ -static int alc_subsystem_id(struct hda_codec *codec, - hda_nid_t porta, hda_nid_t porte, - hda_nid_t portd, hda_nid_t porti) +static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) { unsigned int ass, tmp, i; unsigned nid; @@ -546,14 +559,7 @@ do_sku: spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { hda_nid_t nid; tmp = (ass >> 11) & 0x3; /* HP to chassis */ - if (tmp == 0) - nid = porta; - else if (tmp == 1) - nid = porte; - else if (tmp == 2) - nid = portd; - else if (tmp == 3) - nid = porti; + nid = ports[tmp]; if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, spec->gen.autocfg.line_outs)) return 1; @@ -566,7 +572,7 @@ do_sku: * ports contains an array of 4 pin NIDs for port-A, E, D and I */ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) { - if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) { + if (!alc_subsystem_id(codec, ports)) { struct alc_spec *spec = codec->spec; snd_printd("realtek: " "Enable default setup for auto mode as fallback\n"); @@ -863,7 +869,10 @@ static int alc_suspend(struct hda_codec *codec) #ifdef CONFIG_PM static int alc_resume(struct hda_codec *codec) { - msleep(150); /* to avoid pop noise */ + struct alc_spec *spec = codec->spec; + + if (!spec->no_depop_delay) + msleep(150); /* to avoid pop noise */ codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); @@ -903,7 +912,7 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name) } /* - * Rename codecs appropriately from COEF value + * Rename codecs appropriately from COEF value or subvendor id */ struct alc_codec_rename_table { unsigned int vendor_id; @@ -912,6 +921,13 @@ struct alc_codec_rename_table { const char *name; }; +struct alc_codec_rename_pci_table { + unsigned int codec_vendor_id; + unsigned short pci_subvendor; + unsigned short pci_subdevice; + const char *name; +}; + static struct alc_codec_rename_table rename_tbl[] = { { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, @@ -931,9 +947,20 @@ static struct alc_codec_rename_table rename_tbl[] = { { } /* terminator */ }; +static struct alc_codec_rename_pci_table rename_pci_tbl[] = { + { 0x10ec0280, 0x1028, 0, "ALC3220" }, + { 0x10ec0282, 0x1028, 0, "ALC3221" }, + { 0x10ec0283, 0x1028, 0, "ALC3223" }, + { 0x10ec0292, 0x1028, 0, "ALC3226" }, + { 0x10ec0255, 0x1028, 0, "ALC3234" }, + { 0x10ec0668, 0x1028, 0, "ALC3661" }, + { } /* terminator */ +}; + static int alc_codec_rename_from_preset(struct hda_codec *codec) { const struct alc_codec_rename_table *p; + const struct alc_codec_rename_pci_table *q; for (p = rename_tbl; p->vendor_id; p++) { if (p->vendor_id != codec->vendor_id) @@ -941,6 +968,17 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec) if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) return alc_codec_rename(codec, p->name); } + + for (q = rename_pci_tbl; q->codec_vendor_id; q++) { + if (q->codec_vendor_id != codec->vendor_id) + continue; + if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) + continue; + if (!q->pci_subdevice || + q->pci_subdevice == codec->bus->pci->subsystem_device) + return alc_codec_rename(codec, q->name); + } + return 0; } @@ -1763,6 +1801,7 @@ enum { ALC882_FIXUP_ACER_ASPIRE_7736, ALC882_FIXUP_ASUS_W90V, ALC889_FIXUP_CD, + ALC889_FIXUP_FRONT_HP_NO_PRESENCE, ALC889_FIXUP_VAIO_TT, ALC888_FIXUP_EEE1601, ALC882_FIXUP_EAPD, @@ -1980,6 +2019,15 @@ static const struct hda_fixup alc882_fixups[] = { { } } }, + [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ + { } + }, + .chained = true, + .chain_id = ALC889_FIXUP_CD, + }, [ALC889_FIXUP_VAIO_TT] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -2211,7 +2259,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), @@ -2314,6 +2362,7 @@ enum { ALC262_FIXUP_BENQ, ALC262_FIXUP_BENQ_T31, ALC262_FIXUP_INV_DMIC, + ALC262_FIXUP_INTEL_BAYLEYBAY, }; static const struct hda_fixup alc262_fixups[] = { @@ -2378,6 +2427,10 @@ static const struct hda_fixup alc262_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, + [ALC262_FIXUP_INTEL_BAYLEYBAY] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_no_depop_delay, + }, }; static const struct snd_pci_quirk alc262_fixup_tbl[] = { @@ -2389,6 +2442,7 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), + SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), {} }; @@ -3526,6 +3580,15 @@ static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, alc_fixup_headset_mode(codec, fix, action); } +static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + struct alc_spec *spec = codec->spec; + spec->gen.auto_mute_via_amp = 1; + } +} + static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -3717,101 +3780,18 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec, static void alc290_fixup_mono_speakers(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - if (action == HDA_FIXUP_ACT_PRE_PROBE) - /* Remove DAC node 0x03, as it seems to be - giving mono output */ - snd_hda_override_wcaps(codec, 0x03, 0); -} - -#if IS_ENABLED(CONFIG_THINKPAD_ACPI) - -#include -#include - -static int (*led_set_func)(int, bool); - -static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context, - void **rv) -{ - bool *found = context; - *found = true; - return AE_OK; -} - -static bool is_thinkpad(struct hda_codec *codec) -{ - bool found = false; - if (codec->subsystem_id >> 16 != 0x17aa) - return false; - if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found) - return true; - found = false; - return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found; -} - -static void update_tpacpi_mute_led(void *private_data, int enabled) -{ - if (led_set_func) - led_set_func(TPACPI_LED_MUTE, !enabled); -} - -static void update_tpacpi_micmute_led(struct hda_codec *codec, - struct snd_ctl_elem_value *ucontrol) -{ - if (!ucontrol || !led_set_func) - return; - if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { - /* TODO: How do I verify if it's a mono or stereo here? */ - bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; - led_set_func(TPACPI_LED_MICMUTE, !val); + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + /* DAC node 0x03 is giving mono output. We therefore want to + make sure 0x14 (front speaker) and 0x15 (headphones) use the + stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ + hda_nid_t conn1[2] = { 0x0c }; + snd_hda_override_conn_list(codec, 0x14, 1, conn1); + snd_hda_override_conn_list(codec, 0x15, 1, conn1); } } -static void alc_fixup_thinkpad_acpi(struct hda_codec *codec, - const struct hda_fixup *fix, int action) -{ - struct alc_spec *spec = codec->spec; - bool removefunc = false; - - if (action == HDA_FIXUP_ACT_PROBE) { - if (!is_thinkpad(codec)) - return; - if (!led_set_func) - led_set_func = symbol_request(tpacpi_led_set); - if (!led_set_func) { - snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n"); - return; - } - - removefunc = true; - if (led_set_func(TPACPI_LED_MUTE, false) >= 0) { - spec->gen.vmaster_mute.hook = update_tpacpi_mute_led; - removefunc = false; - } - if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { - if (spec->gen.num_adc_nids > 1) - snd_printdd("Skipping micmute LED control due to several ADCs"); - else { - spec->gen.cap_sync_hook = update_tpacpi_micmute_led; - removefunc = false; - } - } - } - - if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { - symbol_put(tpacpi_led_set); - led_set_func = NULL; - } -} - -#else - -static void alc_fixup_thinkpad_acpi(struct hda_codec *codec, - const struct hda_fixup *fix, int action) -{ -} - -#endif +/* for hda_fixup_thinkpad_acpi() */ +#include "thinkpad_helper.c" enum { ALC269_FIXUP_SONY_VAIO, @@ -3860,6 +3840,9 @@ enum { ALC282_FIXUP_ASUS_TX300, ALC283_FIXUP_INT_MIC, ALC290_FIXUP_MONO_SPEAKERS, + ALC290_FIXUP_MONO_SPEAKERS_HSJACK, + ALC290_FIXUP_SUBWOOFER, + ALC290_FIXUP_SUBWOOFER_HSJACK, ALC269_FIXUP_THINKPAD_ACPI, ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ALC255_FIXUP_HEADSET_MODE, @@ -4182,15 +4165,37 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST }, + [ALC290_FIXUP_SUBWOOFER_HSJACK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x17, 0x90170112 }, /* subwoofer */ + { } + }, + .chained = true, + .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, + }, + [ALC290_FIXUP_SUBWOOFER] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x17, 0x90170112 }, /* subwoofer */ + { } + }, + .chained = true, + .chain_id = ALC290_FIXUP_MONO_SPEAKERS, + }, [ALC290_FIXUP_MONO_SPEAKERS] = { .type = HDA_FIXUP_FUNC, .v.func = alc290_fixup_mono_speakers, + }, + [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc290_fixup_mono_speakers, .chained = true, .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, }, [ALC269_FIXUP_THINKPAD_ACPI] = { .type = HDA_FIXUP_FUNC, - .v.func = alc_fixup_thinkpad_acpi, + .v.func = hda_fixup_thinkpad_acpi, }, [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, @@ -4229,6 +4234,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), @@ -4247,16 +4253,23 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS), + SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), + SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS), + SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), @@ -4502,7 +4515,7 @@ static int patch_alc269(struct hda_codec *codec) } if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { - spec->has_alc5505_dsp = true; + spec->has_alc5505_dsp = 1; spec->init_hook = alc5505_dsp_init; } @@ -4841,6 +4854,7 @@ enum { ALC662_FIXUP_BASS_CHMAP, ALC662_FIXUP_BASS_1A, ALC662_FIXUP_BASS_1A_CHMAP, + ALC668_FIXUP_AUTO_MUTE, }; static const struct hda_fixup alc662_fixups[] = { @@ -5001,6 +5015,12 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_inv_dmic_0x12, }, + [ALC668_FIXUP_AUTO_MUTE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_auto_mute_via_amp, + .chained = true, + .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE + }, [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -5046,11 +5066,12 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), + SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), + SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 088a5afbd1b9..6998cf29b9bc 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -368,6 +368,17 @@ static int stac_vrefout_set(struct hda_codec *codec, return 1; } +/* prevent codec AFG to D3 state when vref-out pin is used for mute LED */ +/* this hook is set in stac_setup_gpio() */ +static unsigned int stac_vref_led_power_filter(struct hda_codec *codec, + hda_nid_t nid, + unsigned int power_state) +{ + if (nid == codec->afg && power_state == AC_PWRST_D3) + return AC_PWRST_D1; + return snd_hda_gen_path_power_filter(codec, nid, power_state); +} + /* update mute-LED accoring to the master switch */ static void stac_update_led_status(struct hda_codec *codec, int enabled) { @@ -4260,30 +4271,8 @@ static int stac_suspend(struct hda_codec *codec) stac_shutup(codec); return 0; } - -static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg, - unsigned int power_state) -{ - unsigned int afg_power_state = power_state; - struct sigmatel_spec *spec = codec->spec; - - if (power_state == AC_PWRST_D3) { - if (spec->vref_mute_led_nid) { - /* with vref-out pin used for mute led control - * codec AFG is prevented from D3 state - */ - afg_power_state = AC_PWRST_D1; - } - /* this delay seems necessary to avoid click noise at power-down */ - msleep(100); - } - snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, - afg_power_state); - snd_hda_codec_set_power_to_all(codec, fg, power_state); -} #else #define stac_suspend NULL -#define stac_set_power_state NULL #endif /* CONFIG_PM */ static const struct hda_codec_ops stac_patch_ops = { @@ -4466,8 +4455,7 @@ static void stac_setup_gpio(struct hda_codec *codec) spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { - codec->patch_ops.set_power_state = - stac_set_power_state; + codec->power_filter = stac_vref_led_power_filter; } } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 0bc20ef5687a..f84195f3ea31 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -138,6 +138,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec) spec->gen.indep_hp = 1; spec->gen.keep_eapd_on = 1; spec->gen.pcm_playback_hook = via_playback_pcm_hook; + spec->gen.add_stereo_mix_input = 1; return spec; } diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c new file mode 100644 index 000000000000..5799fbc24c28 --- /dev/null +++ b/sound/pci/hda/thinkpad_helper.c @@ -0,0 +1,99 @@ +/* Helper functions for Thinkpad LED control; + * to be included from codec driver + */ + +#if IS_ENABLED(CONFIG_THINKPAD_ACPI) + +#include +#include + +static int (*led_set_func)(int, bool); +static void (*old_vmaster_hook)(void *, int); + +static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context, + void **rv) +{ + bool *found = context; + *found = true; + return AE_OK; +} + +static bool is_thinkpad(struct hda_codec *codec) +{ + bool found = false; + if (codec->subsystem_id >> 16 != 0x17aa) + return false; + if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found) + return true; + found = false; + return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found; +} + +static void update_tpacpi_mute_led(void *private_data, int enabled) +{ + if (old_vmaster_hook) + old_vmaster_hook(private_data, enabled); + + if (led_set_func) + led_set_func(TPACPI_LED_MUTE, !enabled); +} + +static void update_tpacpi_micmute_led(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol) +{ + if (!ucontrol || !led_set_func) + return; + if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { + /* TODO: How do I verify if it's a mono or stereo here? */ + bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; + led_set_func(TPACPI_LED_MICMUTE, !val); + } +} + +static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct hda_gen_spec *spec = codec->spec; + bool removefunc = false; + + if (action == HDA_FIXUP_ACT_PROBE) { + if (!is_thinkpad(codec)) + return; + if (!led_set_func) + led_set_func = symbol_request(tpacpi_led_set); + if (!led_set_func) { + snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n"); + return; + } + + removefunc = true; + if (led_set_func(TPACPI_LED_MUTE, false) >= 0) { + old_vmaster_hook = spec->vmaster_mute.hook; + spec->vmaster_mute.hook = update_tpacpi_mute_led; + removefunc = false; + } + if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { + if (spec->num_adc_nids > 1) + snd_printdd("Skipping micmute LED control due to several ADCs"); + else { + spec->cap_sync_hook = update_tpacpi_micmute_led; + removefunc = false; + } + } + } + + if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { + symbol_put(tpacpi_led_set); + led_set_func = NULL; + old_vmaster_hook = NULL; + } +} + +#else /* CONFIG_THINKPAD_ACPI */ + +static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ +} + +#endif /* CONFIG_THINKPAD_ACPI */ diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index f59a321a6d6a..bd90c80bb494 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -584,10 +584,6 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer { dmab->dev.type = SNDRV_DMA_TYPE_DEV; dmab->dev.dev = snd_dma_pci_data(pci); - if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) { - if (dmab->bytes >= size) - return 0; - } if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), size, dmab) < 0) return -ENOMEM; @@ -596,10 +592,8 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) { - if (dmab->area) { - dmab->dev.dev = NULL; /* make it anonymous */ - snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci)); - } + if (dmab->area) + snd_dma_free_pages(dmab); } diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index b96d9e1adf6d..1503ee3585fd 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -285,7 +285,7 @@ static char channel_map_9636_ds[26] = { /* ADAT channels are remapped */ 1, 3, 5, 7, 9, 11, 13, 15, /* channels 8 and 9 are S/PDIF */ - 24, 25 + 24, 25, /* others don't exist */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; @@ -294,10 +294,6 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer { dmab->dev.type = SNDRV_DMA_TYPE_DEV; dmab->dev.dev = snd_dma_pci_data(pci); - if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) { - if (dmab->bytes >= size) - return 0; - } if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), size, dmab) < 0) return -ENOMEM; @@ -306,10 +302,8 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci) { - if (dmab->area) { - dmab->dev.dev = NULL; /* make it anonymous */ - snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci)); - } + if (dmab->area) + snd_dma_free_pages(dmab); } diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 5138b8493051..d62ce483a443 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -31,8 +31,10 @@ config SND_SOC_GENERIC_DMAENGINE_PCM select SND_DMAENGINE_PCM # All the supported SoCs +source "sound/soc/adi/Kconfig" source "sound/soc/atmel/Kconfig" source "sound/soc/au1x/Kconfig" +source "sound/soc/bcm/Kconfig" source "sound/soc/blackfin/Kconfig" source "sound/soc/cirrus/Kconfig" source "sound/soc/davinci/Kconfig" @@ -42,7 +44,7 @@ source "sound/soc/jz4740/Kconfig" source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/kirkwood/Kconfig" -source "sound/soc/mid-x86/Kconfig" +source "sound/soc/intel/Kconfig" source "sound/soc/mxs/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/samsung/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 8b9e70105dd2..62a1822e77bf 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -8,15 +8,17 @@ endif obj-$(CONFIG_SND_SOC) += snd-soc-core.o obj-$(CONFIG_SND_SOC) += codecs/ obj-$(CONFIG_SND_SOC) += generic/ +obj-$(CONFIG_SND_SOC) += adi/ obj-$(CONFIG_SND_SOC) += atmel/ obj-$(CONFIG_SND_SOC) += au1x/ +obj-$(CONFIG_SND_SOC) += bcm/ obj-$(CONFIG_SND_SOC) += blackfin/ obj-$(CONFIG_SND_SOC) += cirrus/ obj-$(CONFIG_SND_SOC) += davinci/ obj-$(CONFIG_SND_SOC) += dwc/ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += jz4740/ -obj-$(CONFIG_SND_SOC) += mid-x86/ +obj-$(CONFIG_SND_SOC) += intel/ obj-$(CONFIG_SND_SOC) += mxs/ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ diff --git a/sound/soc/adi/Kconfig b/sound/soc/adi/Kconfig new file mode 100644 index 000000000000..dd763f55edac --- /dev/null +++ b/sound/soc/adi/Kconfig @@ -0,0 +1,21 @@ +config SND_SOC_ADI + tristate "Audio support for Analog Devices reference designs" + depends on MICROBLAZE || ARCH_ZYNQ || COMPILE_TEST + help + Audio support for various reference designs by Analog Devices. + +config SND_SOC_ADI_AXI_I2S + tristate "AXI-I2S support" + depends on SND_SOC_ADI + select SND_SOC_GENERIC_DMAENGINE_PCM + select REGMAP_MMIO + help + ASoC driver for the Analog Devices AXI-I2S softcore peripheral. + +config SND_SOC_ADI_AXI_SPDIF + tristate "AXI-SPDIF support" + depends on SND_SOC_ADI + select SND_SOC_GENERIC_DMAENGINE_PCM + select REGMAP_MMIO + help + ASoC driver for the Analog Devices AXI-SPDIF softcore peripheral. diff --git a/sound/soc/adi/Makefile b/sound/soc/adi/Makefile new file mode 100644 index 000000000000..64456c1e5347 --- /dev/null +++ b/sound/soc/adi/Makefile @@ -0,0 +1,5 @@ +snd-soc-adi-axi-i2s-objs := axi-i2s.o +snd-soc-adi-axi-spdif-objs := axi-spdif.o + +obj-$(CONFIG_SND_SOC_ADI_AXI_I2S) += snd-soc-adi-axi-i2s.o +obj-$(CONFIG_SND_SOC_ADI_AXI_SPDIF) += snd-soc-adi-axi-spdif.o diff --git a/sound/soc/adi/axi-i2s.c b/sound/soc/adi/axi-i2s.c new file mode 100644 index 000000000000..6058c1fd5070 --- /dev/null +++ b/sound/soc/adi/axi-i2s.c @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2012-2013, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define AXI_I2S_REG_RESET 0x00 +#define AXI_I2S_REG_CTRL 0x04 +#define AXI_I2S_REG_CLK_CTRL 0x08 +#define AXI_I2S_REG_STATUS 0x10 + +#define AXI_I2S_REG_RX_FIFO 0x28 +#define AXI_I2S_REG_TX_FIFO 0x2C + +#define AXI_I2S_RESET_GLOBAL BIT(0) +#define AXI_I2S_RESET_TX_FIFO BIT(1) +#define AXI_I2S_RESET_RX_FIFO BIT(2) + +#define AXI_I2S_CTRL_TX_EN BIT(0) +#define AXI_I2S_CTRL_RX_EN BIT(1) + +/* The frame size is configurable, but for now we always set it 64 bit */ +#define AXI_I2S_BITS_PER_FRAME 64 + +struct axi_i2s { + struct regmap *regmap; + struct clk *clk; + struct clk *clk_ref; + + struct snd_soc_dai_driver dai_driver; + + struct snd_dmaengine_dai_dma_data capture_dma_data; + struct snd_dmaengine_dai_dma_data playback_dma_data; + + struct snd_ratnum ratnum; + struct snd_pcm_hw_constraint_ratnums rate_constraints; +}; + +static int axi_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + unsigned int mask, val; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + mask = AXI_I2S_CTRL_RX_EN; + else + mask = AXI_I2S_CTRL_TX_EN; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + val = mask; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + val = 0; + break; + default: + return -EINVAL; + } + + regmap_update_bits(i2s->regmap, AXI_I2S_REG_CTRL, mask, val); + + return 0; +} + +static int axi_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + unsigned int bclk_div, word_size; + unsigned int bclk_rate; + + bclk_rate = params_rate(params) * AXI_I2S_BITS_PER_FRAME; + + word_size = AXI_I2S_BITS_PER_FRAME / 2 - 1; + bclk_div = DIV_ROUND_UP(clk_get_rate(i2s->clk_ref), bclk_rate) / 2 - 1; + + regmap_write(i2s->regmap, AXI_I2S_REG_CLK_CTRL, (word_size << 16) | + bclk_div); + + return 0; +} + +static int axi_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + uint32_t mask; + int ret; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + mask = AXI_I2S_RESET_RX_FIFO; + else + mask = AXI_I2S_RESET_TX_FIFO; + + regmap_write(i2s->regmap, AXI_I2S_REG_RESET, mask); + + ret = snd_pcm_hw_constraint_ratnums(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &i2s->rate_constraints); + if (ret) + return ret; + + return clk_prepare_enable(i2s->clk_ref); +} + +static void axi_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + + clk_disable_unprepare(i2s->clk_ref); +} + +static int axi_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct axi_i2s *i2s = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, + &i2s->capture_dma_data); + + return 0; +} + +static const struct snd_soc_dai_ops axi_i2s_dai_ops = { + .startup = axi_i2s_startup, + .shutdown = axi_i2s_shutdown, + .trigger = axi_i2s_trigger, + .hw_params = axi_i2s_hw_params, +}; + +static struct snd_soc_dai_driver axi_i2s_dai = { + .probe = axi_i2s_dai_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE, + }, + .ops = &axi_i2s_dai_ops, + .symmetric_rates = 1, +}; + +static const struct snd_soc_component_driver axi_i2s_component = { + .name = "axi-i2s", +}; + +static const struct regmap_config axi_i2s_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = AXI_I2S_REG_STATUS, +}; + +static int axi_i2s_probe(struct platform_device *pdev) +{ + struct resource *res; + struct axi_i2s *i2s; + void __iomem *base; + int ret; + + i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); + if (!i2s) + return -ENOMEM; + + platform_set_drvdata(pdev, i2s); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + i2s->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &axi_i2s_regmap_config); + if (IS_ERR(i2s->regmap)) + return PTR_ERR(i2s->regmap); + + i2s->clk = devm_clk_get(&pdev->dev, "axi"); + if (IS_ERR(i2s->clk)) + return PTR_ERR(i2s->clk); + + i2s->clk_ref = devm_clk_get(&pdev->dev, "ref"); + if (IS_ERR(i2s->clk_ref)) + return PTR_ERR(i2s->clk_ref); + + ret = clk_prepare_enable(i2s->clk); + if (ret) + return ret; + + i2s->playback_dma_data.addr = res->start + AXI_I2S_REG_TX_FIFO; + i2s->playback_dma_data.addr_width = 4; + i2s->playback_dma_data.maxburst = 1; + + i2s->capture_dma_data.addr = res->start + AXI_I2S_REG_RX_FIFO; + i2s->capture_dma_data.addr_width = 4; + i2s->capture_dma_data.maxburst = 1; + + i2s->ratnum.num = clk_get_rate(i2s->clk_ref) / 2 / AXI_I2S_BITS_PER_FRAME; + i2s->ratnum.den_step = 1; + i2s->ratnum.den_min = 1; + i2s->ratnum.den_max = 64; + + i2s->rate_constraints.rats = &i2s->ratnum; + i2s->rate_constraints.nrats = 1; + + regmap_write(i2s->regmap, AXI_I2S_REG_RESET, AXI_I2S_RESET_GLOBAL); + + ret = devm_snd_soc_register_component(&pdev->dev, &axi_i2s_component, + &axi_i2s_dai, 1); + if (ret) + goto err_clk_disable; + + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (ret) + goto err_clk_disable; + +err_clk_disable: + clk_disable_unprepare(i2s->clk); + return ret; +} + +static int axi_i2s_dev_remove(struct platform_device *pdev) +{ + struct axi_i2s *i2s = platform_get_drvdata(pdev); + + clk_disable_unprepare(i2s->clk); + + return 0; +} + +static const struct of_device_id axi_i2s_of_match[] = { + { .compatible = "adi,axi-i2s-1.00.a", }, + {}, +}; +MODULE_DEVICE_TABLE(of, axi_i2s_of_match); + +static struct platform_driver axi_i2s_driver = { + .driver = { + .name = "axi-i2s", + .owner = THIS_MODULE, + .of_match_table = axi_i2s_of_match, + }, + .probe = axi_i2s_probe, + .remove = axi_i2s_dev_remove, +}; +module_platform_driver(axi_i2s_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("AXI I2S driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/adi/axi-spdif.c b/sound/soc/adi/axi-spdif.c new file mode 100644 index 000000000000..198e3a4640f6 --- /dev/null +++ b/sound/soc/adi/axi-spdif.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2012-2013, Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define AXI_SPDIF_REG_CTRL 0x0 +#define AXI_SPDIF_REG_STAT 0x4 +#define AXI_SPDIF_REG_TX_FIFO 0xc + +#define AXI_SPDIF_CTRL_TXDATA BIT(1) +#define AXI_SPDIF_CTRL_TXEN BIT(0) +#define AXI_SPDIF_CTRL_CLKDIV_OFFSET 8 +#define AXI_SPDIF_CTRL_CLKDIV_MASK (0xff << 8) + +#define AXI_SPDIF_FREQ_44100 (0x0 << 6) +#define AXI_SPDIF_FREQ_48000 (0x1 << 6) +#define AXI_SPDIF_FREQ_32000 (0x2 << 6) +#define AXI_SPDIF_FREQ_NA (0x3 << 6) + +struct axi_spdif { + struct regmap *regmap; + struct clk *clk; + struct clk *clk_ref; + + struct snd_dmaengine_dai_dma_data dma_data; + + struct snd_ratnum ratnum; + struct snd_pcm_hw_constraint_ratnums rate_constraints; +}; + +static int axi_spdif_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + unsigned int val; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + val = AXI_SPDIF_CTRL_TXDATA; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + val = 0; + break; + default: + return -EINVAL; + } + + regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL, + AXI_SPDIF_CTRL_TXDATA, val); + + return 0; +} + +static int axi_spdif_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + unsigned int rate = params_rate(params); + unsigned int clkdiv, stat; + + switch (params_rate(params)) { + case 32000: + stat = AXI_SPDIF_FREQ_32000; + break; + case 44100: + stat = AXI_SPDIF_FREQ_44100; + break; + case 48000: + stat = AXI_SPDIF_FREQ_48000; + break; + default: + stat = AXI_SPDIF_FREQ_NA; + break; + } + + clkdiv = DIV_ROUND_CLOSEST(clk_get_rate(spdif->clk_ref), + rate * 64 * 2) - 1; + clkdiv <<= AXI_SPDIF_CTRL_CLKDIV_OFFSET; + + regmap_write(spdif->regmap, AXI_SPDIF_REG_STAT, stat); + regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL, + AXI_SPDIF_CTRL_CLKDIV_MASK, clkdiv); + + return 0; +} + +static int axi_spdif_dai_probe(struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, &spdif->dma_data, NULL); + + return 0; +} + +static int axi_spdif_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + int ret; + + ret = snd_pcm_hw_constraint_ratnums(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &spdif->rate_constraints); + if (ret) + return ret; + + ret = clk_prepare_enable(spdif->clk_ref); + if (ret) + return ret; + + regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL, + AXI_SPDIF_CTRL_TXEN, AXI_SPDIF_CTRL_TXEN); + + return 0; +} + +static void axi_spdif_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct axi_spdif *spdif = snd_soc_dai_get_drvdata(dai); + + regmap_update_bits(spdif->regmap, AXI_SPDIF_REG_CTRL, + AXI_SPDIF_CTRL_TXEN, 0); + + clk_disable_unprepare(spdif->clk_ref); +} + +static const struct snd_soc_dai_ops axi_spdif_dai_ops = { + .startup = axi_spdif_startup, + .shutdown = axi_spdif_shutdown, + .trigger = axi_spdif_trigger, + .hw_params = axi_spdif_hw_params, +}; + +static struct snd_soc_dai_driver axi_spdif_dai = { + .probe = axi_spdif_dai_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &axi_spdif_dai_ops, +}; + +static const struct snd_soc_component_driver axi_spdif_component = { + .name = "axi-spdif", +}; + +static const struct regmap_config axi_spdif_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = AXI_SPDIF_REG_STAT, +}; + +static int axi_spdif_probe(struct platform_device *pdev) +{ + struct axi_spdif *spdif; + struct resource *res; + void __iomem *base; + int ret; + + spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL); + if (!spdif) + return -ENOMEM; + + platform_set_drvdata(pdev, spdif); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + spdif->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &axi_spdif_regmap_config); + if (IS_ERR(spdif->regmap)) + return PTR_ERR(spdif->regmap); + + spdif->clk = devm_clk_get(&pdev->dev, "axi"); + if (IS_ERR(spdif->clk)) + return PTR_ERR(spdif->clk); + + spdif->clk_ref = devm_clk_get(&pdev->dev, "ref"); + if (IS_ERR(spdif->clk_ref)) + return PTR_ERR(spdif->clk_ref); + + ret = clk_prepare_enable(spdif->clk); + if (ret) + return ret; + + spdif->dma_data.addr = res->start + AXI_SPDIF_REG_TX_FIFO; + spdif->dma_data.addr_width = 4; + spdif->dma_data.maxburst = 1; + + spdif->ratnum.num = clk_get_rate(spdif->clk_ref) / 128; + spdif->ratnum.den_step = 1; + spdif->ratnum.den_min = 1; + spdif->ratnum.den_max = 64; + + spdif->rate_constraints.rats = &spdif->ratnum; + spdif->rate_constraints.nrats = 1; + + ret = devm_snd_soc_register_component(&pdev->dev, &axi_spdif_component, + &axi_spdif_dai, 1); + if (ret) + goto err_clk_disable; + + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (ret) + goto err_clk_disable; + + return 0; + +err_clk_disable: + clk_disable_unprepare(spdif->clk); + return ret; +} + +static int axi_spdif_dev_remove(struct platform_device *pdev) +{ + struct axi_spdif *spdif = platform_get_drvdata(pdev); + + clk_disable_unprepare(spdif->clk); + + return 0; +} + +static const struct of_device_id axi_spdif_of_match[] = { + { .compatible = "adi,axi-spdif-tx-1.00.a", }, + {}, +}; +MODULE_DEVICE_TABLE(of, axi_spdif_of_match); + +static struct platform_driver axi_spdif_driver = { + .driver = { + .name = "axi-spdif", + .owner = THIS_MODULE, + .of_match_table = axi_spdif_of_match, + }, + .probe = axi_spdif_probe, + .remove = axi_spdif_dev_remove, +}; +module_platform_driver(axi_spdif_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("AXI SPDIF driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index e48d38a1b95c..e634eb78ed03 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig @@ -25,7 +25,7 @@ config SND_ATMEL_SOC_SSC config SND_AT91_SOC_SAM9G20_WM8731 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" - depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC && AT91_PROGRAMMABLE_CLOCKS + depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC select SND_ATMEL_SOC_PDC select SND_ATMEL_SOC_SSC select SND_SOC_WM8731 diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 06082e5e5dcb..b79a2a864513 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -50,7 +50,6 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE, - .formats = SNDRV_PCM_FMTBIT_S16_LE, .period_bytes_min = 256, /* lighting DMA overhead */ .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ .periods_min = 8, diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c index 054ea4d9326a..33ec592ecd75 100644 --- a/sound/soc/atmel/atmel-pcm-pdc.c +++ b/sound/soc/atmel/atmel-pcm-pdc.c @@ -58,7 +58,6 @@ static const struct snd_pcm_hardware atmel_pcm_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE, - .formats = SNDRV_PCM_FMTBIT_S16_LE, .period_bytes_min = 32, .period_bytes_max = 8192, .periods_min = 2, diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c index 7d6a9055874b..3188036a18f0 100644 --- a/sound/soc/atmel/sam9x5_wm8731.c +++ b/sound/soc/atmel/sam9x5_wm8731.c @@ -155,8 +155,6 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev) of_node_put(codec_np); of_node_put(cpu_np); - platform_set_drvdata(pdev, card); - ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 3b4eafaf30d3..17a24d804734 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -65,19 +65,10 @@ struct au1xpsc_audio_dmadata { #define AU1XPSC_PERIOD_MIN_BYTES 1024 #define AU1XPSC_BUFFER_MIN_BYTES 65536 -#define AU1XPSC_PCM_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \ - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \ - 0) - /* PCM hardware DMA capabilities - platform specific */ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH, - .formats = AU1XPSC_PCM_FMTS, .period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES, .period_bytes_max = 4096 * 1024 - 1, .periods_min = 2, diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index befd1074f9bd..e920b60bf6c2 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -21,14 +21,6 @@ #include "psc.h" -#define ALCHEMY_PCM_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \ - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \ - 0) - struct pcm_period { u32 start; u32 relative_end; /* relative to start of buffer */ @@ -171,12 +163,6 @@ static irqreturn_t au1000_dma_interrupt(int irq, void *ptr) static const struct snd_pcm_hardware alchemy_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH, - .formats = ALCHEMY_PCM_FMTS, - .rates = SNDRV_PCM_RATE_8000_192000, - .rate_min = SNDRV_PCM_RATE_8000, - .rate_max = SNDRV_PCM_RATE_192000, - .channels_min = 2, - .channels_max = 2, .period_bytes_min = 1024, .period_bytes_max = 16 * 1024 - 1, .periods_min = 4, diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig new file mode 100644 index 000000000000..6a834e109f1d --- /dev/null +++ b/sound/soc/bcm/Kconfig @@ -0,0 +1,9 @@ +config SND_BCM2835_SOC_I2S + tristate "SoC Audio support for the Broadcom BCM2835 I2S module" + depends on ARCH_BCM2835 || COMPILE_TEST + select SND_SOC_GENERIC_DMAENGINE_PCM + select REGMAP_MMIO + help + Say Y or M if you want to add support for codecs attached to + the BCM2835 I2S interface. You will also need + to select the audio interfaces to support below. diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile new file mode 100644 index 000000000000..bc816b71e5a4 --- /dev/null +++ b/sound/soc/bcm/Makefile @@ -0,0 +1,5 @@ +# BCM2835 Platform Support +snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o + +obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o + diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c new file mode 100644 index 000000000000..2685fe4f8427 --- /dev/null +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -0,0 +1,879 @@ +/* + * ALSA SoC I2S Audio Layer for Broadcom BCM2835 SoC + * + * Author: Florian Meier + * Copyright 2013 + * + * Based on + * Raspberry Pi PCM I2S ALSA Driver + * Copyright (c) by Phil Poole 2013 + * + * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor + * Vladimir Barinov, + * Copyright (C) 2007 MontaVista Software, Inc., + * + * OMAP ALSA SoC DAI driver using McBSP port + * Copyright (C) 2008 Nokia Corporation + * Contact: Jarkko Nikula + * Peter Ujfalusi + * + * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver + * Author: Timur Tabi + * Copyright 2007-2010 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Clock registers */ +#define BCM2835_CLK_PCMCTL_REG 0x00 +#define BCM2835_CLK_PCMDIV_REG 0x04 + +/* Clock register settings */ +#define BCM2835_CLK_PASSWD (0x5a000000) +#define BCM2835_CLK_PASSWD_MASK (0xff000000) +#define BCM2835_CLK_MASH(v) ((v) << 9) +#define BCM2835_CLK_FLIP BIT(8) +#define BCM2835_CLK_BUSY BIT(7) +#define BCM2835_CLK_KILL BIT(5) +#define BCM2835_CLK_ENAB BIT(4) +#define BCM2835_CLK_SRC(v) (v) + +#define BCM2835_CLK_SHIFT (12) +#define BCM2835_CLK_DIVI(v) ((v) << BCM2835_CLK_SHIFT) +#define BCM2835_CLK_DIVF(v) (v) +#define BCM2835_CLK_DIVF_MASK (0xFFF) + +enum { + BCM2835_CLK_MASH_0 = 0, + BCM2835_CLK_MASH_1, + BCM2835_CLK_MASH_2, + BCM2835_CLK_MASH_3, +}; + +enum { + BCM2835_CLK_SRC_GND = 0, + BCM2835_CLK_SRC_OSC, + BCM2835_CLK_SRC_DBG0, + BCM2835_CLK_SRC_DBG1, + BCM2835_CLK_SRC_PLLA, + BCM2835_CLK_SRC_PLLC, + BCM2835_CLK_SRC_PLLD, + BCM2835_CLK_SRC_HDMI, +}; + +/* Most clocks are not useable (freq = 0) */ +static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = { + [BCM2835_CLK_SRC_GND] = 0, + [BCM2835_CLK_SRC_OSC] = 19200000, + [BCM2835_CLK_SRC_DBG0] = 0, + [BCM2835_CLK_SRC_DBG1] = 0, + [BCM2835_CLK_SRC_PLLA] = 0, + [BCM2835_CLK_SRC_PLLC] = 0, + [BCM2835_CLK_SRC_PLLD] = 500000000, + [BCM2835_CLK_SRC_HDMI] = 0, +}; + +/* I2S registers */ +#define BCM2835_I2S_CS_A_REG 0x00 +#define BCM2835_I2S_FIFO_A_REG 0x04 +#define BCM2835_I2S_MODE_A_REG 0x08 +#define BCM2835_I2S_RXC_A_REG 0x0c +#define BCM2835_I2S_TXC_A_REG 0x10 +#define BCM2835_I2S_DREQ_A_REG 0x14 +#define BCM2835_I2S_INTEN_A_REG 0x18 +#define BCM2835_I2S_INTSTC_A_REG 0x1c +#define BCM2835_I2S_GRAY_REG 0x20 + +/* I2S register settings */ +#define BCM2835_I2S_STBY BIT(25) +#define BCM2835_I2S_SYNC BIT(24) +#define BCM2835_I2S_RXSEX BIT(23) +#define BCM2835_I2S_RXF BIT(22) +#define BCM2835_I2S_TXE BIT(21) +#define BCM2835_I2S_RXD BIT(20) +#define BCM2835_I2S_TXD BIT(19) +#define BCM2835_I2S_RXR BIT(18) +#define BCM2835_I2S_TXW BIT(17) +#define BCM2835_I2S_CS_RXERR BIT(16) +#define BCM2835_I2S_CS_TXERR BIT(15) +#define BCM2835_I2S_RXSYNC BIT(14) +#define BCM2835_I2S_TXSYNC BIT(13) +#define BCM2835_I2S_DMAEN BIT(9) +#define BCM2835_I2S_RXTHR(v) ((v) << 7) +#define BCM2835_I2S_TXTHR(v) ((v) << 5) +#define BCM2835_I2S_RXCLR BIT(4) +#define BCM2835_I2S_TXCLR BIT(3) +#define BCM2835_I2S_TXON BIT(2) +#define BCM2835_I2S_RXON BIT(1) +#define BCM2835_I2S_EN (1) + +#define BCM2835_I2S_CLKDIS BIT(28) +#define BCM2835_I2S_PDMN BIT(27) +#define BCM2835_I2S_PDME BIT(26) +#define BCM2835_I2S_FRXP BIT(25) +#define BCM2835_I2S_FTXP BIT(24) +#define BCM2835_I2S_CLKM BIT(23) +#define BCM2835_I2S_CLKI BIT(22) +#define BCM2835_I2S_FSM BIT(21) +#define BCM2835_I2S_FSI BIT(20) +#define BCM2835_I2S_FLEN(v) ((v) << 10) +#define BCM2835_I2S_FSLEN(v) (v) + +#define BCM2835_I2S_CHWEX BIT(15) +#define BCM2835_I2S_CHEN BIT(14) +#define BCM2835_I2S_CHPOS(v) ((v) << 4) +#define BCM2835_I2S_CHWID(v) (v) +#define BCM2835_I2S_CH1(v) ((v) << 16) +#define BCM2835_I2S_CH2(v) (v) + +#define BCM2835_I2S_TX_PANIC(v) ((v) << 24) +#define BCM2835_I2S_RX_PANIC(v) ((v) << 16) +#define BCM2835_I2S_TX(v) ((v) << 8) +#define BCM2835_I2S_RX(v) (v) + +#define BCM2835_I2S_INT_RXERR BIT(3) +#define BCM2835_I2S_INT_TXERR BIT(2) +#define BCM2835_I2S_INT_RXR BIT(1) +#define BCM2835_I2S_INT_TXW BIT(0) + +/* I2S DMA interface */ +/* FIXME: Needs IOMMU support */ +#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000) + +/* General device struct */ +struct bcm2835_i2s_dev { + struct device *dev; + struct snd_dmaengine_dai_dma_data dma_data[2]; + unsigned int fmt; + unsigned int bclk_ratio; + + struct regmap *i2s_regmap; + struct regmap *clk_regmap; +}; + +static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) +{ + /* Start the clock if in master mode */ + unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; + + switch (master) { + case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBS_CFM: + regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, + BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB, + BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB); + break; + default: + break; + } +} + +static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev) +{ + uint32_t clkreg; + int timeout = 1000; + + /* Stop clock */ + regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, + BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB, + BCM2835_CLK_PASSWD); + + /* Wait for the BUSY flag going down */ + while (--timeout) { + regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg); + if (!(clkreg & BCM2835_CLK_BUSY)) + break; + } + + if (!timeout) { + /* KILL the clock */ + dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n"); + regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, + BCM2835_CLK_KILL | BCM2835_CLK_PASSWD_MASK, + BCM2835_CLK_KILL | BCM2835_CLK_PASSWD); + } +} + +static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, + bool tx, bool rx) +{ + int timeout = 1000; + uint32_t syncval; + uint32_t csreg; + uint32_t i2s_active_state; + uint32_t clkreg; + uint32_t clk_active_state; + uint32_t off; + uint32_t clr; + + off = tx ? BCM2835_I2S_TXON : 0; + off |= rx ? BCM2835_I2S_RXON : 0; + + clr = tx ? BCM2835_I2S_TXCLR : 0; + clr |= rx ? BCM2835_I2S_RXCLR : 0; + + /* Backup the current state */ + regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); + i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON); + + regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg); + clk_active_state = clkreg & BCM2835_CLK_ENAB; + + /* Start clock if not running */ + if (!clk_active_state) { + regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, + BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB, + BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB); + } + + /* Stop I2S module */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0); + + /* + * Clear the FIFOs + * Requires at least 2 PCM clock cycles to take effect + */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr); + + /* Wait for 2 PCM clock cycles */ + + /* + * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back + * FIXME: This does not seem to work for slave mode! + */ + regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval); + syncval &= BCM2835_I2S_SYNC; + + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_SYNC, ~syncval); + + /* Wait for the SYNC flag changing it's state */ + while (--timeout) { + regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); + if ((csreg & BCM2835_I2S_SYNC) != syncval) + break; + } + + if (!timeout) + dev_err(dev->dev, "I2S SYNC error!\n"); + + /* Stop clock if it was not running before */ + if (!clk_active_state) + bcm2835_i2s_stop_clock(dev); + + /* Restore I2S state */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_RXON | BCM2835_I2S_TXON, i2s_active_state); +} + +static int bcm2835_i2s_set_dai_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + dev->fmt = fmt; + return 0; +} + +static int bcm2835_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, + unsigned int ratio) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + dev->bclk_ratio = ratio; + return 0; +} + +static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + + unsigned int sampling_rate = params_rate(params); + unsigned int data_length, data_delay, bclk_ratio; + unsigned int ch1pos, ch2pos, mode, format; + unsigned int mash = BCM2835_CLK_MASH_1; + unsigned int divi, divf, target_frequency; + int clk_src = -1; + unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; + bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS + || master == SND_SOC_DAIFMT_CBS_CFM); + + bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS + || master == SND_SOC_DAIFMT_CBM_CFS); + uint32_t csreg; + + /* + * If a stream is already enabled, + * the registers are already set properly. + */ + regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); + + if (csreg & (BCM2835_I2S_TXON | BCM2835_I2S_RXON)) + return 0; + + /* + * Adjust the data length according to the format. + * We prefill the half frame length with an integer + * divider of 2400 as explained at the clock settings. + * Maybe it is overwritten there, if the Integer mode + * does not apply. + */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + data_length = 16; + bclk_ratio = 40; + break; + case SNDRV_PCM_FORMAT_S32_LE: + data_length = 32; + bclk_ratio = 80; + break; + default: + return -EINVAL; + } + + /* If bclk_ratio already set, use that one. */ + if (dev->bclk_ratio) + bclk_ratio = dev->bclk_ratio; + + /* + * Clock Settings + * + * The target frequency of the bit clock is + * sampling rate * frame length + * + * Integer mode: + * Sampling rates that are multiples of 8000 kHz + * can be driven by the oscillator of 19.2 MHz + * with an integer divider as long as the frame length + * is an integer divider of 19200000/8000=2400 as set up above. + * This is no longer possible if the sampling rate + * is too high (e.g. 192 kHz), because the oscillator is too slow. + * + * MASH mode: + * For all other sampling rates, it is not possible to + * have an integer divider. Approximate the clock + * with the MASH module that induces a slight frequency + * variance. To minimize that it is best to have the fastest + * clock here. That is PLLD with 500 MHz. + */ + target_frequency = sampling_rate * bclk_ratio; + clk_src = BCM2835_CLK_SRC_OSC; + mash = BCM2835_CLK_MASH_0; + + if (bcm2835_clk_freq[clk_src] % target_frequency == 0 + && bit_master && frame_master) { + divi = bcm2835_clk_freq[clk_src] / target_frequency; + divf = 0; + } else { + uint64_t dividend; + + if (!dev->bclk_ratio) { + /* + * Overwrite bclk_ratio, because the + * above trick is not needed or can + * not be used. + */ + bclk_ratio = 2 * data_length; + } + + target_frequency = sampling_rate * bclk_ratio; + + clk_src = BCM2835_CLK_SRC_PLLD; + mash = BCM2835_CLK_MASH_1; + + dividend = bcm2835_clk_freq[clk_src]; + dividend <<= BCM2835_CLK_SHIFT; + do_div(dividend, target_frequency); + divi = dividend >> BCM2835_CLK_SHIFT; + divf = dividend & BCM2835_CLK_DIVF_MASK; + } + + /* Set clock divider */ + regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD + | BCM2835_CLK_DIVI(divi) + | BCM2835_CLK_DIVF(divf)); + + /* Setup clock, but don't start it yet */ + regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD + | BCM2835_CLK_MASH(mash) + | BCM2835_CLK_SRC(clk_src)); + + /* Setup the frame format */ + format = BCM2835_I2S_CHEN; + + if (data_length > 24) + format |= BCM2835_I2S_CHWEX; + + format |= BCM2835_I2S_CHWID((data_length-8)&0xf); + + switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + data_delay = 1; + break; + default: + /* + * TODO + * Others are possible but are not implemented at the moment. + */ + dev_err(dev->dev, "%s:bad format\n", __func__); + return -EINVAL; + } + + ch1pos = data_delay; + ch2pos = bclk_ratio / 2 + data_delay; + + switch (params_channels(params)) { + case 2: + format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format); + format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos)); + format |= BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(ch2pos)); + break; + default: + return -EINVAL; + } + + /* + * Set format for both streams. + * We cannot set another frame length + * (and therefore word length) anyway, + * so the format will be the same. + */ + regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format); + regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format); + + /* Setup the I2S mode */ + mode = 0; + + if (data_length <= 16) { + /* + * Use frame packed mode (2 channels per 32 bit word) + * We cannot set another frame length in the second stream + * (and therefore word length) anyway, + * so the format will be the same. + */ + mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP; + } + + mode |= BCM2835_I2S_FLEN(bclk_ratio - 1); + mode |= BCM2835_I2S_FSLEN(bclk_ratio / 2); + + /* Master or slave? */ + switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* CPU is master */ + break; + case SND_SOC_DAIFMT_CBM_CFS: + /* + * CODEC is bit clock master + * CPU is frame master + */ + mode |= BCM2835_I2S_CLKM; + break; + case SND_SOC_DAIFMT_CBS_CFM: + /* + * CODEC is frame master + * CPU is bit clock master + */ + mode |= BCM2835_I2S_FSM; + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* CODEC is master */ + mode |= BCM2835_I2S_CLKM; + mode |= BCM2835_I2S_FSM; + break; + default: + dev_err(dev->dev, "%s:bad master\n", __func__); + return -EINVAL; + } + + /* + * Invert clocks? + * + * The BCM approach seems to be inverted to the classical I2S approach. + */ + switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + /* None. Therefore, both for BCM */ + mode |= BCM2835_I2S_CLKI; + mode |= BCM2835_I2S_FSI; + break; + case SND_SOC_DAIFMT_IB_IF: + /* Both. Therefore, none for BCM */ + break; + case SND_SOC_DAIFMT_NB_IF: + /* + * Invert only frame sync. Therefore, + * invert only bit clock for BCM + */ + mode |= BCM2835_I2S_CLKI; + break; + case SND_SOC_DAIFMT_IB_NF: + /* + * Invert only bit clock. Therefore, + * invert only frame sync for BCM + */ + mode |= BCM2835_I2S_FSI; + break; + default: + return -EINVAL; + } + + regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode); + + /* Setup the DMA parameters */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_RXTHR(1) + | BCM2835_I2S_TXTHR(1) + | BCM2835_I2S_DMAEN, 0xffffffff); + + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, + BCM2835_I2S_TX_PANIC(0x10) + | BCM2835_I2S_RX_PANIC(0x30) + | BCM2835_I2S_TX(0x30) + | BCM2835_I2S_RX(0x20), 0xffffffff); + + /* Clear FIFOs */ + bcm2835_i2s_clear_fifos(dev, true, true); + + return 0; +} + +static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + uint32_t cs_reg; + + bcm2835_i2s_start_clock(dev); + + /* + * Clear both FIFOs if the one that should be started + * is not empty at the moment. This should only happen + * after overrun. Otherwise, hw_params would have cleared + * the FIFO. + */ + regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &cs_reg); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK + && !(cs_reg & BCM2835_I2S_TXE)) + bcm2835_i2s_clear_fifos(dev, true, false); + else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE + && (cs_reg & BCM2835_I2S_RXD)) + bcm2835_i2s_clear_fifos(dev, false, true); + + return 0; +} + +static void bcm2835_i2s_stop(struct bcm2835_i2s_dev *dev, + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + uint32_t mask; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + mask = BCM2835_I2S_RXON; + else + mask = BCM2835_I2S_TXON; + + regmap_update_bits(dev->i2s_regmap, + BCM2835_I2S_CS_A_REG, mask, 0); + + /* Stop also the clock when not SND_SOC_DAIFMT_CONT */ + if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT)) + bcm2835_i2s_stop_clock(dev); +} + +static int bcm2835_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + uint32_t mask; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + bcm2835_i2s_start_clock(dev); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + mask = BCM2835_I2S_RXON; + else + mask = BCM2835_I2S_TXON; + + regmap_update_bits(dev->i2s_regmap, + BCM2835_I2S_CS_A_REG, mask, mask); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + bcm2835_i2s_stop(dev, substream, dai); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int bcm2835_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + + if (dai->active) + return 0; + + /* Should this still be running stop it */ + bcm2835_i2s_stop_clock(dev); + + /* Enable PCM block */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_EN, BCM2835_I2S_EN); + + /* + * Disable STBY. + * Requires at least 4 PCM clock cycles to take effect. + */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_STBY, BCM2835_I2S_STBY); + + return 0; +} + +static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + + bcm2835_i2s_stop(dev, substream, dai); + + /* If both streams are stopped, disable module and clock */ + if (dai->active) + return; + + /* Disable the module */ + regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, + BCM2835_I2S_EN, 0); + + /* + * Stopping clock is necessary, because stop does + * not stop the clock when SND_SOC_DAIFMT_CONT + */ + bcm2835_i2s_stop_clock(dev); +} + +static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = { + .startup = bcm2835_i2s_startup, + .shutdown = bcm2835_i2s_shutdown, + .prepare = bcm2835_i2s_prepare, + .trigger = bcm2835_i2s_trigger, + .hw_params = bcm2835_i2s_hw_params, + .set_fmt = bcm2835_i2s_set_dai_fmt, + .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio +}; + +static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, + &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + + return 0; +} + +static struct snd_soc_dai_driver bcm2835_i2s_dai = { + .name = "bcm2835-i2s", + .probe = bcm2835_i2s_dai_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE + | SNDRV_PCM_FMTBIT_S32_LE + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE + | SNDRV_PCM_FMTBIT_S32_LE + }, + .ops = &bcm2835_i2s_dai_ops, + .symmetric_rates = 1 +}; + +static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BCM2835_I2S_CS_A_REG: + case BCM2835_I2S_FIFO_A_REG: + case BCM2835_I2S_INTSTC_A_REG: + case BCM2835_I2S_GRAY_REG: + return true; + default: + return false; + }; +} + +static bool bcm2835_i2s_precious_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BCM2835_I2S_FIFO_A_REG: + return true; + default: + return false; + }; +} + +static bool bcm2835_clk_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case BCM2835_CLK_PCMCTL_REG: + return true; + default: + return false; + }; +} + +static const struct regmap_config bcm2835_regmap_config[] = { + { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = BCM2835_I2S_GRAY_REG, + .precious_reg = bcm2835_i2s_precious_reg, + .volatile_reg = bcm2835_i2s_volatile_reg, + .cache_type = REGCACHE_RBTREE, + }, + { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = BCM2835_CLK_PCMDIV_REG, + .volatile_reg = bcm2835_clk_volatile_reg, + .cache_type = REGCACHE_RBTREE, + }, +}; + +static const struct snd_soc_component_driver bcm2835_i2s_component = { + .name = "bcm2835-i2s-comp", +}; + +static int bcm2835_i2s_probe(struct platform_device *pdev) +{ + struct bcm2835_i2s_dev *dev; + int i; + int ret; + struct regmap *regmap[2]; + struct resource *mem[2]; + + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { + void __iomem *base; + + mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); + base = devm_ioremap_resource(&pdev->dev, mem[i]); + if (IS_ERR(base)) + return PTR_ERR(base); + + regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, + &bcm2835_regmap_config[i]); + if (IS_ERR(regmap[i])) + return PTR_ERR(regmap[i]); + } + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), + GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->i2s_regmap = regmap[0]; + dev->clk_regmap = regmap[1]; + + /* Set the DMA address */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = + (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG + + BCM2835_VCMMU_SHIFT; + + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = + (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG + + BCM2835_VCMMU_SHIFT; + + /* Set the bus width */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = + DMA_SLAVE_BUSWIDTH_4_BYTES; + + /* Set burst */ + dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; + dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; + + /* BCLK ratio - use default */ + dev->bclk_ratio = 0; + + /* Store the pdev */ + dev->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, dev); + + ret = devm_snd_soc_register_component(&pdev->dev, + &bcm2835_i2s_component, &bcm2835_i2s_dai, 1); + if (ret) { + dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); + return ret; + } + + ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); + if (ret) { + dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct of_device_id bcm2835_i2s_of_match[] = { + { .compatible = "brcm,bcm2835-i2s", }, + {}, +}; + +static struct platform_driver bcm2835_i2s_driver = { + .probe = bcm2835_i2s_probe, + .driver = { + .name = "bcm2835-i2s", + .owner = THIS_MODULE, + .of_match_table = bcm2835_i2s_of_match, + }, +}; + +module_platform_driver(bcm2835_i2s_driver); + +MODULE_ALIAS("platform:bcm2835-i2s"); +MODULE_DESCRIPTION("BCM2835 I2S interface"); +MODULE_AUTHOR("Florian Meier "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 1d4c676eb6cc..cdb8ee75ded9 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -107,7 +107,6 @@ static const struct snd_pcm_hardware bf5xx_pcm_hardware = { #endif SNDRV_PCM_INFO_BLOCK_TRANSFER, - .formats = SNDRV_PCM_FMTBIT_S16_LE, .period_bytes_min = 32, .period_bytes_max = 0x10000, .periods_min = 1, diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 2a5b43417fd5..a3881c4381c9 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -52,9 +52,6 @@ static const struct snd_pcm_hardware bf5xx_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE, .period_bytes_min = 32, .period_bytes_max = 0x10000, .periods_min = 1, diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index c43fb214558a..4f900efc437c 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -63,7 +63,7 @@ static struct snd_soc_ops edb93xx_ops = { static struct snd_soc_dai_link edb93xx_dai = { .name = "CS4271", .stream_name = "CS4271 HiFi", - .platform_name = "ep93xx-pcm-audio", + .platform_name = "ep93xx-i2s", .cpu_dai_name = "ep93xx-i2s", .codec_name = "spi0.0", .codec_dai_name = "cs4271-hifi", diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index efa75b5086a4..f30dadf85b99 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -19,11 +19,14 @@ #include #include +#include #include #include #include +#include "ep93xx-pcm.h" + /* * Per channel (1-4) registers. */ @@ -95,6 +98,8 @@ struct ep93xx_ac97_info { struct device *dev; void __iomem *regs; struct completion done; + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_dai_dma_data dma_params_tx; }; /* currently ALSA only supports a single AC97 device */ @@ -315,8 +320,13 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai) { - dai->playback_dma_data = &ep93xx_ac97_pcm_out; - dai->capture_dma_data = &ep93xx_ac97_pcm_in; + struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); + + info->dma_params_tx.filter_data = &ep93xx_ac97_pcm_out; + info->dma_params_rx.filter_data = &ep93xx_ac97_pcm_in; + + dai->playback_dma_data = &info->dma_params_tx; + dai->capture_dma_data = &info->dma_params_rx; return 0; } @@ -394,8 +404,14 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) if (ret) goto fail; + ret = devm_ep93xx_pcm_platform_register(&pdev->dev); + if (ret) + goto fail_unregister; + return 0; +fail_unregister: + snd_soc_unregister_component(&pdev->dev); fail: ep93xx_ac97_info = NULL; snd_soc_set_ac97_ops(NULL); diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index a57643d6402f..943145f9d1b6 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,8 @@ #include #include +#include "ep93xx-pcm.h" + #define EP93XX_I2S_TXCLKCFG 0x00 #define EP93XX_I2S_RXCLKCFG 0x04 #define EP93XX_I2S_GLCTRL 0x0C @@ -61,6 +64,8 @@ struct ep93xx_i2s_info { struct clk *sclk; struct clk *lrclk; void __iomem *regs; + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_dai_dma_data dma_params_tx; }; static struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { @@ -140,8 +145,15 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream) static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai) { - dai->playback_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK]; - dai->capture_dma_data = &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE]; + struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai); + + info->dma_params_tx.filter_data = + &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + info->dma_params_rx.filter_data = + &ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE]; + + dai->playback_dma_data = &info->dma_params_tx; + dai->capture_dma_data = &info->dma_params_rx; return 0; } @@ -405,8 +417,14 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) if (err) goto fail_put_lrclk; + err = devm_ep93xx_pcm_platform_register(&pdev->dev); + if (err) + goto fail_unregister; + return 0; +fail_unregister: + snd_soc_unregister_component(&pdev->dev); fail_put_lrclk: clk_put(info->lrclk); fail_put_sclk: diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index cfe517e68009..5f664471d99e 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c @@ -23,20 +23,13 @@ #include +#include "ep93xx-pcm.h" + static const struct snd_pcm_hardware ep93xx_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), - - .rates = SNDRV_PCM_RATE_8000_192000, - .rate_min = SNDRV_PCM_RATE_8000, - .rate_max = SNDRV_PCM_RATE_192000, - - .formats = (SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE), - .buffer_bytes_max = 131072, .period_bytes_min = 32, .period_bytes_max = 32768, @@ -57,53 +50,22 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) return false; } -static struct dma_chan *ep93xx_compat_request_channel( - struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_substream *substream) -{ - struct snd_dmaengine_dai_dma_data *dma_data; - - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - return snd_dmaengine_pcm_request_channel(ep93xx_pcm_dma_filter, - dma_data); -} - static const struct snd_dmaengine_pcm_config ep93xx_dmaengine_pcm_config = { .pcm_hardware = &ep93xx_pcm_hardware, .compat_filter_fn = ep93xx_pcm_dma_filter, - .compat_request_channel = ep93xx_compat_request_channel, .prealloc_buffer_size = 131072, }; -static int ep93xx_soc_platform_probe(struct platform_device *pdev) +int devm_ep93xx_pcm_platform_register(struct device *dev) { - return snd_dmaengine_pcm_register(&pdev->dev, + return devm_snd_dmaengine_pcm_register(dev, &ep93xx_dmaengine_pcm_config, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | SND_DMAENGINE_PCM_FLAG_NO_DT | SND_DMAENGINE_PCM_FLAG_COMPAT); } - -static int ep93xx_soc_platform_remove(struct platform_device *pdev) -{ - snd_dmaengine_pcm_unregister(&pdev->dev); - return 0; -} - -static struct platform_driver ep93xx_pcm_driver = { - .driver = { - .name = "ep93xx-pcm-audio", - .owner = THIS_MODULE, - }, - - .probe = ep93xx_soc_platform_probe, - .remove = ep93xx_soc_platform_remove, -}; - -module_platform_driver(ep93xx_pcm_driver); +EXPORT_SYMBOL_GPL(devm_ep93xx_pcm_platform_register); MODULE_AUTHOR("Ryan Mallon"); MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ep93xx-pcm-audio"); diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h new file mode 100644 index 000000000000..b7a12a2fae9c --- /dev/null +++ b/sound/soc/cirrus/ep93xx-pcm.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __EP93XX_PCM_H__ +#define __EP93XX_PCM_H__ + +int devm_ep93xx_pcm_platform_register(struct device *dev); + +#endif diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index 4d094d00c34a..822a19a89e74 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c @@ -27,7 +27,7 @@ static struct snd_soc_dai_link simone_dai = { .cpu_dai_name = "ep93xx-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "ep93xx-pcm-audio", + .platform_name = "ep93xx-ac97", }; static struct snd_soc_card snd_soc_simone = { diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 69041074f2c1..29238a7476dd 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -83,7 +83,7 @@ static struct snd_soc_dai_link snappercl15_dai = { .cpu_dai_name = "ep93xx-i2s", .codec_dai_name = "tlv320aic23-hifi", .codec_name = "tlv320aic23-codec.0-001a", - .platform_name = "ep93xx-pcm-audio", + .platform_name = "ep93xx-i2s", .init = snappercl15_tlv320aic23_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_CBS_CFS, diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b33b45dfceec..983d087aa92a 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -163,8 +163,10 @@ config SND_SOC_WM_HUBS config SND_SOC_WM_ADSP tristate default y if SND_SOC_WM5102=y + default y if SND_SOC_WM5110=y default y if SND_SOC_WM2200=y default m if SND_SOC_WM5102=m + default m if SND_SOC_WM5110=m default m if SND_SOC_WM2200=m config SND_SOC_AB8500_CODEC diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 9a92b7962f41..77f459868579 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -168,17 +168,19 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, int word_len = 0; /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: word_len = AD1836_WORD_LEN_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: word_len = AD1836_WORD_LEN_20; break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S32_LE: + case 24: + case 32: word_len = AD1836_WORD_LEN_24; break; + default: + return -EINVAL; } regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1, diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index aea7e52cf714..5a42dca535b7 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -249,15 +249,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: word_len = 3; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: word_len = 1; break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S32_LE: + case 24: + case 32: word_len = 0; break; } @@ -413,7 +413,7 @@ static struct spi_driver ad193x_spi_driver = { }; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static const struct regmap_config ad193x_i2c_regmap_config = { .val_bits = 8, @@ -470,7 +470,7 @@ static int __init ad193x_modinit(void) { int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&ad193x_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n", @@ -495,7 +495,7 @@ static void __exit ad193x_modexit(void) spi_unregister_driver(&ad193x_spi_driver); #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&ad193x_i2c_driver); #endif } diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 59654b1e7f3f..eb836ed5271f 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1078,17 +1078,17 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream, ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK, (div << 2) | ADAU1373_BCLKDIV_64); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: ctrl = ADAU1373_DAI_WLEN_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: ctrl = ADAU1373_DAI_WLEN_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: ctrl = ADAU1373_DAI_WLEN_24; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: ctrl = ADAU1373_DAI_WLEN_32; break; default: diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index ebff1128be59..d71c59cf7bdd 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -71,7 +71,7 @@ #define ADAU1701_SEROCTL_WORD_LEN_24 0x0000 #define ADAU1701_SEROCTL_WORD_LEN_20 0x0001 -#define ADAU1701_SEROCTL_WORD_LEN_16 0x0010 +#define ADAU1701_SEROCTL_WORD_LEN_16 0x0002 #define ADAU1701_SEROCTL_WORD_LEN_MASK 0x0003 #define ADAU1701_AUXNPOW_VBPD 0x40 @@ -299,20 +299,20 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv) } static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, - snd_pcm_format_t format) + struct snd_pcm_hw_params *params) { struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); unsigned int mask = ADAU1701_SEROCTL_WORD_LEN_MASK; unsigned int val; - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: val = ADAU1701_SEROCTL_WORD_LEN_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val = ADAU1701_SEROCTL_WORD_LEN_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val = ADAU1701_SEROCTL_WORD_LEN_24; break; default: @@ -320,14 +320,14 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, } if (adau1701->dai_fmt == SND_SOC_DAIFMT_RIGHT_J) { - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: val |= ADAU1701_SEROCTL_MSB_DEALY16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val |= ADAU1701_SEROCTL_MSB_DEALY12; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val |= ADAU1701_SEROCTL_MSB_DEALY8; break; } @@ -340,7 +340,7 @@ static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, } static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec, - snd_pcm_format_t format) + struct snd_pcm_hw_params *params) { struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); unsigned int val; @@ -348,14 +348,14 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec, if (adau1701->dai_fmt != SND_SOC_DAIFMT_RIGHT_J) return 0; - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: val = ADAU1701_SERICTL_RIGHTJ_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val = ADAU1701_SERICTL_RIGHTJ_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val = ADAU1701_SERICTL_RIGHTJ_24; break; default: @@ -374,7 +374,6 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); unsigned int clkdiv = adau1701->sysclk / params_rate(params); - snd_pcm_format_t format; unsigned int val; int ret; @@ -406,11 +405,10 @@ static int adau1701_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(adau1701->regmap, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_SR_MASK, val); - format = params_format(params); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return adau1701_set_playback_pcm_format(codec, format); + return adau1701_set_playback_pcm_format(codec, params); else - return adau1701_set_capture_pcm_format(codec, format); + return adau1701_set_capture_pcm_format(codec, params); } static int adau1701_set_dai_fmt(struct snd_soc_dai *codec_dai, diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 14a7c169d004..f78b27a7c461 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -453,22 +453,22 @@ static int adav80x_set_dac_clock(struct snd_soc_codec *codec, } static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, - struct snd_soc_dai *dai, snd_pcm_format_t format) + struct snd_soc_dai *dai, struct snd_pcm_hw_params *params) { struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int val; - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: val = ADAV80X_CAPTURE_WORD_LEN16; break; - case SNDRV_PCM_FORMAT_S18_3LE: + case 18: val = ADAV80X_CAPTRUE_WORD_LEN18; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val = ADAV80X_CAPTURE_WORD_LEN20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val = ADAV80X_CAPTURE_WORD_LEN24; break; default: @@ -482,7 +482,7 @@ static int adav80x_set_capture_pcm_format(struct snd_soc_codec *codec, } static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec, - struct snd_soc_dai *dai, snd_pcm_format_t format) + struct snd_soc_dai *dai, struct snd_pcm_hw_params *params) { struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int val; @@ -490,17 +490,17 @@ static int adav80x_set_playback_pcm_format(struct snd_soc_codec *codec, if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J) return 0; - switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16; break; - case SNDRV_PCM_FORMAT_S18_3LE: + case 18: val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24; break; default: @@ -524,12 +524,10 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream, return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - adav80x_set_playback_pcm_format(codec, dai, - params_format(params)); + adav80x_set_playback_pcm_format(codec, dai, params); adav80x_set_dac_clock(codec, rate); } else { - adav80x_set_capture_pcm_format(codec, dai, - params_format(params)); + adav80x_set_capture_pcm_format(codec, dai, params); adav80x_set_adc_clock(codec, rate); } adav80x->rate = rate; @@ -939,7 +937,7 @@ static struct spi_driver adav80x_spi_driver = { }; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static const struct regmap_config adav80x_i2c_regmap_config = { .val_bits = 8, .pad_bits = 1, @@ -985,7 +983,7 @@ static int __init adav80x_init(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&adav80x_i2c_driver); if (ret) return ret; @@ -1001,7 +999,7 @@ module_init(adav80x_init); static void __exit adav80x_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&adav80x_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 49cc5f6d6dba..94cbe508dd37 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ /* codec private data */ struct ak4641_priv { + struct regmap *regmap; unsigned int sysclk; int deemph; int playback_fs; @@ -38,12 +40,12 @@ struct ak4641_priv { /* * ak4641 register cache */ -static const u8 ak4641_reg[AK4641_CACHEREGNUM] = { - 0x00, 0x80, 0x00, 0x80, - 0x02, 0x00, 0x11, 0x05, - 0x00, 0x00, 0x36, 0x10, - 0x00, 0x00, 0x57, 0x00, - 0x88, 0x88, 0x08, 0x08 +static const struct reg_default ak4641_reg_defaults[] = { + { 0, 0x00 }, { 1, 0x80 }, { 2, 0x00 }, { 3, 0x80 }, + { 4, 0x02 }, { 5, 0x00 }, { 6, 0x11 }, { 7, 0x05 }, + { 8, 0x00 }, { 9, 0x00 }, { 10, 0x36 }, { 11, 0x10 }, + { 12, 0x00 }, { 13, 0x00 }, { 14, 0x57 }, { 15, 0x00 }, + { 16, 0x88 }, { 17, 0x88 }, { 18, 0x08 }, { 19, 0x08 } }; static const int deemph_settings[] = {44100, 0, 48000, 32000}; @@ -396,6 +398,7 @@ static int ak4641_mute(struct snd_soc_dai *dai, int mute) static int ak4641_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); struct ak4641_platform_data *pdata = codec->dev->platform_data; int ret; @@ -417,7 +420,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec, gpio_set_value(pdata->gpio_npdn, 1); mdelay(1); - ret = snd_soc_cache_sync(codec); + ret = regcache_sync(ak4641->regmap); if (ret) { dev_err(codec->dev, "Failed to sync cache: %d\n", ret); @@ -433,7 +436,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec, gpio_set_value(pdata->gpio_npdn, 0); if (pdata && gpio_is_valid(pdata->gpio_power)) gpio_set_value(pdata->gpio_power, 0); - codec->cache_sync = 1; + regcache_mark_dirty(ak4641->regmap); break; } codec->dapm.bias_level = level; @@ -518,7 +521,7 @@ static int ak4641_probe(struct snd_soc_codec *codec) { int ret; - ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -550,12 +553,17 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { .dapm_routes = ak4641_audio_map, .num_dapm_routes = ARRAY_SIZE(ak4641_audio_map), .set_bias_level = ak4641_set_bias_level, - .reg_cache_size = ARRAY_SIZE(ak4641_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = ak4641_reg, - .reg_cache_step = 1, }; +static const struct regmap_config ak4641_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = AK4641_BTIF, + .reg_defaults = ak4641_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(ak4641_reg_defaults), + .cache_type = REGCACHE_RBTREE, +}; static int ak4641_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) @@ -569,6 +577,10 @@ static int ak4641_i2c_probe(struct i2c_client *i2c, if (!ak4641) return -ENOMEM; + ak4641->regmap = devm_regmap_init_i2c(i2c, &ak4641_regmap); + if (IS_ERR(ak4641->regmap)) + return PTR_ERR(ak4641->regmap); + if (pdata) { if (gpio_is_valid(pdata->gpio_power)) { ret = gpio_request_one(pdata->gpio_power, diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 090d499bb7eb..1f646c6e90c6 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -198,30 +199,30 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = { /* * ak4642 register cache */ -static const u8 ak4642_reg[] = { - 0x00, 0x00, 0x01, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0xe1, 0xe1, 0x18, 0x00, - 0xe1, 0x18, 0x11, 0x08, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, +static const struct reg_default ak4642_reg[] = { + { 0, 0x00 }, { 1, 0x00 }, { 2, 0x01 }, { 3, 0x00 }, + { 4, 0x02 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 }, + { 8, 0xe1 }, { 9, 0xe1 }, { 10, 0x18 }, { 11, 0x00 }, + { 12, 0xe1 }, { 13, 0x18 }, { 14, 0x11 }, { 15, 0x08 }, + { 16, 0x00 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x00 }, + { 20, 0x00 }, { 21, 0x00 }, { 22, 0x00 }, { 23, 0x00 }, + { 24, 0x00 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0x00 }, + { 28, 0x00 }, { 29, 0x00 }, { 30, 0x00 }, { 31, 0x00 }, + { 32, 0x00 }, { 33, 0x00 }, { 34, 0x00 }, { 35, 0x00 }, + { 36, 0x00 }, }; -static const u8 ak4648_reg[] = { - 0x00, 0x00, 0x01, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0xe1, 0xe1, 0x18, 0x00, - 0xe1, 0x18, 0x11, 0xb8, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x88, 0x88, 0x08, +static const struct reg_default ak4648_reg[] = { + { 0, 0x00 }, { 1, 0x00 }, { 2, 0x01 }, { 3, 0x00 }, + { 4, 0x02 }, { 5, 0x00 }, { 6, 0x00 }, { 7, 0x00 }, + { 8, 0xe1 }, { 9, 0xe1 }, { 10, 0x18 }, { 11, 0x00 }, + { 12, 0xe1 }, { 13, 0x18 }, { 14, 0x11 }, { 15, 0xb8 }, + { 16, 0x00 }, { 17, 0x00 }, { 18, 0x00 }, { 19, 0x00 }, + { 20, 0x00 }, { 21, 0x00 }, { 22, 0x00 }, { 23, 0x00 }, + { 24, 0x00 }, { 25, 0x00 }, { 26, 0x00 }, { 27, 0x00 }, + { 28, 0x00 }, { 29, 0x00 }, { 30, 0x00 }, { 31, 0x00 }, + { 32, 0x00 }, { 33, 0x00 }, { 34, 0x00 }, { 35, 0x00 }, + { 36, 0x00 }, { 37, 0x88 }, { 38, 0x88 }, { 39, 0x08 }, }; static int ak4642_dai_startup(struct snd_pcm_substream *substream, @@ -454,7 +455,10 @@ static struct snd_soc_dai_driver ak4642_dai = { static int ak4642_resume(struct snd_soc_codec *codec) { - snd_soc_cache_sync(codec); + struct regmap *regmap = dev_get_regmap(codec->dev, NULL); + + regcache_mark_dirty(regmap); + regcache_sync(regmap); return 0; } @@ -463,15 +467,12 @@ static int ak4642_probe(struct snd_soc_codec *codec) { int ret; - ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } - snd_soc_add_codec_controls(codec, ak4642_snd_controls, - ARRAY_SIZE(ak4642_snd_controls)); - ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; @@ -488,55 +489,59 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { .remove = ak4642_remove, .resume = ak4642_resume, .set_bias_level = ak4642_set_bias_level, - .reg_cache_default = ak4642_reg, /* ak4642 reg */ - .reg_cache_size = ARRAY_SIZE(ak4642_reg), /* ak4642 reg */ - .reg_word_size = sizeof(u8), + .controls = ak4642_snd_controls, + .num_controls = ARRAY_SIZE(ak4642_snd_controls), .dapm_widgets = ak4642_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), .dapm_routes = ak4642_intercon, .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), }; -static struct snd_soc_codec_driver soc_codec_dev_ak4648 = { - .probe = ak4642_probe, - .remove = ak4642_remove, - .resume = ak4642_resume, - .set_bias_level = ak4642_set_bias_level, - .reg_cache_default = ak4648_reg, /* ak4648 reg */ - .reg_cache_size = ARRAY_SIZE(ak4648_reg), /* ak4648 reg */ - .reg_word_size = sizeof(u8), - .dapm_widgets = ak4642_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), - .dapm_routes = ak4642_intercon, - .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), +static const struct regmap_config ak4642_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ARRAY_SIZE(ak4642_reg) + 1, + .reg_defaults = ak4642_reg, + .num_reg_defaults = ARRAY_SIZE(ak4642_reg), +}; + +static const struct regmap_config ak4648_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ARRAY_SIZE(ak4648_reg) + 1, + .reg_defaults = ak4648_reg, + .num_reg_defaults = ARRAY_SIZE(ak4648_reg), }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static struct of_device_id ak4642_of_match[]; static int ak4642_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct device_node *np = i2c->dev.of_node; - const struct snd_soc_codec_driver *driver; + const struct regmap_config *regmap_config = NULL; + struct regmap *regmap; - driver = NULL; if (np) { const struct of_device_id *of_id; of_id = of_match_device(ak4642_of_match, &i2c->dev); if (of_id) - driver = of_id->data; + regmap_config = of_id->data; } else { - driver = (struct snd_soc_codec_driver *)id->driver_data; + regmap_config = (const struct regmap_config *)id->driver_data; } - if (!driver) { - dev_err(&i2c->dev, "no driver\n"); + if (!regmap_config) { + dev_err(&i2c->dev, "Unknown device type\n"); return -EINVAL; } + regmap = devm_regmap_init_i2c(i2c, regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + return snd_soc_register_codec(&i2c->dev, - driver, &ak4642_dai, 1); + &soc_codec_dev_ak4642, &ak4642_dai, 1); } static int ak4642_i2c_remove(struct i2c_client *client) @@ -546,17 +551,17 @@ static int ak4642_i2c_remove(struct i2c_client *client) } static struct of_device_id ak4642_of_match[] = { - { .compatible = "asahi-kasei,ak4642", .data = &soc_codec_dev_ak4642}, - { .compatible = "asahi-kasei,ak4643", .data = &soc_codec_dev_ak4642}, - { .compatible = "asahi-kasei,ak4648", .data = &soc_codec_dev_ak4648}, + { .compatible = "asahi-kasei,ak4642", .data = &ak4642_regmap}, + { .compatible = "asahi-kasei,ak4643", .data = &ak4642_regmap}, + { .compatible = "asahi-kasei,ak4648", .data = &ak4648_regmap}, {}, }; MODULE_DEVICE_TABLE(of, ak4642_of_match); static const struct i2c_device_id ak4642_i2c_id[] = { - { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 }, - { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 }, - { "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 }, + { "ak4642", (kernel_ulong_t)&ak4642_regmap }, + { "ak4643", (kernel_ulong_t)&ak4642_regmap }, + { "ak4648", (kernel_ulong_t)&ak4648_regmap }, { } }; MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id); @@ -571,27 +576,8 @@ static struct i2c_driver ak4642_i2c_driver = { .remove = ak4642_i2c_remove, .id_table = ak4642_i2c_id, }; -#endif -static int __init ak4642_modinit(void) -{ - int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&ak4642_i2c_driver); -#endif - return ret; - -} -module_init(ak4642_modinit); - -static void __exit ak4642_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&ak4642_i2c_driver); -#endif - -} -module_exit(ak4642_exit); +module_i2c_driver(ak4642_i2c_driver); MODULE_DESCRIPTION("Soc AK4642 driver"); MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 256c364193a5..d3036283482a 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -714,17 +714,17 @@ static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, iface &= ~ALC5623_DAI_I2S_DL_MASK; /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: iface |= ALC5623_DAI_I2S_DL_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: iface |= ALC5623_DAI_I2S_DL_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: iface |= ALC5623_DAI_I2S_DL_24; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: iface |= ALC5623_DAI_I2S_DL_32; break; default: diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 19e9f222d09c..fb001c56cf8d 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c @@ -869,14 +869,14 @@ static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream, iface &= ~ALC5632_DAI_I2S_DL_MASK; /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: iface |= ALC5632_DAI_I2S_DL_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: iface |= ALC5632_DAI_I2S_DL_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: iface |= ALC5632_DAI_I2S_DL_24; break; default: diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index fea991031be1..e4295fee8f13 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -93,7 +93,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: if (!priv->spk_ena && manual_ena) { - snd_soc_write(codec, 0x4f5, 0x25a); + regmap_write_async(arizona->regmap, 0x4f5, 0x25a); priv->spk_ena_pending = true; } break; @@ -105,12 +105,13 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, return -EBUSY; } - snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, - 1 << w->shift, 1 << w->shift); + regmap_update_bits_async(arizona->regmap, + ARIZONA_OUTPUT_ENABLES_1, + 1 << w->shift, 1 << w->shift); if (priv->spk_ena_pending) { msleep(75); - snd_soc_write(codec, 0x4f5, 0xda); + regmap_write_async(arizona->regmap, 0x4f5, 0xda); priv->spk_ena_pending = false; priv->spk_ena++; } @@ -119,16 +120,19 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, if (manual_ena) { priv->spk_ena--; if (!priv->spk_ena) - snd_soc_write(codec, 0x4f5, 0x25a); + regmap_write_async(arizona->regmap, + 0x4f5, 0x25a); } - snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, - 1 << w->shift, 0); + regmap_update_bits_async(arizona->regmap, + ARIZONA_OUTPUT_ENABLES_1, + 1 << w->shift, 0); break; case SND_SOC_DAPM_POST_PMD: if (manual_ena) { if (!priv->spk_ena) - snd_soc_write(codec, 0x4f5, 0x0da); + regmap_write_async(arizona->regmap, + 0x4f5, 0x0da); } break; } @@ -292,6 +296,10 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { "AIF1RX8", "AIF2RX1", "AIF2RX2", + "AIF2RX3", + "AIF2RX4", + "AIF2RX5", + "AIF2RX6", "AIF3RX1", "AIF3RX2", "SLIMRX1", @@ -395,6 +403,10 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = { 0x27, 0x28, /* AIF2RX1 */ 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, 0x30, /* AIF3RX1 */ 0x31, 0x38, /* SLIMRX1 */ @@ -486,6 +498,22 @@ const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { EXPORT_SYMBOL_GPL(arizona_rate_val); +const struct soc_enum arizona_isrc_fsh[] = { + SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_1, + ARIZONA_ISRC1_FSH_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_1, + ARIZONA_ISRC2_FSH_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_1, + ARIZONA_ISRC3_FSH_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), +}; +EXPORT_SYMBOL_GPL(arizona_isrc_fsh); + const struct soc_enum arizona_isrc_fsl[] = { SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2, ARIZONA_ISRC1_FSL_SHIFT, 0xf, @@ -502,6 +530,13 @@ const struct soc_enum arizona_isrc_fsl[] = { }; EXPORT_SYMBOL_GPL(arizona_isrc_fsl); +const struct soc_enum arizona_asrc_rate1 = + SOC_VALUE_ENUM_SINGLE(ARIZONA_ASRC_RATE1, + ARIZONA_ASRC_RATE1_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE - 1, + arizona_rate_text, arizona_rate_val); +EXPORT_SYMBOL_GPL(arizona_asrc_rate1); + static const char *arizona_vol_ramp_text[] = { "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", "15ms/6dB", "30ms/6dB", @@ -560,6 +595,16 @@ const struct soc_enum arizona_ng_hold = 4, arizona_ng_hold_text); EXPORT_SYMBOL_GPL(arizona_ng_hold); +static const char * const arizona_in_hpf_cut_text[] = { + "2.5Hz", "5Hz", "10Hz", "20Hz", "40Hz" +}; + +const struct soc_enum arizona_in_hpf_cut_enum = + SOC_ENUM_SINGLE(ARIZONA_HPF_CONTROL, ARIZONA_IN_HPF_CUT_SHIFT, + ARRAY_SIZE(arizona_in_hpf_cut_text), + arizona_in_hpf_cut_text); +EXPORT_SYMBOL_GPL(arizona_in_hpf_cut_enum); + static const char * const arizona_in_dmic_osr_text[] = { "1.536MHz", "3.072MHz", "6.144MHz", }; @@ -669,6 +714,7 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, int event) { struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); + struct arizona *arizona = priv->arizona; unsigned int mask = 1 << w->shift; unsigned int val; @@ -691,7 +737,8 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, if (priv->arizona->hpdet_magic) val = 0; - snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val); + regmap_update_bits_async(arizona->regmap, ARIZONA_OUTPUT_ENABLES_1, + mask, val); return arizona_out_ev(w, kcontrol, event); } @@ -846,6 +893,8 @@ EXPORT_SYMBOL_GPL(arizona_set_sysclk); static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_codec *codec = dai->codec; + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; int lrclk, bclk, mode, base; base = dai->driver->base; @@ -902,17 +951,19 @@ static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, - ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR, - bclk); - snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL, - ARIZONA_AIF1TX_LRCLK_INV | - ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); - snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL, - ARIZONA_AIF1RX_LRCLK_INV | - ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); - snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT, - ARIZONA_AIF1_FMT_MASK, mode); + regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_BCLK_CTRL, + ARIZONA_AIF1_BCLK_INV | + ARIZONA_AIF1_BCLK_MSTR, + bclk); + regmap_update_bits_async(arizona->regmap, base + ARIZONA_AIF_TX_PIN_CTRL, + ARIZONA_AIF1TX_LRCLK_INV | + ARIZONA_AIF1TX_LRCLK_MSTR, lrclk); + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_RX_PIN_CTRL, + ARIZONA_AIF1RX_LRCLK_INV | + ARIZONA_AIF1RX_LRCLK_MSTR, lrclk); + regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FORMAT, + ARIZONA_AIF1_FMT_MASK, mode); return 0; } @@ -1164,18 +1215,22 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, if (ret != 0) return ret; - snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL, - ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); - snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE, - ARIZONA_AIF1TX_BCPF_MASK, lrclk); - snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE, - ARIZONA_AIF1RX_BCPF_MASK, lrclk); - snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1, - ARIZONA_AIF1TX_WL_MASK | - ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); - snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2, - ARIZONA_AIF1RX_WL_MASK | - ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_BCLK_CTRL, + ARIZONA_AIF1_BCLK_FREQ_MASK, bclk); + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_TX_BCLK_RATE, + ARIZONA_AIF1TX_BCPF_MASK, lrclk); + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_RX_BCLK_RATE, + ARIZONA_AIF1RX_BCPF_MASK, lrclk); + regmap_update_bits_async(arizona->regmap, + base + ARIZONA_AIF_FRAME_CTRL_1, + ARIZONA_AIF1TX_WL_MASK | + ARIZONA_AIF1TX_SLOT_LEN_MASK, frame); + regmap_update_bits(arizona->regmap, base + ARIZONA_AIF_FRAME_CTRL_2, + ARIZONA_AIF1RX_WL_MASK | + ARIZONA_AIF1RX_SLOT_LEN_MASK, frame); return 0; } @@ -1428,31 +1483,31 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, struct arizona_fll_cfg *cfg, int source, bool sync) { - regmap_update_bits(arizona->regmap, base + 3, - ARIZONA_FLL1_THETA_MASK, cfg->theta); - regmap_update_bits(arizona->regmap, base + 4, - ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); - regmap_update_bits(arizona->regmap, base + 5, - ARIZONA_FLL1_FRATIO_MASK, - cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); - regmap_update_bits(arizona->regmap, base + 6, - ARIZONA_FLL1_CLK_REF_DIV_MASK | - ARIZONA_FLL1_CLK_REF_SRC_MASK, - cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | - source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); + regmap_update_bits_async(arizona->regmap, base + 3, + ARIZONA_FLL1_THETA_MASK, cfg->theta); + regmap_update_bits_async(arizona->regmap, base + 4, + ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda); + regmap_update_bits_async(arizona->regmap, base + 5, + ARIZONA_FLL1_FRATIO_MASK, + cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT); + regmap_update_bits_async(arizona->regmap, base + 6, + ARIZONA_FLL1_CLK_REF_DIV_MASK | + ARIZONA_FLL1_CLK_REF_SRC_MASK, + cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | + source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); if (sync) - regmap_update_bits(arizona->regmap, base + 0x7, - ARIZONA_FLL1_GAIN_MASK, - cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); + regmap_update_bits_async(arizona->regmap, base + 0x7, + ARIZONA_FLL1_GAIN_MASK, + cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); else - regmap_update_bits(arizona->regmap, base + 0x9, - ARIZONA_FLL1_GAIN_MASK, - cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); + regmap_update_bits_async(arizona->regmap, base + 0x9, + ARIZONA_FLL1_GAIN_MASK, + cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); - regmap_update_bits(arizona->regmap, base + 2, - ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, - ARIZONA_FLL1_CTRL_UPD | cfg->n); + regmap_update_bits_async(arizona->regmap, base + 2, + ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, + ARIZONA_FLL1_CTRL_UPD | cfg->n); } static bool arizona_is_enabled_fll(struct arizona_fll *fll) @@ -1485,9 +1540,9 @@ static void arizona_enable_fll(struct arizona_fll *fll, */ if (fll->ref_src >= 0 && fll->ref_freq && fll->ref_src != fll->sync_src) { - regmap_update_bits(arizona->regmap, fll->base + 5, - ARIZONA_FLL1_OUTDIV_MASK, - ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); + regmap_update_bits_async(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, false); @@ -1497,15 +1552,15 @@ static void arizona_enable_fll(struct arizona_fll *fll, use_sync = true; } } else if (fll->sync_src >= 0) { - regmap_update_bits(arizona->regmap, fll->base + 5, - ARIZONA_FLL1_OUTDIV_MASK, - sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); + regmap_update_bits_async(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); arizona_apply_fll(arizona, fll->base, sync, fll->sync_src, false); - regmap_update_bits(arizona->regmap, fll->base + 0x11, - ARIZONA_FLL1_SYNC_ENA, 0); + regmap_update_bits_async(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, 0); } else { arizona_fll_err(fll, "No clocks provided\n"); return; @@ -1516,11 +1571,12 @@ static void arizona_enable_fll(struct arizona_fll *fll, * sync source. */ if (use_sync && fll->sync_freq > 100000) - regmap_update_bits(arizona->regmap, fll->base + 0x17, - ARIZONA_FLL1_SYNC_BW, 0); + regmap_update_bits_async(arizona->regmap, fll->base + 0x17, + ARIZONA_FLL1_SYNC_BW, 0); else - regmap_update_bits(arizona->regmap, fll->base + 0x17, - ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); + regmap_update_bits_async(arizona->regmap, fll->base + 0x17, + ARIZONA_FLL1_SYNC_BW, + ARIZONA_FLL1_SYNC_BW); if (!arizona_is_enabled_fll(fll)) pm_runtime_get(arizona->dev); @@ -1528,14 +1584,14 @@ static void arizona_enable_fll(struct arizona_fll *fll, /* Clear any pending completions */ try_wait_for_completion(&fll->ok); - regmap_update_bits(arizona->regmap, fll->base + 1, - ARIZONA_FLL1_FREERUN, 0); - regmap_update_bits(arizona->regmap, fll->base + 1, - ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); + regmap_update_bits_async(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_FREERUN, 0); + regmap_update_bits_async(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); if (use_sync) - regmap_update_bits(arizona->regmap, fll->base + 0x11, - ARIZONA_FLL1_SYNC_ENA, - ARIZONA_FLL1_SYNC_ENA); + regmap_update_bits_async(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, + ARIZONA_FLL1_SYNC_ENA); ret = wait_for_completion_timeout(&fll->ok, msecs_to_jiffies(250)); @@ -1548,8 +1604,8 @@ static void arizona_disable_fll(struct arizona_fll *fll) struct arizona *arizona = fll->arizona; bool change; - regmap_update_bits(arizona->regmap, fll->base + 1, - ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); + regmap_update_bits_async(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_FREERUN, ARIZONA_FLL1_FREERUN); regmap_update_bits_check(arizona->regmap, fll->base + 1, ARIZONA_FLL1_ENA, 0, &change); regmap_update_bits(arizona->regmap, fll->base + 0x11, diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 9e81b6392692..16df0f913353 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -81,7 +81,7 @@ struct arizona_priv { unsigned int spk_ena_pending:1; }; -#define ARIZONA_NUM_MIXER_INPUTS 99 +#define ARIZONA_NUM_MIXER_INPUTS 103 extern const unsigned int arizona_mixer_tlv[]; extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; @@ -166,26 +166,29 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_INPUT_ROUTES(name " Input 4") #define ARIZONA_DSP_ROUTES(name) \ - { name, NULL, name " Aux 1" }, \ - { name, NULL, name " Aux 2" }, \ - { name, NULL, name " Aux 3" }, \ - { name, NULL, name " Aux 4" }, \ - { name, NULL, name " Aux 5" }, \ - { name, NULL, name " Aux 6" }, \ + { name, NULL, name " Preloader"}, \ + { name " Preloader", NULL, name " Aux 1" }, \ + { name " Preloader", NULL, name " Aux 2" }, \ + { name " Preloader", NULL, name " Aux 3" }, \ + { name " Preloader", NULL, name " Aux 4" }, \ + { name " Preloader", NULL, name " Aux 5" }, \ + { name " Preloader", NULL, name " Aux 6" }, \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 1"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 2"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 3"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 4"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 5"), \ ARIZONA_MIXER_INPUT_ROUTES(name " Aux 6"), \ - ARIZONA_MIXER_ROUTES(name, name "L"), \ - ARIZONA_MIXER_ROUTES(name, name "R") + ARIZONA_MIXER_ROUTES(name " Preloader", name "L"), \ + ARIZONA_MIXER_ROUTES(name " Preloader", name "R") #define ARIZONA_RATE_ENUM_SIZE 4 extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; extern const struct soc_enum arizona_isrc_fsl[]; +extern const struct soc_enum arizona_isrc_fsh[]; +extern const struct soc_enum arizona_asrc_rate1; extern const struct soc_enum arizona_in_vi_ramp; extern const struct soc_enum arizona_in_vd_ramp; @@ -199,6 +202,7 @@ extern const struct soc_enum arizona_lhpf3_mode; extern const struct soc_enum arizona_lhpf4_mode; extern const struct soc_enum arizona_ng_hold; +extern const struct soc_enum arizona_in_hpf_cut_enum; extern const struct soc_enum arizona_in_dmic_osr[]; extern int arizona_in_ev(struct snd_soc_dapm_widget *w, diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index f6e953454bc0..ce05fd93dc74 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -675,7 +675,7 @@ static struct spi_driver cs4271_spi_driver = { }; #endif /* defined(CONFIG_SPI_MASTER) */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static const struct i2c_device_id cs4271_i2c_id[] = { {"cs4271", 0}, {} @@ -728,7 +728,7 @@ static struct i2c_driver cs4271_i2c_driver = { .probe = cs4271_i2c_probe, .remove = cs4271_i2c_remove, }; -#endif /* defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) */ +#endif /* IS_ENABLED(CONFIG_I2C) */ /* * We only register our serial bus driver here without @@ -741,7 +741,7 @@ static int __init cs4271_modinit(void) { int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&cs4271_i2c_driver); if (ret) { pr_err("Failed to register CS4271 I2C driver: %d\n", ret); @@ -767,7 +767,7 @@ static void __exit cs4271_modexit(void) spi_unregister_driver(&cs4271_spi_driver); #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&cs4271_i2c_driver); #endif } diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 1e0fa3b5f79a..6e9ea8379a91 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -423,21 +423,17 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream, intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24); break; case SND_SOC_DAIFMT_RIGHT_J: - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S16_BE: + switch (params_width(params)) { + case 16: fmt = CS42L51_DAC_DIF_RJ16; break; - case SNDRV_PCM_FORMAT_S18_3LE: - case SNDRV_PCM_FORMAT_S18_3BE: + case 18: fmt = CS42L51_DAC_DIF_RJ18; break; - case SNDRV_PCM_FORMAT_S20_3LE: - case SNDRV_PCM_FORMAT_S20_3BE: + case 20: fmt = CS42L51_DAC_DIF_RJ20; break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S24_BE: + case 24: fmt = CS42L51_DAC_DIF_RJ24; break; default: diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 8b427c977083..0bac6d5a4ac8 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -50,7 +50,7 @@ struct cs42l52_private { u8 mclksel; u32 mclk; u8 flags; -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if IS_ENABLED(CONFIG_INPUT) struct input_dev *beep; struct work_struct beep_work; int beep_rate; @@ -233,7 +233,7 @@ static const struct soc_enum mic_bias_level_enum = SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0, ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text); -static const char * const cs42l52_mic_text[] = { "Single", "Differential" }; +static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; static const struct soc_enum mica_enum = SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5, @@ -243,12 +243,6 @@ static const struct soc_enum micb_enum = SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5, ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); -static const struct snd_kcontrol_new mica_mux = - SOC_DAPM_ENUM("Left Mic Input Capture Mux", mica_enum); - -static const struct snd_kcontrol_new micb_mux = - SOC_DAPM_ENUM("Right Mic Input Capture Mux", micb_enum); - static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; static const struct soc_enum digital_output_mux_enum = @@ -531,6 +525,30 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { }; +static const struct snd_kcontrol_new cs42l52_mica_controls[] = { + SOC_ENUM("MICA Select", mica_enum), +}; + +static const struct snd_kcontrol_new cs42l52_micb_controls[] = { + SOC_ENUM("MICB Select", micb_enum), +}; + +static int cs42l52_add_mic_controls(struct snd_soc_codec *codec) +{ + struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); + struct cs42l52_platform_data *pdata = &cs42l52->pdata; + + if (!pdata->mica_diff_cfg) + snd_soc_add_codec_controls(codec, cs42l52_mica_controls, + ARRAY_SIZE(cs42l52_mica_controls)); + + if (!pdata->micb_diff_cfg) + snd_soc_add_codec_controls(codec, cs42l52_micb_controls, + ARRAY_SIZE(cs42l52_micb_controls)); + + return 0; +} + static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AIN1L"), @@ -550,9 +568,6 @@ static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL, 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_MUX("MICA Mux", SND_SOC_NOPM, 0, 0, &mica_mux), - SND_SOC_DAPM_MUX("MICB Mux", SND_SOC_NOPM, 0, 0, &micb_mux), - SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1), SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1), SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0), @@ -953,7 +968,7 @@ static int cs42l52_resume(struct snd_soc_codec *codec) return 0; } -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if IS_ENABLED(CONFIG_INPUT) static int beep_rates[] = { 261, 522, 585, 667, 706, 774, 889, 1000, 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 @@ -1110,6 +1125,8 @@ static int cs42l52_probe(struct snd_soc_codec *codec) } regcache_cache_only(cs42l52->regmap, true); + cs42l52_add_mic_controls(codec); + cs42l52_init_beep(codec); cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1176,6 +1193,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, int ret; unsigned int devid = 0; unsigned int reg; + u32 val32; cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private), GFP_KERNEL); @@ -1189,9 +1207,39 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); return ret; } - - if (pdata) + if (pdata) { cs42l52->pdata = *pdata; + } else { + pdata = devm_kzalloc(&i2c_client->dev, + sizeof(struct cs42l52_platform_data), + GFP_KERNEL); + if (!pdata) { + dev_err(&i2c_client->dev, "could not allocate pdata\n"); + return -ENOMEM; + } + if (i2c_client->dev.of_node) { + if (of_property_read_bool(i2c_client->dev.of_node, + "cirrus,mica-differential-cfg")) + pdata->mica_diff_cfg = true; + + if (of_property_read_bool(i2c_client->dev.of_node, + "cirrus,micb-differential-cfg")) + pdata->micb_diff_cfg = true; + + if (of_property_read_u32(i2c_client->dev.of_node, + "cirrus,micbias-lvl", &val32) >= 0) + pdata->micbias_lvl = val32; + + if (of_property_read_u32(i2c_client->dev.of_node, + "cirrus,chgfreq-divisor", &val32) >= 0) + pdata->chgfreq = val32; + + pdata->reset_gpio = + of_get_named_gpio(i2c_client->dev.of_node, + "cirrus,reset-gpio", 0); + } + cs42l52->pdata = *pdata; + } if (cs42l52->pdata.reset_gpio) { ret = gpio_request_one(cs42l52->pdata.reset_gpio, @@ -1227,29 +1275,18 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, reg & 0xFF); /* Set Platform Data */ - if (cs42l52->pdata.mica_cfg) + if (cs42l52->pdata.mica_diff_cfg) regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL, CS42L52_MIC_CTL_TYPE_MASK, - cs42l52->pdata.mica_cfg << + cs42l52->pdata.mica_diff_cfg << CS42L52_MIC_CTL_TYPE_SHIFT); - if (cs42l52->pdata.micb_cfg) + if (cs42l52->pdata.micb_diff_cfg) regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL, CS42L52_MIC_CTL_TYPE_MASK, - cs42l52->pdata.micb_cfg << + cs42l52->pdata.micb_diff_cfg << CS42L52_MIC_CTL_TYPE_SHIFT); - if (cs42l52->pdata.mica_sel) - regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL, - CS42L52_MIC_CTL_MIC_SEL_MASK, - cs42l52->pdata.mica_sel << - CS42L52_MIC_CTL_MIC_SEL_SHIFT); - if (cs42l52->pdata.micb_sel) - regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL, - CS42L52_MIC_CTL_MIC_SEL_MASK, - cs42l52->pdata.micb_sel << - CS42L52_MIC_CTL_MIC_SEL_SHIFT); - if (cs42l52->pdata.chgfreq) regmap_update_bits(cs42l52->regmap, CS42L52_CHARGE_PUMP, CS42L52_CHARGE_PUMP_MASK, @@ -1274,6 +1311,13 @@ static int cs42l52_i2c_remove(struct i2c_client *client) return 0; } +static const struct of_device_id cs42l52_of_match[] = { + { .compatible = "cirrus,cs42l52", }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs42l52_of_match); + + static const struct i2c_device_id cs42l52_id[] = { { "cs42l52", 0 }, { } @@ -1284,6 +1328,7 @@ static struct i2c_driver cs42l52_i2c_driver = { .driver = { .name = "cs42l52", .owner = THIS_MODULE, + .of_match_table = cs42l52_of_match, }, .id_table = cs42l52_id, .probe = cs42l52_i2c_probe, diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 9c1231456502..e62e294a8033 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -778,17 +778,17 @@ static int da7210_hw_params(struct snd_pcm_substream *substream, dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: dai_cfg1 |= DA7210_DAI_WORD_S16_LE; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: dai_cfg1 |= DA7210_DAI_WORD_S20_3LE; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: dai_cfg1 |= DA7210_DAI_WORD_S24_LE; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: dai_cfg1 |= DA7210_DAI_WORD_S32_LE; break; default: @@ -1188,7 +1188,7 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = { .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static struct reg_default da7210_regmap_i2c_patch[] = { @@ -1362,7 +1362,7 @@ static struct spi_driver da7210_spi_driver = { static int __init da7210_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&da7210_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) @@ -1378,7 +1378,7 @@ module_init(da7210_modinit); static void __exit da7210_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&da7210_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 4a6f1daf911f..0c77e7ad7423 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1067,17 +1067,17 @@ static int da7213_hw_params(struct snd_pcm_substream *substream, u8 fs; /* Set DAI format */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: dai_ctrl |= DA7213_DAI_WORD_LENGTH_S16_LE; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: dai_ctrl |= DA7213_DAI_WORD_LENGTH_S20_LE; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: dai_ctrl |= DA7213_DAI_WORD_LENGTH_S24_LE; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: dai_ctrl |= DA7213_DAI_WORD_LENGTH_S32_LE; break; default: diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index dc0284dc9e6f..f295b6569910 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -973,17 +973,17 @@ static int da732x_hw_params(struct snd_pcm_substream *substream, reg_aif = dai->driver->base; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: aif |= DA732X_AIF_WORD_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: aif |= DA732X_AIF_WORD_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: aif |= DA732X_AIF_WORD_24; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: aif |= DA732X_AIF_WORD_32; break; default: diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index fc9802d1281d..52b79a487ac7 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1058,17 +1058,17 @@ static int da9055_hw_params(struct snd_pcm_substream *substream, u8 aif_ctrl, fs; u32 sysclk; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: aif_ctrl = DA9055_AIF_WORD_S16_LE; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: aif_ctrl = DA9055_AIF_WORD_S20_3LE; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: aif_ctrl = DA9055_AIF_WORD_S24_LE; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: aif_ctrl = DA9055_AIF_WORD_S32_LE; break; default: diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 68342b121c96..9cb1c7d3e1dc 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -20,6 +20,7 @@ */ #include #include +#include #define DRV_NAME "hdmi-audio-codec" @@ -44,7 +45,7 @@ static struct snd_soc_dai_driver hdmi_codec_dai = { SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, }, .capture = { .stream_name = "Capture", @@ -60,6 +61,14 @@ static struct snd_soc_dai_driver hdmi_codec_dai = { }; +#ifdef CONFIG_OF +static const struct of_device_id hdmi_audio_codec_ids[] = { + { .compatible = "linux,hdmi-audio", }, + { } +}; +MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids); +#endif + static struct snd_soc_codec_driver hdmi_codec = { .dapm_widgets = hdmi_widgets, .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), @@ -83,6 +92,7 @@ static struct platform_driver hdmi_codec_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(hdmi_audio_codec_ids), }, .probe = hdmi_codec_probe, diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index 53b455b8c07a..5839048ec467 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -951,11 +951,11 @@ static int isabelle_hw_params(struct snd_pcm_substream *substream, ISABELLE_FS_RATE_MASK, fs_val); /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S20_3LE: + switch (params_width(params)) { + case 20: aif |= ISABELLE_AIF_LENGTH_20; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: aif |= ISABELLE_AIF_LENGTH_32; break; default: diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 53d7dab4e054..ee660e2d3df3 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1233,12 +1233,12 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream, rate = params_rate(params); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, M98088_DAI_WS, 0); break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: snd_soc_update_bits(codec, M98088_REG_14_DAI1_FORMAT, M98088_DAI_WS, M98088_DAI_WS); break; diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 0569a4c3ae00..51f9b3d16b41 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1840,8 +1840,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, max98090->lrclk = params_rate(params); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: snd_soc_update_bits(codec, M98090_REG_INTERFACE_FORMAT, M98090_WS_MASK, 0); break; diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 67244315c721..3ba1170ebb53 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -1213,12 +1213,12 @@ static int max98095_dai1_hw_params(struct snd_pcm_substream *substream, rate = params_rate(params); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, M98095_DAI_WS, 0); break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: snd_soc_update_bits(codec, M98095_02A_DAI1_FORMAT, M98095_DAI_WS, M98095_DAI_WS); break; diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index c5dd61785f8d..82757ebf0301 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -149,14 +149,14 @@ static int max9850_hw_params(struct snd_pcm_substream *substream, snd_soc_write(codec, MAX9850_LRCLK_MSB, (lrclk_div >> 8) & 0x7f); snd_soc_write(codec, MAX9850_LRCLK_LSB, lrclk_div & 0xff); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: da = 0; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: da = 0x2; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: da = 0x3; break; default: diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index bae60164c7b7..582c2bbd42cb 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -750,30 +750,26 @@ static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { .num_dapm_routes = ARRAY_SIZE(mc13783_routes), }; -static int mc13783_codec_probe(struct platform_device *pdev) +static int __init mc13783_codec_probe(struct platform_device *pdev) { - struct mc13xxx *mc13xxx; struct mc13783_priv *priv; struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data; int ret; - mc13xxx = dev_get_drvdata(pdev->dev.parent); - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (priv == NULL) + if (!priv) return -ENOMEM; - dev_set_drvdata(&pdev->dev, priv); - priv->mc13xxx = mc13xxx; if (pdata) { priv->adc_ssi_port = pdata->adc_ssi_port; priv->dac_ssi_port = pdata->dac_ssi_port; } else { - priv->adc_ssi_port = MC13783_SSI1_PORT; - priv->dac_ssi_port = MC13783_SSI2_PORT; + return -ENOSYS; } + dev_set_drvdata(&pdev->dev, priv); + priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); + if (priv->adc_ssi_port == priv->dac_ssi_port) ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783, mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync)); @@ -781,14 +777,6 @@ static int mc13783_codec_probe(struct platform_device *pdev) ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783, mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async)); - if (ret) - goto err_register_codec; - - return 0; - -err_register_codec: - dev_err(&pdev->dev, "register codec failed with %d\n", ret); - return ret; } @@ -801,14 +789,12 @@ static int mc13783_codec_remove(struct platform_device *pdev) static struct platform_driver mc13783_codec_driver = { .driver = { - .name = "mc13783-codec", - .owner = THIS_MODULE, - }, - .probe = mc13783_codec_probe, + .name = "mc13783-codec", + .owner = THIS_MODULE, + }, .remove = mc13783_codec_remove, }; - -module_platform_driver(mc13783_codec_driver); +module_platform_driver_probe(mc13783_codec_driver, mc13783_codec_probe); MODULE_DESCRIPTION("ASoC MC13783 driver"); MODULE_AUTHOR("Sascha Hauer, Pengutronix "); diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 1f4093f3f3a1..0fcbe90f3ef2 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -115,6 +115,7 @@ struct sgtl5000_priv { struct ldo_regulator *ldo; struct regmap *regmap; struct clk *mclk; + int revision; }; /* @@ -1285,41 +1286,45 @@ static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec) sgtl5000->supplies[VDDD].supply = LDO_CONSUMER_NAME; - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - - if (ret) { - ldo_regulator_remove(codec); - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - return ret; - } - dev_info(codec->dev, "Using internal LDO instead of VDDD\n"); return 0; } static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) { - int reg; int ret; - int rev; int i; int external_vddd = 0; struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); + struct regulator *vddd; for (i = 0; i < ARRAY_SIZE(sgtl5000->supplies); i++) sgtl5000->supplies[i].supply = supply_names[i]; - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - if (!ret) - external_vddd = 1; - else { + /* External VDDD only works before revision 0x11 */ + if (sgtl5000->revision < 0x11) { + vddd = regulator_get_optional(codec->dev, "VDDD"); + if (IS_ERR(vddd)) { + /* See if it's just not registered yet */ + if (PTR_ERR(vddd) == -EPROBE_DEFER) + return -EPROBE_DEFER; + } else { + external_vddd = 1; + regulator_put(vddd); + } + } + + if (!external_vddd) { ret = sgtl5000_replace_vddd_with_ldo(codec); if (ret) return ret; } + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), + sgtl5000->supplies); + if (ret) + goto err_ldo_remove; + ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); if (ret) @@ -1328,47 +1333,13 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) /* wait for all power rails bring up */ udelay(10); - /* - * workaround for revision 0x11 and later, - * roll back to use internal LDO - */ - - ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®); - if (ret) - goto err_regulator_disable; - - rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; - - if (external_vddd && rev >= 0x11) { - /* disable all regulator first */ - regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - /* free VDDD regulator */ - regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - - ret = sgtl5000_replace_vddd_with_ldo(codec); - if (ret) - return ret; - - ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); - if (ret) - goto err_regulator_free; - - /* wait for all power rails bring up */ - udelay(10); - } - return 0; -err_regulator_disable: - regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), - sgtl5000->supplies); err_regulator_free: regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), sgtl5000->supplies); - if (external_vddd) +err_ldo_remove: + if (!external_vddd) ldo_regulator_remove(codec); return ret; @@ -1566,6 +1537,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; dev_info(&client->dev, "sgtl5000 revision 0x%x\n", rev); + sgtl5000->revision = rev; i2c_set_clientdata(client, sgtl5000); diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 95aed552139a..cc8debce752f 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -549,13 +549,13 @@ static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, right_slot = 0; } else { /* We assume the left channel < right channel */ - left_slot = ffs(tx_mask); - tx_mask &= ~(1 << tx_mask); + left_slot = __ffs(tx_mask); + tx_mask &= ~(1 << left_slot); if (tx_mask == 0) { right_slot = left_slot; } else { - right_slot = ffs(tx_mask); - tx_mask &= ~(1 << tx_mask); + right_slot = __ffs(tx_mask); + tx_mask &= ~(1 << right_slot); } } diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 492644e67ace..af76bbd1b24f 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -53,8 +53,6 @@ enum ssm2602_type { struct ssm2602_priv { unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; - struct snd_pcm_substream *master_substream; - struct snd_pcm_substream *slave_substream; struct regmap *regmap; @@ -196,7 +194,7 @@ static const struct snd_soc_dapm_route ssm2604_routes[] = { }; static const unsigned int ssm2602_rates_12288000[] = { - 8000, 32000, 48000, 96000, + 8000, 16000, 32000, 48000, 96000, }; static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { @@ -233,6 +231,11 @@ static const struct ssm2602_coeff ssm2602_coeff_table[] = { {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)}, {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)}, + /* 16k */ + {12288000, 16000, SSM2602_COEFF_SRATE(0x5, 0x0, 0x0)}, + {18432000, 16000, SSM2602_COEFF_SRATE(0x5, 0x1, 0x0)}, + {12000000, 16000, SSM2602_COEFF_SRATE(0xa, 0x0, 0x1)}, + /* 8k */ {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)}, {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)}, @@ -277,11 +280,6 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream, int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params)); unsigned int iface; - if (substream == ssm2602->slave_substream) { - dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n"); - return 0; - } - if (srate < 0) return srate; @@ -314,33 +312,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); - struct snd_pcm_runtime *master_runtime; - - /* The DAI has shared clocks so if we already have a playback or - * capture going then constrain this substream to match it. - * TODO: the ssm2602 allows pairs of non-matching PB/REC rates - */ - if (ssm2602->master_substream) { - master_runtime = ssm2602->master_substream->runtime; - dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n", - master_runtime->sample_bits, - master_runtime->rate); - - if (master_runtime->rate != 0) - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - master_runtime->rate, - master_runtime->rate); - - if (master_runtime->sample_bits != 0) - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - master_runtime->sample_bits, - master_runtime->sample_bits); - - ssm2602->slave_substream = substream; - } else - ssm2602->master_substream = substream; if (ssm2602->sysclk_constraints) { snd_pcm_hw_constraint_list(substream->runtime, 0, @@ -351,19 +322,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, return 0; } -static void ssm2602_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); - - if (ssm2602->master_substream == substream) - ssm2602->master_substream = ssm2602->slave_substream; - - ssm2602->slave_substream = NULL; -} - - static int ssm2602_mute(struct snd_soc_dai *dai, int mute) { struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(dai->codec); @@ -520,9 +478,10 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, return 0; } -#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) +#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000) #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) @@ -530,7 +489,6 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, static const struct snd_soc_dai_ops ssm2602_dai_ops = { .startup = ssm2602_startup, .hw_params = ssm2602_hw_params, - .shutdown = ssm2602_shutdown, .digital_mute = ssm2602_mute, .set_sysclk = ssm2602_set_dai_sysclk, .set_fmt = ssm2602_set_dai_fmt, @@ -551,6 +509,8 @@ static struct snd_soc_dai_driver ssm2602_dai = { .rates = SSM2602_RATES, .formats = SSM2602_FORMATS,}, .ops = &ssm2602_dai_ops, + .symmetric_rates = 1, + .symmetric_samplebits = 1, }; static int ssm2602_suspend(struct snd_soc_codec *codec) @@ -730,7 +690,7 @@ static struct spi_driver ssm2602_spi_driver = { }; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) /* * ssm2602 2 wire address is determined by GPIO5 * state during powerup. @@ -797,7 +757,7 @@ static int __init ssm2602_modinit(void) return ret; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&ssm2602_i2c_driver); if (ret) return ret; @@ -813,7 +773,7 @@ static void __exit ssm2602_exit(void) spi_unregister_driver(&ssm2602_spi_driver); #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&ssm2602_i2c_driver); #endif } diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 18cdcca9014c..385dec16eb8a 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -267,8 +267,8 @@ static const struct regmap_range_cfg aic32x4_regmap_pages[] = { .selector_mask = 0xff, .window_start = 0, .window_len = 128, - .range_min = AIC32X4_PAGE1, - .range_max = AIC32X4_PAGE1 + 127, + .range_min = 0, + .range_max = AIC32X4_RMICPGAVOL, }, }; diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 546d16b7d38f..470fbfb4b386 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -350,16 +350,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume", - LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, - 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("Mono PGA Bypass Volume", - PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL, - 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("Mono DAC Playback Volume", - DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL, - 0, 118, 1, output_stage_tlv), - SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume", LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv), @@ -383,7 +373,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { /* Output pin mute controls */ SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3, 0x01, 0), - SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 0x01, 0), SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, @@ -412,6 +401,20 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = { SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), }; +static const struct snd_kcontrol_new aic3x_mono_controls[] = { + SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume", + LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL, + 0, 118, 1, output_stage_tlv), + SOC_DOUBLE_R_TLV("Mono PGA Bypass Volume", + PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL, + 0, 118, 1, output_stage_tlv), + SOC_DOUBLE_R_TLV("Mono DAC Playback Volume", + DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL, + 0, 118, 1, output_stage_tlv), + + SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0), +}; + /* * Class-D amplifier gain. From 0 to 18 dB in 6 dB steps */ @@ -565,9 +568,6 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { SND_SOC_DAPM_PGA("Right HP Out", HPROUT_CTRL, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Right HP Com", HPRCOM_CTRL, 0, 0, NULL, 0), - /* Mono Output */ - SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0), - /* Inputs to Left ADC */ SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0), SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, @@ -626,9 +626,6 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { SND_SOC_DAPM_MIXER("Right Line Mixer", SND_SOC_NOPM, 0, 0, &aic3x_right_line_mixer_controls[0], ARRAY_SIZE(aic3x_right_line_mixer_controls)), - SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, - &aic3x_mono_mixer_controls[0], - ARRAY_SIZE(aic3x_mono_mixer_controls)), SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0, &aic3x_left_hp_mixer_controls[0], ARRAY_SIZE(aic3x_left_hp_mixer_controls)), @@ -644,7 +641,6 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("LLOUT"), SND_SOC_DAPM_OUTPUT("RLOUT"), - SND_SOC_DAPM_OUTPUT("MONO_LOUT"), SND_SOC_DAPM_OUTPUT("HPLOUT"), SND_SOC_DAPM_OUTPUT("HPROUT"), SND_SOC_DAPM_OUTPUT("HPLCOM"), @@ -666,6 +662,17 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("Detection"), }; +static const struct snd_soc_dapm_widget aic3x_dapm_mono_widgets[] = { + /* Mono Output */ + SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, + &aic3x_mono_mixer_controls[0], + ARRAY_SIZE(aic3x_mono_mixer_controls)), + + SND_SOC_DAPM_OUTPUT("MONO_LOUT"), +}; + static const struct snd_soc_dapm_widget aic3007_dapm_widgets[] = { /* Class-D outputs */ SND_SOC_DAPM_PGA("Left Class-D Out", CLASSD_CTRL, 3, 0, NULL, 0), @@ -754,17 +761,6 @@ static const struct snd_soc_dapm_route intercon[] = { {"Right Line Out", NULL, "Right DAC Mux"}, {"RLOUT", NULL, "Right Line Out"}, - /* Mono Output */ - {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, - {"Mono Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, - {"Mono Mixer", "DACL1 Switch", "Left DAC Mux"}, - {"Mono Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, - {"Mono Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, - {"Mono Mixer", "DACR1 Switch", "Right DAC Mux"}, - - {"Mono Out", NULL, "Mono Mixer"}, - {"MONO_LOUT", NULL, "Mono Out"}, - /* Left HP Output */ {"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, {"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, @@ -820,6 +816,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"HPRCOM", NULL, "Right HP Com"}, }; +static const struct snd_soc_dapm_route intercon_mono[] = { + /* Mono Output */ + {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, + {"Mono Mixer", "PGAL Bypass Switch", "Left PGA Mixer"}, + {"Mono Mixer", "DACL1 Switch", "Left DAC Mux"}, + {"Mono Mixer", "Line2R Bypass Switch", "Right Line2R Mux"}, + {"Mono Mixer", "PGAR Bypass Switch", "Right PGA Mixer"}, + {"Mono Mixer", "DACR1 Switch", "Right DAC Mux"}, + {"Mono Out", NULL, "Mono Mixer"}, + {"MONO_LOUT", NULL, "Mono Out"}, +}; + static const struct snd_soc_dapm_route intercon_3007[] = { /* Class-D outputs */ {"Left Class-D Out", NULL, "Left Line Out"}, @@ -833,11 +841,20 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec) struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm = &codec->dapm; - if (aic3x->model == AIC3X_MODEL_3007) { + switch (aic3x->model) { + case AIC3X_MODEL_3X: + case AIC3X_MODEL_33: + snd_soc_dapm_new_controls(dapm, aic3x_dapm_mono_widgets, + ARRAY_SIZE(aic3x_dapm_mono_widgets)); + snd_soc_dapm_add_routes(dapm, intercon_mono, + ARRAY_SIZE(intercon_mono)); + break; + case AIC3X_MODEL_3007: snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets, ARRAY_SIZE(aic3007_dapm_widgets)); snd_soc_dapm_add_routes(dapm, intercon_3007, ARRAY_SIZE(intercon_3007)); + break; } return 0; @@ -1218,6 +1235,24 @@ static int aic3x_resume(struct snd_soc_codec *codec) return 0; } +static void aic3x_mono_init(struct snd_soc_codec *codec) +{ + /* DAC to Mono Line Out default volume and route to Output mixer */ + snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); + snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); + + /* unmute all outputs */ + snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE); + + /* PGA to Mono Line Out default volume, disconnect from Output Mixer */ + snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL); + snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL); + + /* Line2 to Mono Out default volume, disconnect from Output Mixer */ + snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL); + snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); +} + /* * initialise the AIC3X driver * register the mixer and dsp interfaces with the kernel @@ -1241,14 +1276,10 @@ static int aic3x_init(struct snd_soc_codec *codec) /* DAC to Line Out default volume and route to Output mixer */ snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON); snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON); - /* DAC to Mono Line Out default volume and route to Output mixer */ - snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); - snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); /* unmute all outputs */ snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE); snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE); - snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE); snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE); snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE); snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE); @@ -1269,9 +1300,6 @@ static int aic3x_init(struct snd_soc_codec *codec) /* PGA to Line Out default volume, disconnect from Output Mixer */ snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL); snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL); - /* PGA to Mono Line Out default volume, disconnect from Output Mixer */ - snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL); - snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL); /* Line2 to HP Bypass default volume, disconnect from Output Mixer */ snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL); @@ -1281,12 +1309,15 @@ static int aic3x_init(struct snd_soc_codec *codec) /* Line2 Line Out default volume, disconnect from Output Mixer */ snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL); snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL); - /* Line2 to Mono Out default volume, disconnect from Output Mixer */ - snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL); - snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL); - if (aic3x->model == AIC3X_MODEL_3007) { + switch (aic3x->model) { + case AIC3X_MODEL_3X: + case AIC3X_MODEL_33: + aic3x_mono_init(codec); + break; + case AIC3X_MODEL_3007: snd_soc_write(codec, CLASSD_CTRL, 0); + break; } return 0; @@ -1343,8 +1374,17 @@ static int aic3x_probe(struct snd_soc_codec *codec) (aic3x->setup->gpio_func[1] & 0xf) << 4); } - if (aic3x->model == AIC3X_MODEL_3007) - snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); + switch (aic3x->model) { + case AIC3X_MODEL_3X: + case AIC3X_MODEL_33: + snd_soc_add_codec_controls(codec, aic3x_mono_controls, + ARRAY_SIZE(aic3x_mono_controls)); + break; + case AIC3X_MODEL_3007: + snd_soc_add_codec_controls(codec, + &aic3x_classd_amp_gain_ctrl, 1); + break; + } /* set mic bias voltage */ switch (aic3x->micbias_vg) { diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index dfc51bb425da..00665ada23e2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -48,86 +48,6 @@ #define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) -/* - * twl4030 register cache & default register settings - */ -static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { - 0x00, /* this register not used */ - 0x00, /* REG_CODEC_MODE (0x1) */ - 0x00, /* REG_OPTION (0x2) */ - 0x00, /* REG_UNKNOWN (0x3) */ - 0x00, /* REG_MICBIAS_CTL (0x4) */ - 0x00, /* REG_ANAMICL (0x5) */ - 0x00, /* REG_ANAMICR (0x6) */ - 0x00, /* REG_AVADC_CTL (0x7) */ - 0x00, /* REG_ADCMICSEL (0x8) */ - 0x00, /* REG_DIGMIXING (0x9) */ - 0x0f, /* REG_ATXL1PGA (0xA) */ - 0x0f, /* REG_ATXR1PGA (0xB) */ - 0x0f, /* REG_AVTXL2PGA (0xC) */ - 0x0f, /* REG_AVTXR2PGA (0xD) */ - 0x00, /* REG_AUDIO_IF (0xE) */ - 0x00, /* REG_VOICE_IF (0xF) */ - 0x3f, /* REG_ARXR1PGA (0x10) */ - 0x3f, /* REG_ARXL1PGA (0x11) */ - 0x3f, /* REG_ARXR2PGA (0x12) */ - 0x3f, /* REG_ARXL2PGA (0x13) */ - 0x25, /* REG_VRXPGA (0x14) */ - 0x00, /* REG_VSTPGA (0x15) */ - 0x00, /* REG_VRX2ARXPGA (0x16) */ - 0x00, /* REG_AVDAC_CTL (0x17) */ - 0x00, /* REG_ARX2VTXPGA (0x18) */ - 0x32, /* REG_ARXL1_APGA_CTL (0x19) */ - 0x32, /* REG_ARXR1_APGA_CTL (0x1A) */ - 0x32, /* REG_ARXL2_APGA_CTL (0x1B) */ - 0x32, /* REG_ARXR2_APGA_CTL (0x1C) */ - 0x00, /* REG_ATX2ARXPGA (0x1D) */ - 0x00, /* REG_BT_IF (0x1E) */ - 0x55, /* REG_BTPGA (0x1F) */ - 0x00, /* REG_BTSTPGA (0x20) */ - 0x00, /* REG_EAR_CTL (0x21) */ - 0x00, /* REG_HS_SEL (0x22) */ - 0x00, /* REG_HS_GAIN_SET (0x23) */ - 0x00, /* REG_HS_POPN_SET (0x24) */ - 0x00, /* REG_PREDL_CTL (0x25) */ - 0x00, /* REG_PREDR_CTL (0x26) */ - 0x00, /* REG_PRECKL_CTL (0x27) */ - 0x00, /* REG_PRECKR_CTL (0x28) */ - 0x00, /* REG_HFL_CTL (0x29) */ - 0x00, /* REG_HFR_CTL (0x2A) */ - 0x05, /* REG_ALC_CTL (0x2B) */ - 0x00, /* REG_ALC_SET1 (0x2C) */ - 0x00, /* REG_ALC_SET2 (0x2D) */ - 0x00, /* REG_BOOST_CTL (0x2E) */ - 0x00, /* REG_SOFTVOL_CTL (0x2F) */ - 0x13, /* REG_DTMF_FREQSEL (0x30) */ - 0x00, /* REG_DTMF_TONEXT1H (0x31) */ - 0x00, /* REG_DTMF_TONEXT1L (0x32) */ - 0x00, /* REG_DTMF_TONEXT2H (0x33) */ - 0x00, /* REG_DTMF_TONEXT2L (0x34) */ - 0x79, /* REG_DTMF_TONOFF (0x35) */ - 0x11, /* REG_DTMF_WANONOFF (0x36) */ - 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ - 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ - 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ - 0x06, /* REG_APLL_CTL (0x3A) */ - 0x00, /* REG_DTMF_CTL (0x3B) */ - 0x44, /* REG_DTMF_PGA_CTL2 (0x3C) */ - 0x69, /* REG_DTMF_PGA_CTL1 (0x3D) */ - 0x00, /* REG_MISC_SET_1 (0x3E) */ - 0x00, /* REG_PCMBTMUX (0x3F) */ - 0x00, /* not used (0x40) */ - 0x00, /* not used (0x41) */ - 0x00, /* not used (0x42) */ - 0x00, /* REG_RX_PATH_SEL (0x43) */ - 0x32, /* REG_VDL_APGA_CTL (0x44) */ - 0x00, /* REG_VIBRA_CTL (0x45) */ - 0x00, /* REG_VIBRA_SET (0x46) */ - 0x00, /* REG_VIBRA_PWM_SET (0x47) */ - 0x00, /* REG_ANAMIC_GAIN (0x48) */ - 0x00, /* REG_MISC_SET_2 (0x49) */ -}; - /* codec private data */ struct twl4030_priv { unsigned int codec_powered; @@ -150,81 +70,108 @@ struct twl4030_priv { u8 earpiece_enabled; u8 predrivel_enabled, predriver_enabled; u8 carkitl_enabled, carkitr_enabled; + u8 ctl_cache[TWL4030_REG_PRECKR_CTL - TWL4030_REG_EAR_CTL + 1]; struct twl4030_codec_data *pdata; }; -/* - * read twl4030 register cache - */ -static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) +static void tw4030_init_ctl_cache(struct twl4030_priv *twl4030) { - u8 *cache = codec->reg_cache; + int i; + u8 byte; + + for (i = TWL4030_REG_EAR_CTL; i <= TWL4030_REG_PRECKR_CTL; i++) { + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, i); + twl4030->ctl_cache[i - TWL4030_REG_EAR_CTL] = byte; + } +} + +static unsigned int twl4030_read(struct snd_soc_codec *codec, unsigned int reg) +{ + struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); + u8 value = 0; if (reg >= TWL4030_CACHEREGNUM) return -EIO; - return cache[reg]; + switch (reg) { + case TWL4030_REG_EAR_CTL: + case TWL4030_REG_PREDL_CTL: + case TWL4030_REG_PREDR_CTL: + case TWL4030_REG_PRECKL_CTL: + case TWL4030_REG_PRECKR_CTL: + case TWL4030_REG_HS_GAIN_SET: + value = twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL]; + break; + default: + twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg); + break; + } + + return value; } -/* - * write twl4030 register cache - */ -static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec, - u8 reg, u8 value) +static bool twl4030_can_write_to_chip(struct twl4030_priv *twl4030, + unsigned int reg) { - u8 *cache = codec->reg_cache; + bool write_to_reg = false; - if (reg >= TWL4030_CACHEREGNUM) - return; - cache[reg] = value; -} - -/* - * write to the twl4030 register space - */ -static int twl4030_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); - int write_to_reg = 0; - - twl4030_write_reg_cache(codec, reg, value); /* Decide if the given register can be written */ switch (reg) { case TWL4030_REG_EAR_CTL: if (twl4030->earpiece_enabled) - write_to_reg = 1; + write_to_reg = true; break; case TWL4030_REG_PREDL_CTL: if (twl4030->predrivel_enabled) - write_to_reg = 1; + write_to_reg = true; break; case TWL4030_REG_PREDR_CTL: if (twl4030->predriver_enabled) - write_to_reg = 1; + write_to_reg = true; break; case TWL4030_REG_PRECKL_CTL: if (twl4030->carkitl_enabled) - write_to_reg = 1; + write_to_reg = true; break; case TWL4030_REG_PRECKR_CTL: if (twl4030->carkitr_enabled) - write_to_reg = 1; + write_to_reg = true; break; case TWL4030_REG_HS_GAIN_SET: if (twl4030->hsl_enabled || twl4030->hsr_enabled) - write_to_reg = 1; + write_to_reg = true; break; default: /* All other register can be written */ - write_to_reg = 1; + write_to_reg = true; break; } - if (write_to_reg) - return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - value, reg); + + return write_to_reg; +} + +static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); + + /* Update the ctl cache */ + switch (reg) { + case TWL4030_REG_EAR_CTL: + case TWL4030_REG_PREDL_CTL: + case TWL4030_REG_PREDR_CTL: + case TWL4030_REG_PRECKL_CTL: + case TWL4030_REG_PRECKR_CTL: + case TWL4030_REG_HS_GAIN_SET: + twl4030->ctl_cache[reg - TWL4030_REG_EAR_CTL] = value; + break; + default: + break; + } + + if (twl4030_can_write_to_chip(twl4030, reg)) + return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); return 0; } @@ -252,46 +199,14 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) else mode = twl4030_audio_disable_resource(TWL4030_AUDIO_RES_POWER); - if (mode >= 0) { - twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode); + if (mode >= 0) twl4030->codec_powered = enable; - } /* REVISIT: this delay is present in TI sample drivers */ /* but there seems to be no TRM requirement for it */ udelay(10); } -static inline void twl4030_check_defaults(struct snd_soc_codec *codec) -{ - int i, difference = 0; - u8 val; - - dev_dbg(codec->dev, "Checking TWL audio default configuration\n"); - for (i = 1; i <= TWL4030_REG_MISC_SET_2; i++) { - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &val, i); - if (val != twl4030_reg[i]) { - difference++; - dev_dbg(codec->dev, - "Reg 0x%02x: chip: 0x%02x driver: 0x%02x\n", - i, val, twl4030_reg[i]); - } - } - dev_dbg(codec->dev, "Found %d non-matching registers. %s\n", - difference, difference ? "Not OK" : "OK"); -} - -static inline void twl4030_reset_registers(struct snd_soc_codec *codec) -{ - int i; - - /* set all audio section registers to reasonable defaults */ - for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) - if (i != TWL4030_REG_APLL_CTL) - twl4030_write(codec, i, twl4030_reg[i]); - -} - static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata, struct device_node *node) { @@ -372,27 +287,17 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) } } - /* Check defaults, if instructed before anything else */ - if (pdata && pdata->check_defaults) - twl4030_check_defaults(codec); - - /* Reset registers, if no setup data or if instructed to do so */ - if (!pdata || (pdata && pdata->reset_registers)) - twl4030_reset_registers(codec); - - /* Refresh APLL_CTL register from HW */ - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, - TWL4030_REG_APLL_CTL); - twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, byte); + /* Initialize the local ctl register cache */ + tw4030_init_ctl_cache(twl4030); /* anti-pop when changing analog gain */ - reg = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1); + reg = twl4030_read(codec, TWL4030_REG_MISC_SET_1); twl4030_write(codec, TWL4030_REG_MISC_SET_1, - reg | TWL4030_SMOOTH_ANAVOL_EN); + reg | TWL4030_SMOOTH_ANAVOL_EN); twl4030_write(codec, TWL4030_REG_OPTION, - TWL4030_ATXL1_EN | TWL4030_ATXR1_EN | - TWL4030_ARXL2_EN | TWL4030_ARXR2_EN); + TWL4030_ATXL1_EN | TWL4030_ATXR1_EN | + TWL4030_ARXL2_EN | TWL4030_ARXR2_EN); /* REG_ARXR2_APGA_CTL reset according to the TRM: 0dB, DA_EN */ twl4030_write(codec, TWL4030_REG_ARXR2_APGA_CTL, 0x32); @@ -403,19 +308,19 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) twl4030->pdata = pdata; - reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + reg = twl4030_read(codec, TWL4030_REG_HS_POPN_SET); reg &= ~TWL4030_RAMP_DELAY; reg |= (pdata->ramp_delay_value << 2); - twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, reg); + twl4030_write(codec, TWL4030_REG_HS_POPN_SET, reg); /* initiate offset cancellation */ twl4030_codec_enable(codec, 1); - reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL); + reg = twl4030_read(codec, TWL4030_REG_ANAMICL); reg &= ~TWL4030_OFFSET_CNCL_SEL; reg |= pdata->offset_cncl_path; twl4030_write(codec, TWL4030_REG_ANAMICL, - reg | TWL4030_CNCL_OFFSET_START); + reg | TWL4030_CNCL_OFFSET_START); /* * Wait for offset cancellation to complete. @@ -425,15 +330,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) msleep(20); do { usleep_range(1000, 2000); + twl_set_regcache_bypass(TWL4030_MODULE_AUDIO_VOICE, true); twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, - TWL4030_REG_ANAMICL); + TWL4030_REG_ANAMICL); + twl_set_regcache_bypass(TWL4030_MODULE_AUDIO_VOICE, false); } while ((i++ < 100) && ((byte & TWL4030_CNCL_OFFSET_START) == TWL4030_CNCL_OFFSET_START)); - /* Make sure that the reg_cache has the same value as the HW */ - twl4030_write_reg_cache(codec, TWL4030_REG_ANAMICL, byte); - twl4030_codec_enable(codec, 0); } @@ -453,9 +357,6 @@ static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable) status = twl4030_audio_disable_resource( TWL4030_AUDIO_RES_APLL); } - - if (status >= 0) - twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status); } /* Earpiece */ @@ -671,20 +572,18 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control = */ #define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \ static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \ - struct snd_kcontrol *kcontrol, int event) \ + struct snd_kcontrol *kcontrol, int event) \ { \ struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \ \ switch (event) { \ case SND_SOC_DAPM_POST_PMU: \ twl4030->pin_name##_enabled = 1; \ - twl4030_write(w->codec, reg, \ - twl4030_read_reg_cache(w->codec, reg)); \ + twl4030_write(w->codec, reg, twl4030_read(w->codec, reg)); \ break; \ case SND_SOC_DAPM_POST_PMD: \ twl4030->pin_name##_enabled = 0; \ - twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \ - 0, reg); \ + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 0, reg); \ break; \ } \ return 0; \ @@ -700,7 +599,7 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) { unsigned char hs_ctl; - hs_ctl = twl4030_read_reg_cache(codec, reg); + hs_ctl = twl4030_read(codec, reg); if (ramp) { /* HF ramp-up */ @@ -727,7 +626,7 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) } static int handsfreelpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { switch (event) { case SND_SOC_DAPM_POST_PMU: @@ -741,7 +640,7 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w, } static int handsfreerpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { switch (event) { case SND_SOC_DAPM_POST_PMU: @@ -755,14 +654,14 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w, } static int vibramux_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff); return 0; } static int apll_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -776,11 +675,11 @@ static int apll_event(struct snd_soc_dapm_widget *w, } static int aif_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { u8 audio_if; - audio_if = twl4030_read_reg_cache(w->codec, TWL4030_REG_AUDIO_IF); + audio_if = twl4030_read(w->codec, TWL4030_REG_AUDIO_IF); switch (event) { case SND_SOC_DAPM_PRE_PMU: /* Enable AIF */ @@ -788,12 +687,12 @@ static int aif_event(struct snd_soc_dapm_widget *w, twl4030_apll_enable(w->codec, 1); twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, - audio_if | TWL4030_AIF_EN); + audio_if | TWL4030_AIF_EN); break; case SND_SOC_DAPM_POST_PMD: /* disable the DAI before we stop it's source PLL */ twl4030_write(w->codec, TWL4030_REG_AUDIO_IF, - audio_if & ~TWL4030_AIF_EN); + audio_if & ~TWL4030_AIF_EN); twl4030_apll_enable(w->codec, 0); break; } @@ -810,8 +709,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) 8388608, 16777216, 33554432, 67108864}; unsigned int delay; - hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); - hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + hs_gain = twl4030_read(codec, TWL4030_REG_HS_GAIN_SET); + hs_pop = twl4030_read(codec, TWL4030_REG_HS_POPN_SET); delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / twl4030->sysclk) + 1; @@ -831,9 +730,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) hs_pop |= TWL4030_VMID_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Actually write to the register */ - twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - hs_gain, - TWL4030_REG_HS_GAIN_SET); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain, + TWL4030_REG_HS_GAIN_SET); hs_pop |= TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ @@ -846,9 +744,8 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) /* Wait ramp delay time + 1, so the VMID can settle */ twl4030_wait_ms(delay); /* Bypass the reg_cache to mute the headset */ - twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - hs_gain & (~0x0f), - TWL4030_REG_HS_GAIN_SET); + twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), + TWL4030_REG_HS_GAIN_SET); hs_pop &= ~TWL4030_VMID_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); @@ -866,7 +763,7 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) } static int headsetlpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); @@ -890,7 +787,7 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w, } static int headsetrpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); @@ -914,7 +811,7 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w, } static int digimic_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); struct twl4030_codec_data *pdata = twl4030->pdata; @@ -935,7 +832,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w, * Custom volsw and volsw_2r get/put functions to handle these gain bits. */ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -964,7 +861,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, } static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -993,7 +890,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, } static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -1020,7 +917,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, } static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -1751,11 +1648,11 @@ static void twl4030_constraints(struct twl4030_priv *twl4030, /* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for * capture has to be enabled/disabled. */ static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction, - int enable) + int enable) { u8 reg, mask; - reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); + reg = twl4030_read(codec, TWL4030_REG_OPTION); if (direction == SNDRV_PCM_STREAM_PLAYBACK) mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN; @@ -1784,14 +1681,14 @@ static int twl4030_startup(struct snd_pcm_substream *substream, if (twl4030->configured) twl4030_constraints(twl4030, twl4030->master_substream); } else { - if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & + if (!(twl4030_read(codec, TWL4030_REG_CODEC_MODE) & TWL4030_OPTION_1)) { /* In option2 4 channel is not supported, set the * constraint for the first stream for channels, the * second stream will 'inherit' this cosntraint */ snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_CHANNELS, - 2, 2); + SNDRV_PCM_HW_PARAM_CHANNELS, + 2, 2); } twl4030->master_substream = substream; } @@ -1823,8 +1720,8 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream, } static int twl4030_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -1832,8 +1729,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, /* If the substream has 4 channel, do the necessary setup */ if (params_channels(params) == 4) { - format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); - mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); + format = twl4030_read(codec, TWL4030_REG_AUDIO_IF); + mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE); /* Safety check: are we in the correct operating mode and * the interface is in TDM mode? */ @@ -1849,8 +1746,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, return 0; /* bit rate */ - old_mode = twl4030_read_reg_cache(codec, - TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; + old_mode = twl4030_read(codec, + TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; mode = old_mode & ~TWL4030_APLL_RATE; switch (params_rate(params)) { @@ -1891,7 +1788,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, } /* sample size */ - old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); + old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF); format = old_format; format &= ~TWL4030_DATA_WIDTH; switch (params_format(params)) { @@ -1940,8 +1837,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, return 0; } -static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) +static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, + unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -1966,15 +1863,14 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, return 0; } -static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) +static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); u8 old_format, format; /* get format */ - old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); + old_format = twl4030_read(codec, TWL4030_REG_AUDIO_IF); format = old_format; /* set master/slave audio interface */ @@ -2024,7 +1920,7 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate) { struct snd_soc_codec *codec = dai->codec; - u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); + u8 reg = twl4030_read(codec, TWL4030_REG_AUDIO_IF); if (tristate) reg |= TWL4030_AIF_TRI_EN; @@ -2037,11 +1933,11 @@ static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate) /* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R * (VTXL, VTXR) for uplink has to be enabled/disabled. */ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, - int enable) + int enable) { u8 reg, mask; - reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); + reg = twl4030_read(codec, TWL4030_REG_OPTION); if (direction == SNDRV_PCM_STREAM_PLAYBACK) mask = TWL4030_ARXL1_VRX_EN; @@ -2057,7 +1953,7 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, } static int twl4030_voice_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) + struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -2076,7 +1972,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, /* If the codec mode is not option2, the voice PCM interface is not * available. */ - mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) + mode = twl4030_read(codec, TWL4030_REG_CODEC_MODE) & TWL4030_OPT_MODE; if (mode != TWL4030_OPTION_2) { @@ -2089,7 +1985,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, } static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) + struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; @@ -2098,7 +1994,8 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, } static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -2108,8 +2005,8 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, twl4030_voice_enable(codec, substream->stream, 1); /* bit rate */ - old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) - & ~(TWL4030_CODECPDZ); + old_mode = twl4030_read(codec, + TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ; mode = old_mode; switch (params_rate(params)) { @@ -2143,7 +2040,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, } static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) + int clk_id, unsigned int freq, int dir) { struct snd_soc_codec *codec = codec_dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -2164,14 +2061,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, } static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) + unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); u8 old_format, format; /* get format */ - old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); + old_format = twl4030_read(codec, TWL4030_REG_VOICE_IF); format = old_format; /* set master/slave audio interface */ @@ -2218,7 +2115,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate) { struct snd_soc_codec *codec = dai->codec; - u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); + u8 reg = twl4030_read(codec, TWL4030_REG_VOICE_IF); if (tristate) reg |= TWL4030_VIF_TRI_EN; @@ -2310,8 +2207,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); struct twl4030_codec_data *pdata = twl4030->pdata; - /* Reset registers to their chip default before leaving */ - twl4030_reset_registers(codec); twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) @@ -2323,13 +2218,10 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .probe = twl4030_soc_probe, .remove = twl4030_soc_remove, - .read = twl4030_read_reg_cache, + .read = twl4030_read, .write = twl4030_write, .set_bias_level = twl4030_set_bias_level, .idle_bias_off = true, - .reg_cache_size = sizeof(twl4030_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = twl4030_reg, .controls = twl4030_snd_controls, .num_controls = ARRAY_SIZE(twl4030_snd_controls), @@ -2342,7 +2234,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { static int twl4030_codec_probe(struct platform_device *pdev) { return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030, - twl4030_dai, ARRAY_SIZE(twl4030_dai)); + twl4030_dai, ARRAY_SIZE(twl4030_dai)); } static int twl4030_codec_remove(struct platform_device *pdev) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index f2f4bcb2ff71..0afe8bef6765 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -72,6 +72,7 @@ struct twl6040_data { int hs_power_mode_locked; bool dl1_unmuted; bool dl2_unmuted; + u8 dl12_cache[TWL6040_REG_HFRCTL - TWL6040_REG_HSLCTL + 1]; unsigned int clk_in; unsigned int sysclk; struct twl6040_jack_data hs_jack; @@ -79,75 +80,6 @@ struct twl6040_data { struct mutex mutex; }; -/* - * twl6040 register cache & default register settings - */ -static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { - 0x00, /* not used 0x00 */ - 0x4B, /* REG_ASICID 0x01 (ro) */ - 0x00, /* REG_ASICREV 0x02 (ro) */ - 0x00, /* REG_INTID 0x03 */ - 0x00, /* REG_INTMR 0x04 */ - 0x00, /* REG_NCPCTRL 0x05 */ - 0x00, /* REG_LDOCTL 0x06 */ - 0x60, /* REG_HPPLLCTL 0x07 */ - 0x00, /* REG_LPPLLCTL 0x08 */ - 0x4A, /* REG_LPPLLDIV 0x09 */ - 0x00, /* REG_AMICBCTL 0x0A */ - 0x00, /* REG_DMICBCTL 0x0B */ - 0x00, /* REG_MICLCTL 0x0C */ - 0x00, /* REG_MICRCTL 0x0D */ - 0x00, /* REG_MICGAIN 0x0E */ - 0x1B, /* REG_LINEGAIN 0x0F */ - 0x00, /* REG_HSLCTL 0x10 */ - 0x00, /* REG_HSRCTL 0x11 */ - 0x00, /* REG_HSGAIN 0x12 */ - 0x00, /* REG_EARCTL 0x13 */ - 0x00, /* REG_HFLCTL 0x14 */ - 0x00, /* REG_HFLGAIN 0x15 */ - 0x00, /* REG_HFRCTL 0x16 */ - 0x00, /* REG_HFRGAIN 0x17 */ - 0x00, /* REG_VIBCTLL 0x18 */ - 0x00, /* REG_VIBDATL 0x19 */ - 0x00, /* REG_VIBCTLR 0x1A */ - 0x00, /* REG_VIBDATR 0x1B */ - 0x00, /* REG_HKCTL1 0x1C */ - 0x00, /* REG_HKCTL2 0x1D */ - 0x00, /* REG_GPOCTL 0x1E */ - 0x00, /* REG_ALB 0x1F */ - 0x00, /* REG_DLB 0x20 */ - 0x00, /* not used 0x21 */ - 0x00, /* not used 0x22 */ - 0x00, /* not used 0x23 */ - 0x00, /* not used 0x24 */ - 0x00, /* not used 0x25 */ - 0x00, /* not used 0x26 */ - 0x00, /* not used 0x27 */ - 0x00, /* REG_TRIM1 0x28 */ - 0x00, /* REG_TRIM2 0x29 */ - 0x00, /* REG_TRIM3 0x2A */ - 0x00, /* REG_HSOTRIM 0x2B */ - 0x00, /* REG_HFOTRIM 0x2C */ - 0x09, /* REG_ACCCTL 0x2D */ - 0x00, /* REG_STATUS 0x2E (ro) */ -}; - -/* List of registers to be restored after power up */ -static const int twl6040_restore_list[] = { - TWL6040_REG_MICLCTL, - TWL6040_REG_MICRCTL, - TWL6040_REG_MICGAIN, - TWL6040_REG_LINEGAIN, - TWL6040_REG_HSLCTL, - TWL6040_REG_HSRCTL, - TWL6040_REG_HSGAIN, - TWL6040_REG_EARCTL, - TWL6040_REG_HFLCTL, - TWL6040_REG_HFLGAIN, - TWL6040_REG_HFRCTL, - TWL6040_REG_HFRGAIN, -}; - /* set of rates for each pll: low-power and high-performance */ static unsigned int lp_rates[] = { 8000, @@ -174,53 +106,33 @@ static struct snd_pcm_hw_constraint_list sysclk_constraints[] = { { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, }; -/* - * read twl6040 register cache - */ -static inline unsigned int twl6040_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u8 *cache = codec->reg_cache; - - if (reg >= TWL6040_CACHEREGNUM) - return -EIO; - - return cache[reg]; -} - -/* - * write twl6040 register cache - */ -static inline void twl6040_write_reg_cache(struct snd_soc_codec *codec, - u8 reg, u8 value) -{ - u8 *cache = codec->reg_cache; - - if (reg >= TWL6040_CACHEREGNUM) - return; - cache[reg] = value; -} - -/* - * read from twl6040 hardware register - */ -static int twl6040_read_reg_volatile(struct snd_soc_codec *codec, - unsigned int reg) +static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg) { + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); struct twl6040 *twl6040 = codec->control_data; u8 value; if (reg >= TWL6040_CACHEREGNUM) return -EIO; - value = twl6040_reg_read(twl6040, reg); - twl6040_write_reg_cache(codec, reg, value); + switch (reg) { + case TWL6040_REG_HSLCTL: + case TWL6040_REG_HSRCTL: + case TWL6040_REG_EARCTL: + case TWL6040_REG_HFLCTL: + case TWL6040_REG_HFRCTL: + value = priv->dl12_cache[reg - TWL6040_REG_HSLCTL]; + break; + default: + value = twl6040_reg_read(twl6040, reg); + break; + } return value; } -static bool twl6040_is_path_unmuted(struct snd_soc_codec *codec, - unsigned int reg) +static bool twl6040_can_write_to_chip(struct snd_soc_codec *codec, + unsigned int reg) { struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); @@ -238,9 +150,24 @@ static bool twl6040_is_path_unmuted(struct snd_soc_codec *codec, } } -/* - * write to the twl6040 register space - */ +static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec, + u8 reg, u8 value) +{ + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + + switch (reg) { + case TWL6040_REG_HSLCTL: + case TWL6040_REG_HSRCTL: + case TWL6040_REG_EARCTL: + case TWL6040_REG_HFLCTL: + case TWL6040_REG_HFRCTL: + priv->dl12_cache[reg - TWL6040_REG_HSLCTL] = value; + break; + default: + break; + } +} + static int twl6040_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { @@ -249,8 +176,8 @@ static int twl6040_write(struct snd_soc_codec *codec, if (reg >= TWL6040_CACHEREGNUM) return -EIO; - twl6040_write_reg_cache(codec, reg, value); - if (twl6040_is_path_unmuted(codec, reg)) + twl6040_update_dl12_cache(codec, reg, value); + if (twl6040_can_write_to_chip(codec, reg)) return twl6040_reg_write(twl6040, reg, value); else return 0; @@ -258,45 +185,27 @@ static int twl6040_write(struct snd_soc_codec *codec, static void twl6040_init_chip(struct snd_soc_codec *codec) { - struct twl6040 *twl6040 = codec->control_data; - u8 val; - - /* Update reg_cache: ASICREV, and TRIM values */ - val = twl6040_get_revid(twl6040); - twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val); - - twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1); - twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2); - twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3); - twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM); - twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM); + twl6040_read(codec, TWL6040_REG_TRIM1); + twl6040_read(codec, TWL6040_REG_TRIM2); + twl6040_read(codec, TWL6040_REG_TRIM3); + twl6040_read(codec, TWL6040_REG_HSOTRIM); + twl6040_read(codec, TWL6040_REG_HFOTRIM); /* Change chip defaults */ /* No imput selected for microphone amplifiers */ - twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18); - twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18); + twl6040_write(codec, TWL6040_REG_MICLCTL, 0x18); + twl6040_write(codec, TWL6040_REG_MICRCTL, 0x18); /* * We need to lower the default gain values, so the ramp code * can work correctly for the first playback. * This reduces the pop noise heard at the first playback. */ - twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff); - twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e); - twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d); - twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d); - twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0); -} - -static void twl6040_restore_regs(struct snd_soc_codec *codec) -{ - u8 *cache = codec->reg_cache; - int reg, i; - - for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) { - reg = twl6040_restore_list[i]; - twl6040_write(codec, reg, cache[reg]); - } + twl6040_write(codec, TWL6040_REG_HSGAIN, 0xff); + twl6040_write(codec, TWL6040_REG_EARCTL, 0x1e); + twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1d); + twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1d); + twl6040_write(codec, TWL6040_REG_LINEGAIN, 0); } /* set headset dac and driver power mode */ @@ -305,8 +214,8 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) int hslctl, hsrctl; int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE; - hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); - hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); + hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL); + hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL); if (high_perf) { hslctl &= ~mask; @@ -333,8 +242,8 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, * Both HS DAC need to be turned on (before the HS driver) and off at * the same time. */ - hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); - hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); + hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL); + hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL); if (SND_SOC_DAPM_EVENT_ON(event)) { hslctl |= TWL6040_HSDACENA; hsrctl |= TWL6040_HSDACENA; @@ -379,7 +288,7 @@ static void twl6040_hs_jack_report(struct snd_soc_codec *codec, mutex_lock(&priv->mutex); /* Sync status */ - status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS); + status = twl6040_read(codec, TWL6040_REG_STATUS); if (status & TWL6040_PLUGCOMP) snd_soc_jack_report(jack, report, report); else @@ -431,7 +340,7 @@ static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, unsigned int val; /* Do not allow changes while Input/FF efect is running */ - val = twl6040_read_reg_volatile(codec, e->reg); + val = twl6040_read(codec, e->reg); if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL)) return -EBUSY; @@ -656,7 +565,7 @@ int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim) if (unlikely(trim >= TWL6040_TRIM_INVAL)) return -EINVAL; - return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim); + return twl6040_read(codec, TWL6040_REG_TRIM1 + trim); } EXPORT_SYMBOL_GPL(twl6040_get_trim_value); @@ -931,8 +840,6 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, priv->codec_powered = 1; - twl6040_restore_regs(codec); - /* Set external boost GPO */ twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); break; @@ -1053,9 +960,9 @@ static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id i switch (id) { case TWL6040_DAI_DL1: - hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); - hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); - earctl = twl6040_read_reg_cache(codec, TWL6040_REG_EARCTL); + hslctl = twl6040_read(codec, TWL6040_REG_HSLCTL); + hsrctl = twl6040_read(codec, TWL6040_REG_HSRCTL); + earctl = twl6040_read(codec, TWL6040_REG_EARCTL); if (mute) { /* Power down drivers and DACs */ @@ -1071,8 +978,8 @@ static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id i priv->dl1_unmuted = !mute; break; case TWL6040_DAI_DL2: - hflctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFLCTL); - hfrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HFRCTL); + hflctl = twl6040_read(codec, TWL6040_REG_HFLCTL); + hfrctl = twl6040_read(codec, TWL6040_REG_HFRCTL); if (mute) { /* Power down drivers and DACs */ @@ -1209,6 +1116,7 @@ static int twl6040_resume(struct snd_soc_codec *codec) static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; + struct twl6040 *twl6040 = dev_get_drvdata(codec->dev->parent); struct platform_device *pdev = container_of(codec->dev, struct platform_device, dev); int ret = 0; @@ -1220,7 +1128,7 @@ static int twl6040_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, priv); priv->codec = codec; - codec->control_data = dev_get_drvdata(codec->dev->parent); + codec->control_data = twl6040; priv->plug_irq = platform_get_irq(pdev, 0); if (priv->plug_irq < 0) { @@ -1240,10 +1148,10 @@ static int twl6040_probe(struct snd_soc_codec *codec) return ret; } + twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); twl6040_init_chip(codec); - /* power on device */ - return twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; } static int twl6040_remove(struct snd_soc_codec *codec) @@ -1261,12 +1169,9 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .remove = twl6040_remove, .suspend = twl6040_suspend, .resume = twl6040_resume, - .read = twl6040_read_reg_cache, + .read = twl6040_read, .write = twl6040_write, .set_bias_level = twl6040_set_bias_level, - .reg_cache_size = ARRAY_SIZE(twl6040_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = twl6040_reg, .ignore_pmdown_time = true, .controls = twl6040_snd_controls, diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index fd0a314bc209..726df6d43c2b 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -794,7 +794,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int uda1380_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -840,7 +840,7 @@ static struct i2c_driver uda1380_i2c_driver = { static int __init uda1380_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&uda1380_i2c_driver); if (ret != 0) pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); @@ -851,7 +851,7 @@ module_init(uda1380_modinit); static void __exit uda1380_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&uda1380_i2c_driver); #endif } diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index a08e8bf6d07c..ce9c8e14d4bd 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -601,8 +601,8 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: if (patch) for (i = 0; i < patch_size; i++) - regmap_write(regmap, patch[i].reg, - patch[i].def); + regmap_write_async(regmap, patch[i].reg, + patch[i].def); break; default: diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 0ab2dc296474..d862f76b59f9 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -30,13 +30,51 @@ #include #include "arizona.h" +#include "wm_adsp.h" #include "wm5110.h" +#define WM5110_NUM_ADSP 4 + struct wm5110_priv { struct arizona_priv core; struct arizona_fll fll[2]; }; +static const struct wm_adsp_region wm5110_dsp1_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x100000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x180000 }, + { .type = WMFW_ADSP2_XM, .base = 0x190000 }, + { .type = WMFW_ADSP2_YM, .base = 0x1a8000 }, +}; + +static const struct wm_adsp_region wm5110_dsp2_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x200000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x280000 }, + { .type = WMFW_ADSP2_XM, .base = 0x290000 }, + { .type = WMFW_ADSP2_YM, .base = 0x2a8000 }, +}; + +static const struct wm_adsp_region wm5110_dsp3_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x300000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x380000 }, + { .type = WMFW_ADSP2_XM, .base = 0x390000 }, + { .type = WMFW_ADSP2_YM, .base = 0x3a8000 }, +}; + +static const struct wm_adsp_region wm5110_dsp4_regions[] = { + { .type = WMFW_ADSP2_PM, .base = 0x400000 }, + { .type = WMFW_ADSP2_ZM, .base = 0x480000 }, + { .type = WMFW_ADSP2_XM, .base = 0x490000 }, + { .type = WMFW_ADSP2_YM, .base = 0x4a8000 }, +}; + +static const struct wm_adsp_region *wm5110_dsp_regions[] = { + wm5110_dsp1_regions, + wm5110_dsp2_regions, + wm5110_dsp3_regions, + wm5110_dsp4_regions, +}; + static const struct reg_default wm5110_sysclk_revd_patch[] = { { 0x3093, 0x1001 }, { 0x30E3, 0x1301 }, @@ -67,8 +105,8 @@ static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: if (patch) for (i = 0; i < patch_size; i++) - regmap_write(regmap, patch[i].reg, - patch[i].def); + regmap_write_async(regmap, patch[i].reg, + patch[i].def); break; default: @@ -117,6 +155,25 @@ SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL, SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL, ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), +SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum), + +SOC_SINGLE("IN1L HPF Switch", ARIZONA_IN1L_CONTROL, + ARIZONA_IN1L_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN1R HPF Switch", ARIZONA_IN1R_CONTROL, + ARIZONA_IN1R_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN2L HPF Switch", ARIZONA_IN2L_CONTROL, + ARIZONA_IN2L_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN2R HPF Switch", ARIZONA_IN2R_CONTROL, + ARIZONA_IN2R_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN3L HPF Switch", ARIZONA_IN3L_CONTROL, + ARIZONA_IN3L_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN3R HPF Switch", ARIZONA_IN3R_CONTROL, + ARIZONA_IN3R_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN4L HPF Switch", ARIZONA_IN4L_CONTROL, + ARIZONA_IN4L_HPF_SHIFT, 1, 0), +SOC_SINGLE("IN4R HPF Switch", ARIZONA_IN4R_CONTROL, + ARIZONA_IN4R_HPF_SHIFT, 1, 0), + SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L, ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv), SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R, @@ -220,6 +277,14 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), +SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_VALUE_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), +SOC_VALUE_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), +SOC_VALUE_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), +SOC_VALUE_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), +SOC_VALUE_ENUM("ASRC RATE 1", arizona_asrc_rate1), + ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE), @@ -248,6 +313,13 @@ ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE), +SOC_SINGLE("HPOUT1 SC Protect Switch", ARIZONA_HP1_SHORT_CIRCUIT_CTRL, + ARIZONA_HP1_SC_ENA_SHIFT, 1, 0), +SOC_SINGLE("HPOUT2 SC Protect Switch", ARIZONA_HP2_SHORT_CIRCUIT_CTRL, + ARIZONA_HP2_SC_ENA_SHIFT, 1, 0), +SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL, + ARIZONA_HP3_SC_ENA_SHIFT, 1, 0), + SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, @@ -285,6 +357,13 @@ SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT, SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT, ARIZONA_SPK2R_MUTE_SHIFT, 1, 1), +SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE, + ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0), +SOC_DOUBLE("HPOUT2 DRE Switch", ARIZONA_DRE_ENABLE, + ARIZONA_DRE2L_ENA_SHIFT, ARIZONA_DRE2R_ENA_SHIFT, 1, 0), +SOC_DOUBLE("HPOUT3 DRE Switch", ARIZONA_DRE_ENABLE, + ARIZONA_DRE3L_ENA_SHIFT, ARIZONA_DRE3R_ENA_SHIFT, 1, 0), + SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), @@ -318,6 +397,10 @@ ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF2TX3", ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF2TX4", ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF2TX5", ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("AIF2TX6", ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), @@ -347,6 +430,22 @@ ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP1L, ARIZONA_DSP1LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP1R, ARIZONA_DSP1RMIX_INPUT_1_SOURCE); +ARIZONA_DSP_AUX_ENUMS(DSP1, ARIZONA_DSP1AUX1MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(DSP2L, ARIZONA_DSP2LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP2R, ARIZONA_DSP2RMIX_INPUT_1_SOURCE); +ARIZONA_DSP_AUX_ENUMS(DSP2, ARIZONA_DSP2AUX1MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(DSP3L, ARIZONA_DSP3LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP3R, ARIZONA_DSP3RMIX_INPUT_1_SOURCE); +ARIZONA_DSP_AUX_ENUMS(DSP3, ARIZONA_DSP3AUX1MIX_INPUT_1_SOURCE); + +ARIZONA_MIXER_ENUMS(DSP4L, ARIZONA_DSP4LMIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(DSP4R, ARIZONA_DSP4RMIX_INPUT_1_SOURCE); +ARIZONA_DSP_AUX_ENUMS(DSP4, ARIZONA_DSP4AUX1MIX_INPUT_1_SOURCE); + ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE); @@ -377,6 +476,10 @@ ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF2TX3, ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF2TX4, ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF2TX5, ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE); +ARIZONA_MIXER_ENUMS(AIF2TX6, ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE); @@ -395,6 +498,36 @@ ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE); ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE); ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1INT3, ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1INT4, ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE); + +ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1DEC3, ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC1DEC4, ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE); + +ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC2INT3, ARIZONA_ISRC2INT3MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC2INT4, ARIZONA_ISRC2INT4MIX_INPUT_1_SOURCE); + +ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC2DEC3, ARIZONA_ISRC2DEC3MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC2DEC4, ARIZONA_ISRC2DEC4MIX_INPUT_1_SOURCE); + +ARIZONA_MUX_ENUMS(ISRC3INT1, ARIZONA_ISRC3INT1MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC3INT2, ARIZONA_ISRC3INT2MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC3INT3, ARIZONA_ISRC3INT3MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC3INT4, ARIZONA_ISRC3INT4MIX_INPUT_1_SOURCE); + +ARIZONA_MUX_ENUMS(ISRC3DEC1, ARIZONA_ISRC3DEC1MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC3DEC2, ARIZONA_ISRC3DEC2MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC3DEC3, ARIZONA_ISRC3DEC3MIX_INPUT_1_SOURCE); +ARIZONA_MUX_ENUMS(ISRC3DEC4, ARIZONA_ISRC3DEC4MIX_INPUT_1_SOURCE); + static const char *wm5110_aec_loopback_texts[] = { "HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R", "SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R", @@ -535,6 +668,65 @@ SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0, SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0, NULL, 0), +WM_ADSP2("DSP1", 0), +WM_ADSP2("DSP2", 1), +WM_ADSP2("DSP3", 2), +WM_ADSP2("DSP4", 3), + +SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC1INT3", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC1INT4", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC1DEC3", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC1DEC4", ARIZONA_ISRC_1_CTRL_3, + ARIZONA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC2INT3", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_INT2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC2INT4", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_INT3_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC2DEC3", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_DEC2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC2DEC4", ARIZONA_ISRC_2_CTRL_3, + ARIZONA_ISRC2_DEC3_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("ISRC3INT1", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_INT0_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC3INT2", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_INT1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC3INT3", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_INT2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC3INT4", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_INT3_ENA_SHIFT, 0, NULL, 0), + +SND_SOC_DAPM_PGA("ISRC3DEC1", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_DEC0_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC3DEC2", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_DEC1_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_DEC2_ENA_SHIFT, 0, NULL, 0), +SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3, + ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5110_aec_loopback_mux), @@ -577,11 +769,27 @@ SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0), SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0, ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0, + ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0, + ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0, + ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0, + ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0), SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0), SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0, ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0, + ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0, + ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0, + ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0, + ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0), SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0, ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE, @@ -719,6 +927,10 @@ ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"), ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"), ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), +ARIZONA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"), +ARIZONA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"), +ARIZONA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"), +ARIZONA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"), ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), @@ -737,6 +949,41 @@ ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"), ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"), ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"), +ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), +ARIZONA_DSP_WIDGETS(DSP2, "DSP2"), +ARIZONA_DSP_WIDGETS(DSP3, "DSP3"), +ARIZONA_DSP_WIDGETS(DSP4, "DSP4"), + +ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"), +ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"), +ARIZONA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"), +ARIZONA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"), + +ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"), +ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"), +ARIZONA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"), +ARIZONA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"), + +ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"), +ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"), +ARIZONA_MUX_WIDGETS(ISRC2DEC3, "ISRC2DEC3"), +ARIZONA_MUX_WIDGETS(ISRC2DEC4, "ISRC2DEC4"), + +ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"), +ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"), +ARIZONA_MUX_WIDGETS(ISRC2INT3, "ISRC2INT3"), +ARIZONA_MUX_WIDGETS(ISRC2INT4, "ISRC2INT4"), + +ARIZONA_MUX_WIDGETS(ISRC3DEC1, "ISRC3DEC1"), +ARIZONA_MUX_WIDGETS(ISRC3DEC2, "ISRC3DEC2"), +ARIZONA_MUX_WIDGETS(ISRC3DEC3, "ISRC3DEC3"), +ARIZONA_MUX_WIDGETS(ISRC3DEC4, "ISRC3DEC4"), + +ARIZONA_MUX_WIDGETS(ISRC3INT1, "ISRC3INT1"), +ARIZONA_MUX_WIDGETS(ISRC3INT2, "ISRC3INT2"), +ARIZONA_MUX_WIDGETS(ISRC3INT3, "ISRC3INT3"), +ARIZONA_MUX_WIDGETS(ISRC3INT4, "ISRC3INT4"), + SND_SOC_DAPM_OUTPUT("HPOUT1L"), SND_SOC_DAPM_OUTPUT("HPOUT1R"), SND_SOC_DAPM_OUTPUT("HPOUT2L"), @@ -780,6 +1027,10 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"), { name, "AIF1RX8", "AIF1RX8" }, \ { name, "AIF2RX1", "AIF2RX1" }, \ { name, "AIF2RX2", "AIF2RX2" }, \ + { name, "AIF2RX3", "AIF2RX3" }, \ + { name, "AIF2RX4", "AIF2RX4" }, \ + { name, "AIF2RX5", "AIF2RX5" }, \ + { name, "AIF2RX6", "AIF2RX6" }, \ { name, "AIF3RX1", "AIF3RX1" }, \ { name, "AIF3RX2", "AIF3RX2" }, \ { name, "SLIMRX1", "SLIMRX1" }, \ @@ -805,7 +1056,55 @@ SND_SOC_DAPM_OUTPUT("MICSUPP"), { name, "ASRC1L", "ASRC1L" }, \ { name, "ASRC1R", "ASRC1R" }, \ { name, "ASRC2L", "ASRC2L" }, \ - { name, "ASRC2R", "ASRC2R" } + { name, "ASRC2R", "ASRC2R" }, \ + { name, "ISRC1DEC1", "ISRC1DEC1" }, \ + { name, "ISRC1DEC2", "ISRC1DEC2" }, \ + { name, "ISRC1DEC3", "ISRC1DEC3" }, \ + { name, "ISRC1DEC4", "ISRC1DEC4" }, \ + { name, "ISRC1INT1", "ISRC1INT1" }, \ + { name, "ISRC1INT2", "ISRC1INT2" }, \ + { name, "ISRC1INT3", "ISRC1INT3" }, \ + { name, "ISRC1INT4", "ISRC1INT4" }, \ + { name, "ISRC2DEC1", "ISRC2DEC1" }, \ + { name, "ISRC2DEC2", "ISRC2DEC2" }, \ + { name, "ISRC2DEC3", "ISRC2DEC3" }, \ + { name, "ISRC2DEC4", "ISRC2DEC4" }, \ + { name, "ISRC2INT1", "ISRC2INT1" }, \ + { name, "ISRC2INT2", "ISRC2INT2" }, \ + { name, "ISRC2INT3", "ISRC2INT3" }, \ + { name, "ISRC2INT4", "ISRC2INT4" }, \ + { name, "ISRC3DEC1", "ISRC3DEC1" }, \ + { name, "ISRC3DEC2", "ISRC3DEC2" }, \ + { name, "ISRC3DEC3", "ISRC3DEC3" }, \ + { name, "ISRC3DEC4", "ISRC3DEC4" }, \ + { name, "ISRC3INT1", "ISRC3INT1" }, \ + { name, "ISRC3INT2", "ISRC3INT2" }, \ + { name, "ISRC3INT3", "ISRC3INT3" }, \ + { name, "ISRC3INT4", "ISRC3INT4" }, \ + { name, "DSP1.1", "DSP1" }, \ + { name, "DSP1.2", "DSP1" }, \ + { name, "DSP1.3", "DSP1" }, \ + { name, "DSP1.4", "DSP1" }, \ + { name, "DSP1.5", "DSP1" }, \ + { name, "DSP1.6", "DSP1" }, \ + { name, "DSP2.1", "DSP2" }, \ + { name, "DSP2.2", "DSP2" }, \ + { name, "DSP2.3", "DSP2" }, \ + { name, "DSP2.4", "DSP2" }, \ + { name, "DSP2.5", "DSP2" }, \ + { name, "DSP2.6", "DSP2" }, \ + { name, "DSP3.1", "DSP3" }, \ + { name, "DSP3.2", "DSP3" }, \ + { name, "DSP3.3", "DSP3" }, \ + { name, "DSP3.4", "DSP3" }, \ + { name, "DSP3.5", "DSP3" }, \ + { name, "DSP3.6", "DSP3" }, \ + { name, "DSP4.1", "DSP4" }, \ + { name, "DSP4.2", "DSP4" }, \ + { name, "DSP4.3", "DSP4" }, \ + { name, "DSP4.4", "DSP4" }, \ + { name, "DSP4.5", "DSP4" }, \ + { name, "DSP4.6", "DSP4" } static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { { "AIF2 Capture", NULL, "DBVDD2" }, @@ -877,9 +1176,17 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { { "AIF2 Capture", NULL, "AIF2TX1" }, { "AIF2 Capture", NULL, "AIF2TX2" }, + { "AIF2 Capture", NULL, "AIF2TX3" }, + { "AIF2 Capture", NULL, "AIF2TX4" }, + { "AIF2 Capture", NULL, "AIF2TX5" }, + { "AIF2 Capture", NULL, "AIF2TX6" }, { "AIF2RX1", NULL, "AIF2 Playback" }, { "AIF2RX2", NULL, "AIF2 Playback" }, + { "AIF2RX3", NULL, "AIF2 Playback" }, + { "AIF2RX4", NULL, "AIF2 Playback" }, + { "AIF2RX5", NULL, "AIF2 Playback" }, + { "AIF2RX6", NULL, "AIF2 Playback" }, { "AIF3 Capture", NULL, "AIF3TX1" }, { "AIF3 Capture", NULL, "AIF3TX2" }, @@ -963,6 +1270,10 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"), ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"), + ARIZONA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"), + ARIZONA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"), + ARIZONA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"), + ARIZONA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"), ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), @@ -999,6 +1310,41 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"), ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"), + ARIZONA_DSP_ROUTES("DSP1"), + ARIZONA_DSP_ROUTES("DSP2"), + ARIZONA_DSP_ROUTES("DSP3"), + ARIZONA_DSP_ROUTES("DSP4"), + + ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"), + ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"), + ARIZONA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"), + ARIZONA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"), + + ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"), + ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"), + ARIZONA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"), + ARIZONA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"), + + ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"), + ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"), + ARIZONA_MUX_ROUTES("ISRC2INT3", "ISRC2INT3"), + ARIZONA_MUX_ROUTES("ISRC2INT4", "ISRC2INT4"), + + ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"), + ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"), + ARIZONA_MUX_ROUTES("ISRC2DEC3", "ISRC2DEC3"), + ARIZONA_MUX_ROUTES("ISRC2DEC4", "ISRC2DEC4"), + + ARIZONA_MUX_ROUTES("ISRC3INT1", "ISRC3INT1"), + ARIZONA_MUX_ROUTES("ISRC3INT2", "ISRC3INT2"), + ARIZONA_MUX_ROUTES("ISRC3INT3", "ISRC3INT3"), + ARIZONA_MUX_ROUTES("ISRC3INT4", "ISRC3INT4"), + + ARIZONA_MUX_ROUTES("ISRC3DEC1", "ISRC3DEC1"), + ARIZONA_MUX_ROUTES("ISRC3DEC2", "ISRC3DEC2"), + ARIZONA_MUX_ROUTES("ISRC3DEC3", "ISRC3DEC3"), + ARIZONA_MUX_ROUTES("ISRC3DEC4", "ISRC3DEC4"), + { "AEC Loopback", "HPOUT1L", "OUT1L" }, { "AEC Loopback", "HPOUT1R", "OUT1R" }, { "HPOUT1L", NULL, "OUT1L" }, @@ -1095,14 +1441,14 @@ static struct snd_soc_dai_driver wm5110_dai[] = { .playback = { .stream_name = "AIF2 Playback", .channels_min = 1, - .channels_max = 2, + .channels_max = 6, .rates = WM5110_RATES, .formats = WM5110_FORMATS, }, .capture = { .stream_name = "AIF2 Capture", .channels_min = 1, - .channels_max = 2, + .channels_max = 6, .rates = WM5110_RATES, .formats = WM5110_FORMATS, }, @@ -1204,6 +1550,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) arizona_init_spk(codec); arizona_init_gpio(codec); + ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 8); + if (ret != 0) + return ret; + snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); priv->core.arizona->dapm = &codec->dapm; @@ -1258,7 +1608,7 @@ static int wm5110_probe(struct platform_device *pdev) { struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct wm5110_priv *wm5110; - int i; + int i, ret; wm5110 = devm_kzalloc(&pdev->dev, sizeof(struct wm5110_priv), GFP_KERNEL); @@ -1269,6 +1619,24 @@ static int wm5110_probe(struct platform_device *pdev) wm5110->core.arizona = arizona; wm5110->core.num_inputs = 8; + for (i = 0; i < WM5110_NUM_ADSP; i++) { + wm5110->core.adsp[i].part = "wm5110"; + wm5110->core.adsp[i].num = i + 1; + wm5110->core.adsp[i].type = WMFW_ADSP2; + wm5110->core.adsp[i].dev = arizona->dev; + wm5110->core.adsp[i].regmap = arizona->regmap; + + wm5110->core.adsp[i].base = ARIZONA_DSP1_CONTROL_1 + + (0x100 * i); + wm5110->core.adsp[i].mem = wm5110_dsp_regions[i]; + wm5110->core.adsp[i].num_mems + = ARRAY_SIZE(wm5110_dsp1_regions); + + ret = wm_adsp2_init(&wm5110->core.adsp[i], false); + if (ret != 0) + return ret; + } + for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) wm5110->fll[i].vco_mult = 3; @@ -1279,6 +1647,12 @@ static int wm5110_probe(struct platform_device *pdev) ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, &wm5110->fll[1]); + /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */ + regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2, + ARIZONA_SAMPLE_RATE_2_MASK, 0x11); + regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3, + ARIZONA_SAMPLE_RATE_3_MASK, 0x12); + for (i = 0; i < ARRAY_SIZE(wm5110_dai); i++) arizona_init_dai(&wm5110->core, i); diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 6ed5433943ea..7df7d4572755 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -684,7 +684,7 @@ static struct spi_driver wm8510_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8510_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -735,7 +735,7 @@ static struct i2c_driver wm8510_i2c_driver = { static int __init wm8510_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8510_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8510 I2C driver: %d\n", @@ -755,7 +755,7 @@ module_init(wm8510_modinit); static void __exit wm8510_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8510_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 139bf9ac9407..74d106dc7667 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -452,7 +452,7 @@ static const struct regmap_config wm8523_regmap = { .volatile_reg = wm8523_volatile_register, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8523_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -555,7 +555,7 @@ static struct i2c_driver wm8523_i2c_driver = { static int __init wm8523_modinit(void) { int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8523_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8523 I2C driver: %d\n", @@ -568,7 +568,7 @@ module_init(wm8523_modinit); static void __exit wm8523_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8523_i2c_driver); #endif } diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 08a414b57b1e..318989acbbe5 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -941,7 +941,7 @@ static const struct regmap_config wm8580_regmap = { .volatile_reg = wm8580_volatile, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8580_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1003,7 +1003,7 @@ static int __init wm8580_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8580_i2c_driver); if (ret != 0) { pr_err("Failed to register WM8580 I2C driver: %d\n", ret); @@ -1016,7 +1016,7 @@ module_init(wm8580_modinit); static void __exit wm8580_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8580_i2c_driver); #endif } diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 5b428b060d41..d99f948c513c 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -469,7 +469,7 @@ static struct spi_driver wm8711_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8711_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -520,7 +520,7 @@ static struct i2c_driver wm8711_i2c_driver = { static int __init wm8711_modinit(void) { int ret; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8711_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n", @@ -540,7 +540,7 @@ module_init(wm8711_modinit); static void __exit wm8711_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8711_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index c6a292dcded0..cd89033e84c0 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -320,7 +320,7 @@ static struct spi_driver wm8728_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8728_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -371,7 +371,7 @@ static struct i2c_driver wm8728_i2c_driver = { static int __init wm8728_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8728_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8728 I2C driver: %d\n", @@ -391,7 +391,7 @@ module_init(wm8728_modinit); static void __exit wm8728_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8728_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index bc7472c968e3..029720366ff8 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -732,7 +732,7 @@ static struct spi_driver wm8731_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8731_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -791,7 +791,7 @@ static struct i2c_driver wm8731_i2c_driver = { static int __init wm8731_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8731_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n", @@ -811,7 +811,7 @@ module_init(wm8731_modinit); static void __exit wm8731_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8731_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index b18813cc7ba9..2895c8d3b5e4 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -500,7 +500,7 @@ static const struct regmap_config wm8741_regmap = { .readable_reg = wm8741_readable, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8741_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -617,7 +617,7 @@ static int __init wm8741_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8741_i2c_driver); if (ret != 0) pr_err("Failed to register WM8741 I2C driver: %d\n", ret); @@ -639,7 +639,7 @@ static void __exit wm8741_exit(void) #if defined(CONFIG_SPI_MASTER) spi_unregister_driver(&wm8741_spi_driver); #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8741_i2c_driver); #endif } diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 50d5ff616232..78616a638a55 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -816,7 +816,7 @@ static struct spi_driver wm8750_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8750_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -868,7 +868,7 @@ static struct i2c_driver wm8750_i2c_driver = { static int __init wm8750_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8750_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n", @@ -888,7 +888,7 @@ module_init(wm8750_modinit); static void __exit wm8750_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8750_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index d96ebf52d953..be85da93a268 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1596,7 +1596,7 @@ static struct spi_driver wm8753_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8753_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1653,7 +1653,7 @@ static struct i2c_driver wm8753_i2c_driver = { static int __init wm8753_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8753_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n", @@ -1673,7 +1673,7 @@ module_init(wm8753_modinit); static void __exit wm8753_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8753_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 942d58e455f3..ef8246725232 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -532,7 +532,7 @@ static struct spi_driver wm8776_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8776_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -584,7 +584,7 @@ static struct i2c_driver wm8776_i2c_driver = { static int __init wm8776_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8776_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8776 I2C driver: %d\n", @@ -604,7 +604,7 @@ module_init(wm8776_modinit); static void __exit wm8776_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8776_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 1704b1e119cb..9bc8206a6807 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -739,7 +739,7 @@ static struct spi_driver wm8804_spi_driver = { }; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8804_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -791,7 +791,7 @@ static int __init wm8804_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8804_i2c_driver); if (ret) { printk(KERN_ERR "Failed to register wm8804 I2C driver: %d\n", @@ -811,7 +811,7 @@ module_init(wm8804_modinit); static void __exit wm8804_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8804_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 734209e252c3..e98bc7038a08 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -1288,7 +1288,7 @@ static struct spi_driver wm8900_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8900_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1338,7 +1338,7 @@ static struct i2c_driver wm8900_i2c_driver = { static int __init wm8900_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8900_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n", @@ -1358,7 +1358,7 @@ module_init(wm8900_modinit); static void __exit wm8900_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8900_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index b1591c61c254..b404c26c1753 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -41,78 +41,116 @@ struct wm8940_priv { unsigned int sysclk; - enum snd_soc_control_type control_type; + struct regmap *regmap; }; -static int wm8940_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) +static bool wm8940_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM8940_SOFTRESET: - return 1; + return true; default: - return 0; + return false; } } -static u16 wm8940_reg_defaults[] = { - 0x8940, /* Soft Reset */ - 0x0000, /* Power 1 */ - 0x0000, /* Power 2 */ - 0x0000, /* Power 3 */ - 0x0010, /* Interface Control */ - 0x0000, /* Companding Control */ - 0x0140, /* Clock Control */ - 0x0000, /* Additional Controls */ - 0x0000, /* GPIO Control */ - 0x0002, /* Auto Increment Control */ - 0x0000, /* DAC Control */ - 0x00FF, /* DAC Volume */ - 0, - 0, - 0x0100, /* ADC Control */ - 0x00FF, /* ADC Volume */ - 0x0000, /* Notch Filter 1 Control 1 */ - 0x0000, /* Notch Filter 1 Control 2 */ - 0x0000, /* Notch Filter 2 Control 1 */ - 0x0000, /* Notch Filter 2 Control 2 */ - 0x0000, /* Notch Filter 3 Control 1 */ - 0x0000, /* Notch Filter 3 Control 2 */ - 0x0000, /* Notch Filter 4 Control 1 */ - 0x0000, /* Notch Filter 4 Control 2 */ - 0x0032, /* DAC Limit Control 1 */ - 0x0000, /* DAC Limit Control 2 */ - 0, - 0, - 0, - 0, - 0, - 0, - 0x0038, /* ALC Control 1 */ - 0x000B, /* ALC Control 2 */ - 0x0032, /* ALC Control 3 */ - 0x0000, /* Noise Gate */ - 0x0041, /* PLLN */ - 0x000C, /* PLLK1 */ - 0x0093, /* PLLK2 */ - 0x00E9, /* PLLK3 */ - 0, - 0, - 0x0030, /* ALC Control 4 */ - 0, - 0x0002, /* Input Control */ - 0x0050, /* PGA Gain */ - 0, - 0x0002, /* ADC Boost Control */ - 0, - 0x0002, /* Output Control */ - 0x0000, /* Speaker Mixer Control */ - 0, - 0, - 0, - 0x0079, /* Speaker Volume */ - 0, - 0x0000, /* Mono Mixer Control */ +static bool wm8940_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8940_SOFTRESET: + case WM8940_POWER1: + case WM8940_POWER2: + case WM8940_POWER3: + case WM8940_IFACE: + case WM8940_COMPANDINGCTL: + case WM8940_CLOCK: + case WM8940_ADDCNTRL: + case WM8940_GPIO: + case WM8940_CTLINT: + case WM8940_DAC: + case WM8940_DACVOL: + case WM8940_ADC: + case WM8940_ADCVOL: + case WM8940_NOTCH1: + case WM8940_NOTCH2: + case WM8940_NOTCH3: + case WM8940_NOTCH4: + case WM8940_NOTCH5: + case WM8940_NOTCH6: + case WM8940_NOTCH7: + case WM8940_NOTCH8: + case WM8940_DACLIM1: + case WM8940_DACLIM2: + case WM8940_ALC1: + case WM8940_ALC2: + case WM8940_ALC3: + case WM8940_NOISEGATE: + case WM8940_PLLN: + case WM8940_PLLK1: + case WM8940_PLLK2: + case WM8940_PLLK3: + case WM8940_ALC4: + case WM8940_INPUTCTL: + case WM8940_PGAGAIN: + case WM8940_ADCBOOST: + case WM8940_OUTPUTCTL: + case WM8940_SPKMIX: + case WM8940_SPKVOL: + case WM8940_MONOMIX: + return true; + default: + return false; + } +} + +static const struct reg_default wm8940_reg_defaults[] = { + { 0x1, 0x0000 }, /* Power 1 */ + { 0x2, 0x0000 }, /* Power 2 */ + { 0x3, 0x0000 }, /* Power 3 */ + { 0x4, 0x0010 }, /* Interface Control */ + { 0x5, 0x0000 }, /* Companding Control */ + { 0x6, 0x0140 }, /* Clock Control */ + { 0x7, 0x0000 }, /* Additional Controls */ + { 0x8, 0x0000 }, /* GPIO Control */ + { 0x9, 0x0002 }, /* Auto Increment Control */ + { 0xa, 0x0000 }, /* DAC Control */ + { 0xb, 0x00FF }, /* DAC Volume */ + + { 0xe, 0x0100 }, /* ADC Control */ + { 0xf, 0x00FF }, /* ADC Volume */ + { 0x10, 0x0000 }, /* Notch Filter 1 Control 1 */ + { 0x11, 0x0000 }, /* Notch Filter 1 Control 2 */ + { 0x12, 0x0000 }, /* Notch Filter 2 Control 1 */ + { 0x13, 0x0000 }, /* Notch Filter 2 Control 2 */ + { 0x14, 0x0000 }, /* Notch Filter 3 Control 1 */ + { 0x15, 0x0000 }, /* Notch Filter 3 Control 2 */ + { 0x16, 0x0000 }, /* Notch Filter 4 Control 1 */ + { 0x17, 0x0000 }, /* Notch Filter 4 Control 2 */ + { 0x18, 0x0032 }, /* DAC Limit Control 1 */ + { 0x19, 0x0000 }, /* DAC Limit Control 2 */ + + { 0x20, 0x0038 }, /* ALC Control 1 */ + { 0x21, 0x000B }, /* ALC Control 2 */ + { 0x22, 0x0032 }, /* ALC Control 3 */ + { 0x23, 0x0000 }, /* Noise Gate */ + { 0x24, 0x0041 }, /* PLLN */ + { 0x25, 0x000C }, /* PLLK1 */ + { 0x26, 0x0093 }, /* PLLK2 */ + { 0x27, 0x00E9 }, /* PLLK3 */ + + { 0x2a, 0x0030 }, /* ALC Control 4 */ + + { 0x2c, 0x0002 }, /* Input Control */ + { 0x2d, 0x0050 }, /* PGA Gain */ + + { 0x2f, 0x0002 }, /* ADC Boost Control */ + + { 0x31, 0x0002 }, /* Output Control */ + { 0x32, 0x0000 }, /* Speaker Mixer Control */ + + { 0x36, 0x0079 }, /* Speaker Volume */ + + { 0x38, 0x0000 }, /* Mono Mixer Control */ }; static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; @@ -264,7 +302,7 @@ static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AUX"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8940_dapm_routes[] = { /* Mono output mixer */ {"Mono Mixer", "PCM Playback Switch", "DAC"}, {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, @@ -296,21 +334,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ADC", NULL, "Boost Mixer"}, }; -static int wm8940_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets, - ARRAY_SIZE(wm8940_dapm_widgets)); - if (ret) - goto error_ret; - ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - -error_ret: - return ret; -} - #define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0); static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai, @@ -446,6 +469,7 @@ static int wm8940_mute(struct snd_soc_dai *dai, int mute) static int wm8940_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec); u16 val; u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0; int ret = 0; @@ -469,7 +493,7 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - ret = snd_soc_cache_sync(codec); + ret = regcache_sync(wm8940->regmap); if (ret < 0) { dev_err(codec->dev, "Failed to sync cache: %d\n", ret); return ret; @@ -684,12 +708,11 @@ static int wm8940_resume(struct snd_soc_codec *codec) static int wm8940_probe(struct snd_soc_codec *codec) { - struct wm8940_priv *wm8940 = snd_soc_codec_get_drvdata(codec); struct wm8940_setup_data *pdata = codec->dev->platform_data; int ret; u16 reg; - ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type); + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -716,11 +739,6 @@ static int wm8940_probe(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls, - ARRAY_SIZE(wm8940_snd_controls)); - if (ret) - return ret; - ret = wm8940_add_widgets(codec); return ret; } @@ -736,10 +754,24 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { .suspend = wm8940_suspend, .resume = wm8940_resume, .set_bias_level = wm8940_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8940_reg_defaults, - .volatile_register = wm8940_volatile_register, + .controls = wm8940_snd_controls, + .num_controls = ARRAY_SIZE(wm8940_snd_controls), + .dapm_widgets = wm8940_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8940_dapm_widgets), + .dapm_routes = wm8940_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8940_dapm_routes), +}; + +static const struct regmap_config wm8940_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM8940_MONOMIX, + .reg_defaults = wm8940_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8940_reg_defaults), + + .readable_reg = wm8940_readable_register, + .volatile_reg = wm8940_volatile_register, }; static int wm8940_i2c_probe(struct i2c_client *i2c, @@ -753,8 +785,11 @@ static int wm8940_i2c_probe(struct i2c_client *i2c, if (wm8940 == NULL) return -ENOMEM; + wm8940->regmap = devm_regmap_init_i2c(i2c, &wm8940_regmap); + if (IS_ERR(wm8940->regmap)) + return PTR_ERR(wm8940->regmap); + i2c_set_clientdata(i2c, wm8940); - wm8940->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8940, &wm8940_dai, 1); diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 0f17ed3e29f4..97db3b45b411 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -74,7 +74,7 @@ struct wm8962_priv { struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES]; struct notifier_block disable_nb[WM8962_NUM_SUPPLIES]; -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if IS_ENABLED(CONFIG_INPUT) struct input_dev *beep; struct work_struct beep_work; int beep_rate; @@ -3121,7 +3121,7 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) } EXPORT_SYMBOL_GPL(wm8962_mic_detect); -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if IS_ENABLED(CONFIG_INPUT) static int beep_rates[] = { 500, 1000, 2000, 4000, }; diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index a2d01d10a5dd..15f45c7bd833 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -27,22 +28,22 @@ #include "wm8974.h" -static const u16 wm8974_reg[WM8974_CACHEREGNUM] = { - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0050, 0x0000, 0x0140, 0x0000, - 0x0000, 0x0000, 0x0000, 0x00ff, - 0x0000, 0x0000, 0x0100, 0x00ff, - 0x0000, 0x0000, 0x012c, 0x002c, - 0x002c, 0x002c, 0x002c, 0x0000, - 0x0032, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0038, 0x000b, 0x0032, 0x0000, - 0x0008, 0x000c, 0x0093, 0x00e9, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0003, 0x0010, 0x0000, 0x0000, - 0x0000, 0x0002, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0039, 0x0000, - 0x0000, +static const struct reg_default wm8974_reg_defaults[] = { + { 0, 0x0000 }, { 1, 0x0000 }, { 2, 0x0000 }, { 3, 0x0000 }, + { 4, 0x0050 }, { 5, 0x0000 }, { 6, 0x0140 }, { 7, 0x0000 }, + { 8, 0x0000 }, { 9, 0x0000 }, { 10, 0x0000 }, { 11, 0x00ff }, + { 12, 0x0000 }, { 13, 0x0000 }, { 14, 0x0100 }, { 15, 0x00ff }, + { 16, 0x0000 }, { 17, 0x0000 }, { 18, 0x012c }, { 19, 0x002c }, + { 20, 0x002c }, { 21, 0x002c }, { 22, 0x002c }, { 23, 0x0000 }, + { 24, 0x0032 }, { 25, 0x0000 }, { 26, 0x0000 }, { 27, 0x0000 }, + { 28, 0x0000 }, { 29, 0x0000 }, { 30, 0x0000 }, { 31, 0x0000 }, + { 32, 0x0038 }, { 33, 0x000b }, { 34, 0x0032 }, { 35, 0x0000 }, + { 36, 0x0008 }, { 37, 0x000c }, { 38, 0x0093 }, { 39, 0x00e9 }, + { 40, 0x0000 }, { 41, 0x0000 }, { 42, 0x0000 }, { 43, 0x0000 }, + { 44, 0x0003 }, { 45, 0x0010 }, { 46, 0x0000 }, { 47, 0x0000 }, + { 48, 0x0000 }, { 49, 0x0002 }, { 50, 0x0000 }, { 51, 0x0000 }, + { 52, 0x0000 }, { 53, 0x0000 }, { 54, 0x0039 }, { 55, 0x0000 }, + { 56, 0x0000 }, }; #define WM8974_POWER1_BIASEN 0x08 @@ -514,7 +515,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - snd_soc_cache_sync(codec); + regcache_sync(dev_get_regmap(codec->dev, NULL)); /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); @@ -579,11 +580,20 @@ static int wm8974_resume(struct snd_soc_codec *codec) return 0; } +static const struct regmap_config wm8974_regmap = { + .reg_bits = 7, + .val_bits = 9, + + .max_register = WM8974_MONOMIX, + .reg_defaults = wm8974_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8974_reg_defaults), +}; + static int wm8974_probe(struct snd_soc_codec *codec) { int ret = 0; - ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -613,9 +623,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { .suspend = wm8974_suspend, .resume = wm8974_resume, .set_bias_level = wm8974_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8974_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8974_reg, .controls = wm8974_snd_controls, .num_controls = ARRAY_SIZE(wm8974_snd_controls), @@ -628,8 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { static int wm8974_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct regmap *regmap; int ret; + regmap = devm_regmap_init_i2c(i2c, &wm8974_regmap); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8974, &wm8974_dai, 1); diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 18f2babe1090..271b517911a4 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -1148,7 +1148,7 @@ static struct spi_driver wm8985_spi_driver = { }; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8985_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1201,7 +1201,7 @@ static int __init wm8985_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8985_i2c_driver); if (ret) { printk(KERN_ERR "Failed to register wm8985 I2C driver: %d\n", @@ -1221,7 +1221,7 @@ module_init(wm8985_modinit); static void __exit wm8985_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8985_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 39b9acceb595..a55e1c2c382e 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -912,7 +912,7 @@ static struct spi_driver wm8988_spi_driver = { }; #endif /* CONFIG_SPI_MASTER */ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8988_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -964,7 +964,7 @@ static struct i2c_driver wm8988_i2c_driver = { static int __init wm8988_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8988_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n", @@ -984,7 +984,7 @@ module_init(wm8988_modinit); static void __exit wm8988_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8988_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 4f05fb88bddf..0ccd4d8d043b 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -30,13 +31,12 @@ /* codec private data */ struct wm8990_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; unsigned int sysclk; unsigned int pcmclk; }; -static int wm8990_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) +static bool wm8990_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM8990_RESET: @@ -46,71 +46,69 @@ static int wm8990_volatile_register(struct snd_soc_codec *codec, } } -static const u16 wm8990_reg[] = { - 0x8990, /* R0 - Reset */ - 0x0000, /* R1 - Power Management (1) */ - 0x6000, /* R2 - Power Management (2) */ - 0x0000, /* R3 - Power Management (3) */ - 0x4050, /* R4 - Audio Interface (1) */ - 0x4000, /* R5 - Audio Interface (2) */ - 0x01C8, /* R6 - Clocking (1) */ - 0x0000, /* R7 - Clocking (2) */ - 0x0040, /* R8 - Audio Interface (3) */ - 0x0040, /* R9 - Audio Interface (4) */ - 0x0004, /* R10 - DAC CTRL */ - 0x00C0, /* R11 - Left DAC Digital Volume */ - 0x00C0, /* R12 - Right DAC Digital Volume */ - 0x0000, /* R13 - Digital Side Tone */ - 0x0100, /* R14 - ADC CTRL */ - 0x00C0, /* R15 - Left ADC Digital Volume */ - 0x00C0, /* R16 - Right ADC Digital Volume */ - 0x0000, /* R17 */ - 0x0000, /* R18 - GPIO CTRL 1 */ - 0x1000, /* R19 - GPIO1 & GPIO2 */ - 0x1010, /* R20 - GPIO3 & GPIO4 */ - 0x1010, /* R21 - GPIO5 & GPIO6 */ - 0x8000, /* R22 - GPIOCTRL 2 */ - 0x0800, /* R23 - GPIO_POL */ - 0x008B, /* R24 - Left Line Input 1&2 Volume */ - 0x008B, /* R25 - Left Line Input 3&4 Volume */ - 0x008B, /* R26 - Right Line Input 1&2 Volume */ - 0x008B, /* R27 - Right Line Input 3&4 Volume */ - 0x0000, /* R28 - Left Output Volume */ - 0x0000, /* R29 - Right Output Volume */ - 0x0066, /* R30 - Line Outputs Volume */ - 0x0022, /* R31 - Out3/4 Volume */ - 0x0079, /* R32 - Left OPGA Volume */ - 0x0079, /* R33 - Right OPGA Volume */ - 0x0003, /* R34 - Speaker Volume */ - 0x0003, /* R35 - ClassD1 */ - 0x0000, /* R36 */ - 0x0100, /* R37 - ClassD3 */ - 0x0079, /* R38 - ClassD4 */ - 0x0000, /* R39 - Input Mixer1 */ - 0x0000, /* R40 - Input Mixer2 */ - 0x0000, /* R41 - Input Mixer3 */ - 0x0000, /* R42 - Input Mixer4 */ - 0x0000, /* R43 - Input Mixer5 */ - 0x0000, /* R44 - Input Mixer6 */ - 0x0000, /* R45 - Output Mixer1 */ - 0x0000, /* R46 - Output Mixer2 */ - 0x0000, /* R47 - Output Mixer3 */ - 0x0000, /* R48 - Output Mixer4 */ - 0x0000, /* R49 - Output Mixer5 */ - 0x0000, /* R50 - Output Mixer6 */ - 0x0180, /* R51 - Out3/4 Mixer */ - 0x0000, /* R52 - Line Mixer1 */ - 0x0000, /* R53 - Line Mixer2 */ - 0x0000, /* R54 - Speaker Mixer */ - 0x0000, /* R55 - Additional Control */ - 0x0000, /* R56 - AntiPOP1 */ - 0x0000, /* R57 - AntiPOP2 */ - 0x0000, /* R58 - MICBIAS */ - 0x0000, /* R59 */ - 0x0008, /* R60 - PLL1 */ - 0x0031, /* R61 - PLL2 */ - 0x0026, /* R62 - PLL3 */ - 0x0000, /* R63 - Driver internal */ +static const struct reg_default wm8990_reg_defaults[] = { + { 1, 0x0000 }, /* R1 - Power Management (1) */ + { 2, 0x6000 }, /* R2 - Power Management (2) */ + { 3, 0x0000 }, /* R3 - Power Management (3) */ + { 4, 0x4050 }, /* R4 - Audio Interface (1) */ + { 5, 0x4000 }, /* R5 - Audio Interface (2) */ + { 6, 0x01C8 }, /* R6 - Clocking (1) */ + { 7, 0x0000 }, /* R7 - Clocking (2) */ + { 8, 0x0040 }, /* R8 - Audio Interface (3) */ + { 9, 0x0040 }, /* R9 - Audio Interface (4) */ + { 10, 0x0004 }, /* R10 - DAC CTRL */ + { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */ + { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */ + { 13, 0x0000 }, /* R13 - Digital Side Tone */ + { 14, 0x0100 }, /* R14 - ADC CTRL */ + { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */ + { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */ + + { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ + { 19, 0x1000 }, /* R19 - GPIO1 & GPIO2 */ + { 20, 0x1010 }, /* R20 - GPIO3 & GPIO4 */ + { 21, 0x1010 }, /* R21 - GPIO5 & GPIO6 */ + { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */ + { 23, 0x0800 }, /* R23 - GPIO_POL */ + { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ + { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ + { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ + { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ + { 28, 0x0000 }, /* R28 - Left Output Volume */ + { 29, 0x0000 }, /* R29 - Right Output Volume */ + { 30, 0x0066 }, /* R30 - Line Outputs Volume */ + { 31, 0x0022 }, /* R31 - Out3/4 Volume */ + { 32, 0x0079 }, /* R32 - Left OPGA Volume */ + { 33, 0x0079 }, /* R33 - Right OPGA Volume */ + { 34, 0x0003 }, /* R34 - Speaker Volume */ + { 35, 0x0003 }, /* R35 - ClassD1 */ + + { 37, 0x0100 }, /* R37 - ClassD3 */ + { 38, 0x0079 }, /* R38 - ClassD4 */ + { 39, 0x0000 }, /* R39 - Input Mixer1 */ + { 40, 0x0000 }, /* R40 - Input Mixer2 */ + { 41, 0x0000 }, /* R41 - Input Mixer3 */ + { 42, 0x0000 }, /* R42 - Input Mixer4 */ + { 43, 0x0000 }, /* R43 - Input Mixer5 */ + { 44, 0x0000 }, /* R44 - Input Mixer6 */ + { 45, 0x0000 }, /* R45 - Output Mixer1 */ + { 46, 0x0000 }, /* R46 - Output Mixer2 */ + { 47, 0x0000 }, /* R47 - Output Mixer3 */ + { 48, 0x0000 }, /* R48 - Output Mixer4 */ + { 49, 0x0000 }, /* R49 - Output Mixer5 */ + { 50, 0x0000 }, /* R50 - Output Mixer6 */ + { 51, 0x0180 }, /* R51 - Out3/4 Mixer */ + { 52, 0x0000 }, /* R52 - Line Mixer1 */ + { 53, 0x0000 }, /* R53 - Line Mixer2 */ + { 54, 0x0000 }, /* R54 - Speaker Mixer */ + { 55, 0x0000 }, /* R55 - Additional Control */ + { 56, 0x0000 }, /* R56 - AntiPOP1 */ + { 57, 0x0000 }, /* R57 - AntiPOP2 */ + { 58, 0x0000 }, /* R58 - MICBIAS */ + + { 60, 0x0008 }, /* R60 - PLL1 */ + { 61, 0x0031 }, /* R61 - PLL2 */ + { 62, 0x0026 }, /* R62 - PLL3 */ }; #define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0) @@ -376,32 +374,6 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME, * _DAPM_ Controls */ -static int inmixer_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - u16 reg, fakepower; - - reg = snd_soc_read(w->codec, WM8990_POWER_MANAGEMENT_2); - fakepower = snd_soc_read(w->codec, WM8990_INTDRIVBITS); - - if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) | - (1 << WM8990_AINLMUX_PWR_BIT))) { - reg |= WM8990_AINL_ENA; - } else { - reg &= ~WM8990_AINL_ENA; - } - - if (fakepower & ((1 << WM8990_INMIXR_PWR_BIT) | - (1 << WM8990_AINRMUX_PWR_BIT))) { - reg |= WM8990_AINR_ENA; - } else { - reg &= ~WM8990_AINR_ENA; - } - snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); - - return 0; -} - static int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -656,6 +628,11 @@ SND_SOC_DAPM_INPUT("RIN1"), SND_SOC_DAPM_INPUT("RIN2"), SND_SOC_DAPM_INPUT("Internal ADC Source"), +SND_SOC_DAPM_SUPPLY("INL", WM8990_POWER_MANAGEMENT_2, WM8990_AINL_ENA_BIT, 0, + NULL, 0), +SND_SOC_DAPM_SUPPLY("INR", WM8990_POWER_MANAGEMENT_2, WM8990_AINR_ENA_BIT, 0, + NULL, 0), + /* DACs */ SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8990_POWER_MANAGEMENT_2, WM8990_ADCL_ENA_BIT, 0), @@ -677,26 +654,20 @@ SND_SOC_DAPM_MIXER("RIN34 PGA", WM8990_POWER_MANAGEMENT_2, WM8990_RIN34_ENA_BIT, ARRAY_SIZE(wm8990_dapm_rin34_pga_controls)), /* INMIXL */ -SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0, +SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0, &wm8990_dapm_inmixl_controls[0], - ARRAY_SIZE(wm8990_dapm_inmixl_controls), - inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + ARRAY_SIZE(wm8990_dapm_inmixl_controls)), /* AINLMUX */ -SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0, - &wm8990_dapm_ainlmux_controls, inmixer_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_MUX("AINLMUX", SND_SOC_NOPM, 0, 0, &wm8990_dapm_ainlmux_controls), /* INMIXR */ -SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0, +SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0, &wm8990_dapm_inmixr_controls[0], - ARRAY_SIZE(wm8990_dapm_inmixr_controls), - inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + ARRAY_SIZE(wm8990_dapm_inmixr_controls)), /* AINRMUX */ -SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0, - &wm8990_dapm_ainrmux_controls, inmixer_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_MUX("AINRMUX", SND_SOC_NOPM, 0, 0, &wm8990_dapm_ainrmux_controls), /* Output Side */ /* DACs */ @@ -787,7 +758,7 @@ SND_SOC_DAPM_OUTPUT("RON"), SND_SOC_DAPM_OUTPUT("Internal DAC Sink"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8990_dapm_routes[] = { /* Make DACs turn on when playing even if not mixed into any outputs */ {"Internal DAC Sink", NULL, "Left DAC"}, {"Internal DAC Sink", NULL, "Right DAC"}, @@ -796,6 +767,11 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Left ADC", NULL, "Internal ADC Source"}, {"Right ADC", NULL, "Internal ADC Source"}, + {"AINLMUX", NULL, "INL"}, + {"INMIXL", NULL, "INL"}, + {"AINRMUX", NULL, "INR"}, + {"INMIXR", NULL, "INR"}, + /* Input Side */ /* LIN12 PGA */ {"LIN12 PGA", "LIN1 Switch", "LIN1"}, @@ -912,18 +888,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"RON", NULL, "RONMIX"}, }; -static int wm8990_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets, - ARRAY_SIZE(wm8990_dapm_widgets)); - /* set up the WM8990 audio map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - /* PLL divisors */ struct _pll_div { u32 div2; @@ -1148,6 +1112,7 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute) static int wm8990_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct wm8990_priv *wm8990 = snd_soc_codec_get_drvdata(codec); int ret; switch (level) { @@ -1162,7 +1127,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - ret = snd_soc_cache_sync(codec); + ret = regcache_sync(wm8990->regmap); if (ret < 0) { dev_err(codec->dev, "Failed to sync cache: %d\n", ret); return ret; @@ -1260,7 +1225,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ snd_soc_write(codec, WM8990_ANTIPOP2, 0x0); - codec->cache_sync = 1; + regcache_mark_dirty(wm8990->regmap); break; } @@ -1329,7 +1294,7 @@ static int wm8990_probe(struct snd_soc_codec *codec) { int ret; - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret < 0) { printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret); return ret; @@ -1352,10 +1317,6 @@ static int wm8990_probe(struct snd_soc_codec *codec) snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - snd_soc_add_codec_controls(codec, wm8990_snd_controls, - ARRAY_SIZE(wm8990_snd_controls)); - wm8990_add_widgets(codec); - return 0; } @@ -1372,13 +1333,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { .suspend = wm8990_suspend, .resume = wm8990_resume, .set_bias_level = wm8990_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8990_reg), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8990_reg, - .volatile_register = wm8990_volatile_register, + .controls = wm8990_snd_controls, + .num_controls = ARRAY_SIZE(wm8990_snd_controls), + .dapm_widgets = wm8990_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8990_dapm_widgets), + .dapm_routes = wm8990_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8990_dapm_routes), +}; + +static const struct regmap_config wm8990_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM8990_PLL3, + .volatile_reg = wm8990_volatile_register, + .reg_defaults = wm8990_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8990_reg_defaults), + .cache_type = REGCACHE_RBTREE, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static int wm8990_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1420,29 +1393,8 @@ static struct i2c_driver wm8990_i2c_driver = { .remove = wm8990_i2c_remove, .id_table = wm8990_i2c_id, }; -#endif -static int __init wm8990_modinit(void) -{ - int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8990_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register wm8990 I2C driver: %d\n", - ret); - } -#endif - return ret; -} -module_init(wm8990_modinit); - -static void __exit wm8990_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8990_i2c_driver); -#endif -} -module_exit(wm8990_exit); +module_i2c_driver(wm8990_i2c_driver); MODULE_DESCRIPTION("ASoC WM8990 driver"); MODULE_AUTHOR("Liam Girdwood"); diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h index 77c98a4bfe9c..0e9c78040c4c 100644 --- a/sound/soc/codecs/wm8990.h +++ b/sound/soc/codecs/wm8990.h @@ -78,7 +78,6 @@ #define WM8990_PLL1 0x3C #define WM8990_PLL2 0x3D #define WM8990_PLL3 0x3E -#define WM8990_INTDRIVBITS 0x3F #define WM8990_EXT_ACCESS_ENA 0x75 #define WM8990_EXT_CTL1 0x7a @@ -818,14 +817,6 @@ */ #define WM8990_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */ -/* - * R63 (0x3F) - Internal Driver Bits - */ -#define WM8990_INMIXL_PWR_BIT 0 -#define WM8990_AINLMUX_PWR_BIT 1 -#define WM8990_INMIXR_PWR_BIT 2 -#define WM8990_AINRMUX_PWR_BIT 3 - #define WM8990_MCLK_DIV 0 #define WM8990_DACCLK_DIV 1 #define WM8990_ADCCLK_DIV 2 diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 3a39df7a3829..dba0306c42a5 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -31,77 +32,84 @@ #include "wm8991.h" struct wm8991_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; unsigned int pcmclk; }; -static const u16 wm8991_reg_defs[] = { - 0x8991, /* R0 - Reset */ - 0x0000, /* R1 - Power Management (1) */ - 0x6000, /* R2 - Power Management (2) */ - 0x0000, /* R3 - Power Management (3) */ - 0x4050, /* R4 - Audio Interface (1) */ - 0x4000, /* R5 - Audio Interface (2) */ - 0x01C8, /* R6 - Clocking (1) */ - 0x0000, /* R7 - Clocking (2) */ - 0x0040, /* R8 - Audio Interface (3) */ - 0x0040, /* R9 - Audio Interface (4) */ - 0x0004, /* R10 - DAC CTRL */ - 0x00C0, /* R11 - Left DAC Digital Volume */ - 0x00C0, /* R12 - Right DAC Digital Volume */ - 0x0000, /* R13 - Digital Side Tone */ - 0x0100, /* R14 - ADC CTRL */ - 0x00C0, /* R15 - Left ADC Digital Volume */ - 0x00C0, /* R16 - Right ADC Digital Volume */ - 0x0000, /* R17 */ - 0x0000, /* R18 - GPIO CTRL 1 */ - 0x1000, /* R19 - GPIO1 & GPIO2 */ - 0x1010, /* R20 - GPIO3 & GPIO4 */ - 0x1010, /* R21 - GPIO5 & GPIO6 */ - 0x8000, /* R22 - GPIOCTRL 2 */ - 0x0800, /* R23 - GPIO_POL */ - 0x008B, /* R24 - Left Line Input 1&2 Volume */ - 0x008B, /* R25 - Left Line Input 3&4 Volume */ - 0x008B, /* R26 - Right Line Input 1&2 Volume */ - 0x008B, /* R27 - Right Line Input 3&4 Volume */ - 0x0000, /* R28 - Left Output Volume */ - 0x0000, /* R29 - Right Output Volume */ - 0x0066, /* R30 - Line Outputs Volume */ - 0x0022, /* R31 - Out3/4 Volume */ - 0x0079, /* R32 - Left OPGA Volume */ - 0x0079, /* R33 - Right OPGA Volume */ - 0x0003, /* R34 - Speaker Volume */ - 0x0003, /* R35 - ClassD1 */ - 0x0000, /* R36 */ - 0x0100, /* R37 - ClassD3 */ - 0x0000, /* R38 */ - 0x0000, /* R39 - Input Mixer1 */ - 0x0000, /* R40 - Input Mixer2 */ - 0x0000, /* R41 - Input Mixer3 */ - 0x0000, /* R42 - Input Mixer4 */ - 0x0000, /* R43 - Input Mixer5 */ - 0x0000, /* R44 - Input Mixer6 */ - 0x0000, /* R45 - Output Mixer1 */ - 0x0000, /* R46 - Output Mixer2 */ - 0x0000, /* R47 - Output Mixer3 */ - 0x0000, /* R48 - Output Mixer4 */ - 0x0000, /* R49 - Output Mixer5 */ - 0x0000, /* R50 - Output Mixer6 */ - 0x0180, /* R51 - Out3/4 Mixer */ - 0x0000, /* R52 - Line Mixer1 */ - 0x0000, /* R53 - Line Mixer2 */ - 0x0000, /* R54 - Speaker Mixer */ - 0x0000, /* R55 - Additional Control */ - 0x0000, /* R56 - AntiPOP1 */ - 0x0000, /* R57 - AntiPOP2 */ - 0x0000, /* R58 - MICBIAS */ - 0x0000, /* R59 */ - 0x0008, /* R60 - PLL1 */ - 0x0031, /* R61 - PLL2 */ - 0x0026, /* R62 - PLL3 */ +static const struct reg_default wm8991_reg_defaults[] = { + { 1, 0x0000 }, /* R1 - Power Management (1) */ + { 2, 0x6000 }, /* R2 - Power Management (2) */ + { 3, 0x0000 }, /* R3 - Power Management (3) */ + { 4, 0x4050 }, /* R4 - Audio Interface (1) */ + { 5, 0x4000 }, /* R5 - Audio Interface (2) */ + { 6, 0x01C8 }, /* R6 - Clocking (1) */ + { 7, 0x0000 }, /* R7 - Clocking (2) */ + { 8, 0x0040 }, /* R8 - Audio Interface (3) */ + { 9, 0x0040 }, /* R9 - Audio Interface (4) */ + { 10, 0x0004 }, /* R10 - DAC CTRL */ + { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */ + { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */ + { 13, 0x0000 }, /* R13 - Digital Side Tone */ + { 14, 0x0100 }, /* R14 - ADC CTRL */ + { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */ + { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */ + + { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ + { 19, 0x1000 }, /* R19 - GPIO1 & GPIO2 */ + { 20, 0x1010 }, /* R20 - GPIO3 & GPIO4 */ + { 21, 0x1010 }, /* R21 - GPIO5 & GPIO6 */ + { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */ + { 23, 0x0800 }, /* R23 - GPIO_POL */ + { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ + { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ + { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ + { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ + { 28, 0x0000 }, /* R28 - Left Output Volume */ + { 29, 0x0000 }, /* R29 - Right Output Volume */ + { 30, 0x0066 }, /* R30 - Line Outputs Volume */ + { 31, 0x0022 }, /* R31 - Out3/4 Volume */ + { 32, 0x0079 }, /* R32 - Left OPGA Volume */ + { 33, 0x0079 }, /* R33 - Right OPGA Volume */ + { 34, 0x0003 }, /* R34 - Speaker Volume */ + { 35, 0x0003 }, /* R35 - ClassD1 */ + + { 37, 0x0100 }, /* R37 - ClassD3 */ + + { 39, 0x0000 }, /* R39 - Input Mixer1 */ + { 40, 0x0000 }, /* R40 - Input Mixer2 */ + { 41, 0x0000 }, /* R41 - Input Mixer3 */ + { 42, 0x0000 }, /* R42 - Input Mixer4 */ + { 43, 0x0000 }, /* R43 - Input Mixer5 */ + { 44, 0x0000 }, /* R44 - Input Mixer6 */ + { 45, 0x0000 }, /* R45 - Output Mixer1 */ + { 46, 0x0000 }, /* R46 - Output Mixer2 */ + { 47, 0x0000 }, /* R47 - Output Mixer3 */ + { 48, 0x0000 }, /* R48 - Output Mixer4 */ + { 49, 0x0000 }, /* R49 - Output Mixer5 */ + { 50, 0x0000 }, /* R50 - Output Mixer6 */ + { 51, 0x0180 }, /* R51 - Out3/4 Mixer */ + { 52, 0x0000 }, /* R52 - Line Mixer1 */ + { 53, 0x0000 }, /* R53 - Line Mixer2 */ + { 54, 0x0000 }, /* R54 - Speaker Mixer */ + { 55, 0x0000 }, /* R55 - Additional Control */ + { 56, 0x0000 }, /* R56 - AntiPOP1 */ + { 57, 0x0000 }, /* R57 - AntiPOP2 */ + { 58, 0x0000 }, /* R58 - MICBIAS */ + + { 60, 0x0008 }, /* R60 - PLL1 */ + { 61, 0x0031 }, /* R61 - PLL2 */ + { 62, 0x0026 }, /* R62 - PLL3 */ }; -#define wm8991_reset(c) snd_soc_write(c, WM8991_RESET, 0) +static bool wm8991_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8991_RESET: + return true; + default: + return false; + } +} static const unsigned int rec_mix_tlv[] = { TLV_DB_RANGE_HEAD(1), @@ -374,30 +382,6 @@ static const struct snd_kcontrol_new wm8991_snd_controls[] = { /* * _DAPM_ Controls */ -static int inmixer_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - u16 reg, fakepower; - - reg = snd_soc_read(w->codec, WM8991_POWER_MANAGEMENT_2); - fakepower = snd_soc_read(w->codec, WM8991_INTDRIVBITS); - - if (fakepower & ((1 << WM8991_INMIXL_PWR_BIT) | - (1 << WM8991_AINLMUX_PWR_BIT))) - reg |= WM8991_AINL_ENA; - else - reg &= ~WM8991_AINL_ENA; - - if (fakepower & ((1 << WM8991_INMIXR_PWR_BIT) | - (1 << WM8991_AINRMUX_PWR_BIT))) - reg |= WM8991_AINR_ENA; - else - reg &= ~WM8991_AINR_ENA; - - snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg); - return 0; -} - static int outmixer_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -655,6 +639,11 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = { SND_SOC_DAPM_INPUT("RIN2"), SND_SOC_DAPM_INPUT("Internal ADC Source"), + SND_SOC_DAPM_SUPPLY("INL", WM8991_POWER_MANAGEMENT_2, + WM8991_AINL_ENA_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("INR", WM8991_POWER_MANAGEMENT_2, + WM8991_AINR_ENA_BIT, 0, NULL, 0), + /* DACs */ SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8991_POWER_MANAGEMENT_2, WM8991_ADCL_ENA_BIT, 0), @@ -676,26 +665,22 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = { ARRAY_SIZE(wm8991_dapm_rin34_pga_controls)), /* INMIXL */ - SND_SOC_DAPM_MIXER_E("INMIXL", WM8991_INTDRIVBITS, WM8991_INMIXL_PWR_BIT, 0, + SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0, &wm8991_dapm_inmixl_controls[0], - ARRAY_SIZE(wm8991_dapm_inmixl_controls), - inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + ARRAY_SIZE(wm8991_dapm_inmixl_controls)), /* AINLMUX */ - SND_SOC_DAPM_MUX_E("AINLMUX", WM8991_INTDRIVBITS, WM8991_AINLMUX_PWR_BIT, 0, - &wm8991_dapm_ainlmux_controls, inmixer_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("AINLMUX", SND_SOC_NOPM, 0, 0, + &wm8991_dapm_ainlmux_controls), /* INMIXR */ - SND_SOC_DAPM_MIXER_E("INMIXR", WM8991_INTDRIVBITS, WM8991_INMIXR_PWR_BIT, 0, + SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0, &wm8991_dapm_inmixr_controls[0], - ARRAY_SIZE(wm8991_dapm_inmixr_controls), - inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + ARRAY_SIZE(wm8991_dapm_inmixr_controls)), /* AINRMUX */ - SND_SOC_DAPM_MUX_E("AINRMUX", WM8991_INTDRIVBITS, WM8991_AINRMUX_PWR_BIT, 0, - &wm8991_dapm_ainrmux_controls, inmixer_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("AINRMUX", SND_SOC_NOPM, 0, 0, + &wm8991_dapm_ainrmux_controls), /* Output Side */ /* DACs */ @@ -787,7 +772,7 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("Internal DAC Sink"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8991_dapm_routes[] = { /* Make DACs turn on when playing even if not mixed into any outputs */ {"Internal DAC Sink", NULL, "Left DAC"}, {"Internal DAC Sink", NULL, "Right DAC"}, @@ -797,6 +782,10 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Right ADC", NULL, "Internal ADC Source"}, /* Input Side */ + {"INMIXL", NULL, "INL"}, + {"AINLMUX", NULL, "INL"}, + {"INMIXR", NULL, "INR"}, + {"AINRMUX", NULL, "INR"}, /* LIN12 PGA */ {"LIN12 PGA", "LIN1 Switch", "LIN1"}, {"LIN12 PGA", "LIN2 Switch", "LIN2"}, @@ -1129,6 +1118,7 @@ static int wm8991_mute(struct snd_soc_dai *dai, int mute) static int wm8991_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct wm8991_priv *wm8991 = snd_soc_codec_get_drvdata(codec); u16 val; switch (level) { @@ -1144,7 +1134,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - snd_soc_cache_sync(codec); + regcache_sync(wm8991->regmap); /* Enable all output discharge bits */ snd_soc_write(codec, WM8991_ANTIPOP1, WM8991_DIS_LLINE | WM8991_DIS_RLINE | WM8991_DIS_OUT3 | @@ -1232,7 +1222,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec, /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ snd_soc_write(codec, WM8991_ANTIPOP2, 0x0); - codec->cache_sync = 1; + regcache_mark_dirty(wm8991->regmap); break; } @@ -1266,44 +1256,14 @@ static int wm8991_probe(struct snd_soc_codec *codec) wm8991 = snd_soc_codec_get_drvdata(codec); - ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8991->control_type); + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); return ret; } - ret = wm8991_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4, - WM8991_ALRCGPIO1, WM8991_ALRCGPIO1); - - snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2, - WM8991_GPIO1_SEL_MASK, 1); - - snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1, - WM8991_VREF_ENA | WM8991_VMID_MODE_MASK, - WM8991_VREF_ENA | WM8991_VMID_MODE_MASK); - - snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2, - WM8991_OPCLK_ENA, WM8991_OPCLK_ENA); - - snd_soc_write(codec, WM8991_DAC_CTRL, 0); - snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); - snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); - - snd_soc_add_codec_controls(codec, wm8991_snd_controls, - ARRAY_SIZE(wm8991_snd_controls)); - - snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets, - ARRAY_SIZE(wm8991_dapm_widgets)); - snd_soc_dapm_add_routes(&codec->dapm, audio_map, - ARRAY_SIZE(audio_map)); return 0; } @@ -1352,24 +1312,77 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8991 = { .suspend = wm8991_suspend, .resume = wm8991_resume, .set_bias_level = wm8991_set_bias_level, - .reg_cache_size = WM8991_MAX_REGISTER + 1, - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8991_reg_defs + .controls = wm8991_snd_controls, + .num_controls = ARRAY_SIZE(wm8991_snd_controls), + .dapm_widgets = wm8991_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8991_dapm_widgets), + .dapm_routes = wm8991_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8991_dapm_routes), +}; + +static const struct regmap_config wm8991_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM8991_PLL3, + .volatile_reg = wm8991_volatile, + .reg_defaults = wm8991_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8991_reg_defaults), + .cache_type = REGCACHE_RBTREE, }; static int wm8991_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8991_priv *wm8991; + unsigned int val; int ret; wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL); if (!wm8991) return -ENOMEM; - wm8991->control_type = SND_SOC_I2C; + wm8991->regmap = devm_regmap_init_i2c(i2c, &wm8991_regmap); + if (IS_ERR(wm8991->regmap)) + return PTR_ERR(wm8991->regmap); + i2c_set_clientdata(i2c, wm8991); + ret = regmap_read(wm8991->regmap, WM8991_RESET, &val); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read device ID: %d\n", ret); + return ret; + } + if (val != 0x8991) { + dev_err(&i2c->dev, "Device with ID %x is not a WM8991\n", val); + return -EINVAL; + } + + ret = regmap_write(wm8991->regmap, WM8991_RESET, 0); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); + return ret; + } + + regmap_update_bits(wm8991->regmap, WM8991_AUDIO_INTERFACE_4, + WM8991_ALRCGPIO1, WM8991_ALRCGPIO1); + + regmap_update_bits(wm8991->regmap, WM8991_GPIO1_GPIO2, + WM8991_GPIO1_SEL_MASK, 1); + + regmap_update_bits(wm8991->regmap, WM8991_POWER_MANAGEMENT_1, + WM8991_VREF_ENA | WM8991_VMID_MODE_MASK, + WM8991_VREF_ENA | WM8991_VMID_MODE_MASK); + + regmap_update_bits(wm8991->regmap, WM8991_POWER_MANAGEMENT_2, + WM8991_OPCLK_ENA, WM8991_OPCLK_ENA); + + regmap_write(wm8991->regmap, WM8991_DAC_CTRL, 0); + regmap_write(wm8991->regmap, WM8991_LEFT_OUTPUT_VOLUME, + 0x50 | (1<<8)); + regmap_write(wm8991->regmap, WM8991_RIGHT_OUTPUT_VOLUME, + 0x50 | (1<<8)); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8991, &wm8991_dai, 1); diff --git a/sound/soc/codecs/wm8991.h b/sound/soc/codecs/wm8991.h index 07707d8d7e20..08ed383303c0 100644 --- a/sound/soc/codecs/wm8991.h +++ b/sound/soc/codecs/wm8991.h @@ -76,7 +76,6 @@ #define WM8991_PLL1 0x3C #define WM8991_PLL2 0x3D #define WM8991_PLL3 0x3E -#define WM8991_INTDRIVBITS 0x3F #define WM8991_REGISTER_COUNT 60 #define WM8991_MAX_REGISTER 0x3F @@ -807,14 +806,6 @@ */ #define WM8991_PLLK2_MASK 0x00FF /* PLLK2 - [7:0] */ -/* - * R63 (0x3F) - Internal Driver Bits - */ -#define WM8991_INMIXL_PWR_BIT 0 -#define WM8991_AINLMUX_PWR_BIT 1 -#define WM8991_INMIXR_PWR_BIT 2 -#define WM8991_AINRMUX_PWR_BIT 3 - #define WM8991_MCLK_DIV 0 #define WM8991_DACCLK_DIV 1 #define WM8991_ADCCLK_DIV 2 diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 86426a117b07..b9be9cbc4603 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4077,12 +4077,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, wm8994_temp_shut, "Thermal shutdown", codec); - ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, - wm_hubs_dcs_done, "DC servo done", - &wm8994->hubs); - if (ret == 0) - wm8994->hubs.dcs_done_irq = true; - switch (control->type) { case WM8994: if (wm8994->micdet_irq) { @@ -4313,6 +4307,11 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) } wm_hubs_add_analogue_routes(codec, 0, 0); + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, + wm_hubs_dcs_done, "DC servo done", + &wm8994->hubs); + if (ret == 0) + wm8994->hubs.dcs_done_irq = true; snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); switch (control->type) { diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index da2899e6c401..4300caff1783 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -2293,7 +2293,7 @@ static struct spi_driver wm8995_spi_driver = { }; #endif -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm8995_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2350,7 +2350,7 @@ static int __init wm8995_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8995_i2c_driver); if (ret) { printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n", @@ -2371,7 +2371,7 @@ module_init(wm8995_modinit); static void __exit wm8995_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8995_i2c_driver); #endif #if defined(CONFIG_SPI_MASTER) diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 1392bb3c9254..555115ee2159 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -103,8 +103,8 @@ static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: if (patch) for (i = 0; i < patch_size; i++) - regmap_write(regmap, patch[i].reg, - patch[i].def); + regmap_write_async(regmap, patch[i].reg, + patch[i].def); break; default: break; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 630b3d776ec2..0982c1d38ec4 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -1326,7 +1326,7 @@ static const struct regmap_config wm9081_regmap = { .cache_type = REGCACHE_RBTREE, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +#if IS_ENABLED(CONFIG_I2C) static int wm9081_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 4fbcab63e61f..444626fcab40 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1286,6 +1286,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) reg = wm_adsp_region_to_reg(mem, reg); reg += offset; + break; } } @@ -1468,8 +1469,8 @@ static int wm_adsp2_ena(struct wm_adsp *dsp) unsigned int val; int ret, count; - ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_SYS_ENA, ADSP2_SYS_ENA); + ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA, ADSP2_SYS_ENA); if (ret != 0) return ret; @@ -1492,11 +1493,130 @@ static int wm_adsp2_ena(struct wm_adsp *dsp) } adsp_dbg(dsp, "RAM ready after %d polls\n", count); - adsp_info(dsp, "RAM ready after %d polls\n", count); return 0; } +static void wm_adsp2_boot_work(struct work_struct *work) +{ + struct wm_adsp *dsp = container_of(work, + struct wm_adsp, + boot_work); + int ret; + unsigned int val; + + /* + * For simplicity set the DSP clock rate to be the + * SYSCLK rate rather than making it configurable. + */ + ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); + if (ret != 0) { + adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); + return; + } + val = (val & ARIZONA_SYSCLK_FREQ_MASK) + >> ARIZONA_SYSCLK_FREQ_SHIFT; + + ret = regmap_update_bits_async(dsp->regmap, + dsp->base + ADSP2_CLOCKING, + ADSP2_CLK_SEL_MASK, val); + if (ret != 0) { + adsp_err(dsp, "Failed to set clock rate: %d\n", ret); + return; + } + + if (dsp->dvfs) { + ret = regmap_read(dsp->regmap, + dsp->base + ADSP2_CLOCKING, &val); + if (ret != 0) { + dev_err(dsp->dev, "Failed to read clocking: %d\n", ret); + return; + } + + if ((val & ADSP2_CLK_SEL_MASK) >= 3) { + ret = regulator_enable(dsp->dvfs); + if (ret != 0) { + dev_err(dsp->dev, + "Failed to enable supply: %d\n", + ret); + return; + } + + ret = regulator_set_voltage(dsp->dvfs, + 1800000, + 1800000); + if (ret != 0) { + dev_err(dsp->dev, + "Failed to raise supply: %d\n", + ret); + return; + } + } + } + + ret = wm_adsp2_ena(dsp); + if (ret != 0) + return; + + ret = wm_adsp_load(dsp); + if (ret != 0) + goto err; + + ret = wm_adsp_setup_algs(dsp); + if (ret != 0) + goto err; + + ret = wm_adsp_load_coeff(dsp); + if (ret != 0) + goto err; + + /* Initialize caches for enabled and unset controls */ + ret = wm_coeff_init_control_caches(dsp); + if (ret != 0) + goto err; + + /* Sync set controls */ + ret = wm_coeff_sync_controls(dsp); + if (ret != 0) + goto err; + + ret = regmap_update_bits_async(dsp->regmap, + dsp->base + ADSP2_CONTROL, + ADSP2_CORE_ENA, + ADSP2_CORE_ENA); + if (ret != 0) + goto err; + + dsp->running = true; + + return; + +err: + regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, + ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); +} + +int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); + struct wm_adsp *dsp = &dsps[w->shift]; + + dsp->card = codec->card; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + queue_work(system_unbound_wq, &dsp->boot_work); + break; + default: + break; + }; + + return 0; +} +EXPORT_SYMBOL_GPL(wm_adsp2_early_event); + int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1505,99 +1625,21 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct wm_adsp *dsp = &dsps[w->shift]; struct wm_adsp_alg_region *alg_region; struct wm_coeff_ctl *ctl; - unsigned int val; int ret; - dsp->card = codec->card; - switch (event) { case SND_SOC_DAPM_POST_PMU: - /* - * For simplicity set the DSP clock rate to be the - * SYSCLK rate rather than making it configurable. - */ - ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); - if (ret != 0) { - adsp_err(dsp, "Failed to read SYSCLK state: %d\n", - ret); - return ret; - } - val = (val & ARIZONA_SYSCLK_FREQ_MASK) - >> ARIZONA_SYSCLK_FREQ_SHIFT; + flush_work(&dsp->boot_work); - ret = regmap_update_bits(dsp->regmap, - dsp->base + ADSP2_CLOCKING, - ADSP2_CLK_SEL_MASK, val); - if (ret != 0) { - adsp_err(dsp, "Failed to set clock rate: %d\n", - ret); - return ret; - } - - if (dsp->dvfs) { - ret = regmap_read(dsp->regmap, - dsp->base + ADSP2_CLOCKING, &val); - if (ret != 0) { - dev_err(dsp->dev, - "Failed to read clocking: %d\n", ret); - return ret; - } - - if ((val & ADSP2_CLK_SEL_MASK) >= 3) { - ret = regulator_enable(dsp->dvfs); - if (ret != 0) { - dev_err(dsp->dev, - "Failed to enable supply: %d\n", - ret); - return ret; - } - - ret = regulator_set_voltage(dsp->dvfs, - 1800000, - 1800000); - if (ret != 0) { - dev_err(dsp->dev, - "Failed to raise supply: %d\n", - ret); - return ret; - } - } - } - - ret = wm_adsp2_ena(dsp); - if (ret != 0) - return ret; - - ret = wm_adsp_load(dsp); - if (ret != 0) - goto err; - - ret = wm_adsp_setup_algs(dsp); - if (ret != 0) - goto err; - - ret = wm_adsp_load_coeff(dsp); - if (ret != 0) - goto err; - - /* Initialize caches for enabled and unset controls */ - ret = wm_coeff_init_control_caches(dsp); - if (ret != 0) - goto err; - - /* Sync set controls */ - ret = wm_coeff_sync_controls(dsp); - if (ret != 0) - goto err; + if (!dsp->running) + return -EIO; ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, - ADSP2_CORE_ENA | ADSP2_START, - ADSP2_CORE_ENA | ADSP2_START); + ADSP2_START, + ADSP2_START); if (ret != 0) goto err; - - dsp->running = true; break; case SND_SOC_DAPM_PRE_PMD: @@ -1668,6 +1710,7 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) INIT_LIST_HEAD(&adsp->alg_regions); INIT_LIST_HEAD(&adsp->ctl_list); + INIT_WORK(&adsp->boot_work, wm_adsp2_boot_work); if (dvfs) { adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index d018dea6254d..a4f6b64deb61 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -59,6 +59,8 @@ struct wm_adsp { struct regulator *dvfs; struct list_head ctl_list; + + struct work_struct boot_work; }; #define WM_ADSP1(wname, num) \ @@ -66,8 +68,12 @@ struct wm_adsp { wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) #define WM_ADSP2(wname, num) \ - SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ - wm_adsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) +{ .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ + .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \ + .event_flags = SND_SOC_DAPM_PRE_PMU }, \ +{ .id = snd_soc_dapm_out_drv, .name = wname, \ + .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; @@ -76,6 +82,8 @@ int wm_adsp1_init(struct wm_adsp *adsp); int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); int wm_adsp1_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); +int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); int wm_adsp2_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 95970f5db3ec..a8ec1fc3e4d0 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -1,11 +1,6 @@ config SND_DAVINCI_SOC - tristate "SoC Audio for the TI DAVINCI or AM33XX chip" - depends on ARCH_DAVINCI || SOC_AM33XX - help - Platform driver for daVinci or AM33xx - Say Y or M if you want to add support for codecs attached to - the DAVINCI AC97, I2S, or McASP interface. You will also need - to select the audio interfaces to support below. + tristate "SoC Audio for TI DAVINCI or AM33XX/AM43XX chips" + depends on ARCH_DAVINCI || SOC_AM33XX || SOC_AM43XX config SND_DAVINCI_SOC_I2S tristate @@ -16,11 +11,15 @@ config SND_DAVINCI_SOC_MCASP config SND_DAVINCI_SOC_VCIF tristate +config SND_DAVINCI_SOC_GENERIC_EVM + tristate + select SND_SOC_TLV320AIC3X + select SND_DAVINCI_SOC_MCASP + config SND_AM33XX_SOC_EVM tristate "SoC Audio for the AM33XX chip based boards" depends on SND_DAVINCI_SOC && SOC_AM33XX - select SND_SOC_TLV320AIC3X - select SND_DAVINCI_SOC_MCASP + select SND_DAVINCI_SOC_GENERIC_EVM help Say Y or M if you want to add support for SoC audio on AM33XX boards using McASP and TLV320AIC3X codec. For example AM335X-EVM, @@ -31,8 +30,7 @@ config SND_DAVINCI_SOC_EVM tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" depends on SND_DAVINCI_SOC depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM - select SND_DAVINCI_SOC_I2S - select SND_SOC_TLV320AIC3X + select SND_DAVINCI_SOC_GENERIC_EVM help Say Y if you want to add support for SoC audio on TI DaVinci DM6446, DM355 or DM365 EVM platforms. @@ -59,8 +57,7 @@ endchoice config SND_DM6467_SOC_EVM tristate "SoC Audio support for DaVinci DM6467 EVM" depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM - select SND_DAVINCI_SOC_MCASP - select SND_SOC_TLV320AIC3X + select SND_DAVINCI_SOC_GENERIC_EVM select SND_SOC_SPDIF help @@ -69,8 +66,7 @@ config SND_DM6467_SOC_EVM config SND_DA830_SOC_EVM tristate "SoC Audio support for DA830/OMAP-L137 EVM" depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM - select SND_DAVINCI_SOC_MCASP - select SND_SOC_TLV320AIC3X + select SND_DAVINCI_SOC_GENERIC_EVM help Say Y if you want to add support for SoC audio on TI @@ -79,8 +75,7 @@ config SND_DA830_SOC_EVM config SND_DA850_SOC_EVM tristate "SoC Audio support for DA850/OMAP-L138 EVM" depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM - select SND_DAVINCI_SOC_MCASP - select SND_SOC_TLV320AIC3X + select SND_DAVINCI_SOC_GENERIC_EVM help Say Y if you want to add support for SoC audio on TI DA850/OMAP-L138 EVM diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile index bc81e79fc301..744d4d9a0184 100644 --- a/sound/soc/davinci/Makefile +++ b/sound/soc/davinci/Makefile @@ -9,11 +9,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o -# DAVINCI Machine Support +# Generic DAVINCI/AM33xx Machine Support snd-soc-evm-objs := davinci-evm.o -obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o -obj-$(CONFIG_SND_AM33XX_SOC_EVM) += snd-soc-evm.o -obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o -obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o -obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o +obj-$(CONFIG_SND_DAVINCI_SOC_GENERIC_EVM) += snd-soc-evm.o diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 623eb5e7c089..70ff3772079f 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -28,14 +28,11 @@ #include "davinci-pcm.h" #include "davinci-i2s.h" -#include "davinci-mcasp.h" struct snd_soc_card_drvdata_davinci { unsigned sysclk; }; -#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ - SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) static int evm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -48,16 +45,6 @@ static int evm_hw_params(struct snd_pcm_substream *substream, unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *) snd_soc_card_get_drvdata(soc_card))->sysclk; - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT); - if (ret < 0) - return ret; - /* set the codec system clock */ ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT); if (ret < 0) @@ -71,24 +58,10 @@ static int evm_hw_params(struct snd_pcm_substream *substream, return 0; } -static int evm_spdif_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - /* set cpu DAI configuration */ - return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT); -} - static struct snd_soc_ops evm_ops = { .hw_params = evm_hw_params, }; -static struct snd_soc_ops evm_spdif_ops = { - .hw_params = evm_spdif_hw_params, -}; - /* davinci-evm machine dapm widgets */ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), @@ -165,6 +138,8 @@ static struct snd_soc_dai_link dm6446_evm_dai = { .platform_name = "davinci-mcbsp", .init = evm_aic3x_init, .ops = &evm_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }; static struct snd_soc_dai_link dm355_evm_dai = { @@ -176,6 +151,8 @@ static struct snd_soc_dai_link dm355_evm_dai = { .platform_name = "davinci-mcbsp.1", .init = evm_aic3x_init, .ops = &evm_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }; static struct snd_soc_dai_link dm365_evm_dai = { @@ -184,10 +161,12 @@ static struct snd_soc_dai_link dm365_evm_dai = { .stream_name = "AIC3X", .cpu_dai_name = "davinci-mcbsp", .codec_dai_name = "tlv320aic3x-hifi", - .init = evm_aic3x_init, .codec_name = "tlv320aic3x-codec.1-0018", - .ops = &evm_ops, .platform_name = "davinci-mcbsp", + .init = evm_aic3x_init, + .ops = &evm_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, #elif defined(CONFIG_SND_DM365_VOICE_CODEC) .name = "Voice Codec - CQ93VC", .stream_name = "CQ93", @@ -208,6 +187,8 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = { .codec_name = "tlv320aic3x-codec.0-001a", .init = evm_aic3x_init, .ops = &evm_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }, { .name = "McASP", @@ -216,7 +197,8 @@ static struct snd_soc_dai_link dm6467_evm_dai[] = { .codec_dai_name = "dit-hifi", .codec_name = "spdif_dit", .platform_name = "davinci-mcasp.1", - .ops = &evm_spdif_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }, }; @@ -229,6 +211,8 @@ static struct snd_soc_dai_link da830_evm_dai = { .platform_name = "davinci-mcasp.1", .init = evm_aic3x_init, .ops = &evm_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }; static struct snd_soc_dai_link da850_evm_dai = { @@ -240,6 +224,8 @@ static struct snd_soc_dai_link da850_evm_dai = { .platform_name = "davinci-mcasp.0", .init = evm_aic3x_init, .ops = &evm_ops, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }; /* davinci dm6446 evm audio machine driver */ @@ -336,6 +322,8 @@ static struct snd_soc_dai_link evm_dai_tlv320aic3x = { .codec_dai_name = "tlv320aic3x-hifi", .ops = &evm_ops, .init = evm_aic3x_init, + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_NF, }; static const struct of_device_id davinci_evm_dt_ids[] = { diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 71e14bb3a8cd..b7858bfa0295 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -31,351 +32,147 @@ #include #include #include +#include #include "davinci-pcm.h" #include "davinci-mcasp.h" -/* - * McASP register definitions - */ -#define DAVINCI_MCASP_PID_REG 0x00 -#define DAVINCI_MCASP_PWREMUMGT_REG 0x04 +struct davinci_mcasp { + struct davinci_pcm_dma_params dma_params[2]; + struct snd_dmaengine_dai_dma_data dma_data[2]; + void __iomem *base; + u32 fifo_base; + struct device *dev; -#define DAVINCI_MCASP_PFUNC_REG 0x10 -#define DAVINCI_MCASP_PDIR_REG 0x14 -#define DAVINCI_MCASP_PDOUT_REG 0x18 -#define DAVINCI_MCASP_PDSET_REG 0x1c + /* McASP specific data */ + int tdm_slots; + u8 op_mode; + u8 num_serializer; + u8 *serial_dir; + u8 version; + u16 bclk_lrclk_ratio; + int streams; -#define DAVINCI_MCASP_PDCLR_REG 0x20 + /* McASP FIFO related */ + u8 txnumevt; + u8 rxnumevt; -#define DAVINCI_MCASP_TLGC_REG 0x30 -#define DAVINCI_MCASP_TLMR_REG 0x34 + bool dat_port; -#define DAVINCI_MCASP_GBLCTL_REG 0x44 -#define DAVINCI_MCASP_AMUTE_REG 0x48 -#define DAVINCI_MCASP_LBCTL_REG 0x4c +#ifdef CONFIG_PM_SLEEP + struct { + u32 txfmtctl; + u32 rxfmtctl; + u32 txfmt; + u32 rxfmt; + u32 aclkxctl; + u32 aclkrctl; + u32 pdir; + } context; +#endif +}; -#define DAVINCI_MCASP_TXDITCTL_REG 0x50 - -#define DAVINCI_MCASP_GBLCTLR_REG 0x60 -#define DAVINCI_MCASP_RXMASK_REG 0x64 -#define DAVINCI_MCASP_RXFMT_REG 0x68 -#define DAVINCI_MCASP_RXFMCTL_REG 0x6c - -#define DAVINCI_MCASP_ACLKRCTL_REG 0x70 -#define DAVINCI_MCASP_AHCLKRCTL_REG 0x74 -#define DAVINCI_MCASP_RXTDM_REG 0x78 -#define DAVINCI_MCASP_EVTCTLR_REG 0x7c - -#define DAVINCI_MCASP_RXSTAT_REG 0x80 -#define DAVINCI_MCASP_RXTDMSLOT_REG 0x84 -#define DAVINCI_MCASP_RXCLKCHK_REG 0x88 -#define DAVINCI_MCASP_REVTCTL_REG 0x8c - -#define DAVINCI_MCASP_GBLCTLX_REG 0xa0 -#define DAVINCI_MCASP_TXMASK_REG 0xa4 -#define DAVINCI_MCASP_TXFMT_REG 0xa8 -#define DAVINCI_MCASP_TXFMCTL_REG 0xac - -#define DAVINCI_MCASP_ACLKXCTL_REG 0xb0 -#define DAVINCI_MCASP_AHCLKXCTL_REG 0xb4 -#define DAVINCI_MCASP_TXTDM_REG 0xb8 -#define DAVINCI_MCASP_EVTCTLX_REG 0xbc - -#define DAVINCI_MCASP_TXSTAT_REG 0xc0 -#define DAVINCI_MCASP_TXTDMSLOT_REG 0xc4 -#define DAVINCI_MCASP_TXCLKCHK_REG 0xc8 -#define DAVINCI_MCASP_XEVTCTL_REG 0xcc - -/* Left(even TDM Slot) Channel Status Register File */ -#define DAVINCI_MCASP_DITCSRA_REG 0x100 -/* Right(odd TDM slot) Channel Status Register File */ -#define DAVINCI_MCASP_DITCSRB_REG 0x118 -/* Left(even TDM slot) User Data Register File */ -#define DAVINCI_MCASP_DITUDRA_REG 0x130 -/* Right(odd TDM Slot) User Data Register File */ -#define DAVINCI_MCASP_DITUDRB_REG 0x148 - -/* Serializer n Control Register */ -#define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180 -#define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \ - (n << 2)) - -/* Transmit Buffer for Serializer n */ -#define DAVINCI_MCASP_TXBUF_REG 0x200 -/* Receive Buffer for Serializer n */ -#define DAVINCI_MCASP_RXBUF_REG 0x280 - -/* McASP FIFO Registers */ -#define DAVINCI_MCASP_WFIFOCTL (0x1010) -#define DAVINCI_MCASP_WFIFOSTS (0x1014) -#define DAVINCI_MCASP_RFIFOCTL (0x1018) -#define DAVINCI_MCASP_RFIFOSTS (0x101C) -#define MCASP_VER3_WFIFOCTL (0x1000) -#define MCASP_VER3_WFIFOSTS (0x1004) -#define MCASP_VER3_RFIFOCTL (0x1008) -#define MCASP_VER3_RFIFOSTS (0x100C) - -/* - * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management - * Register Bits - */ -#define MCASP_FREE BIT(0) -#define MCASP_SOFT BIT(1) - -/* - * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits - */ -#define AXR(n) (1<base + offset; __raw_writel(__raw_readl(reg) | val, reg); } -static inline void mcasp_clr_bits(void __iomem *reg, u32 val) +static inline void mcasp_clr_bits(struct davinci_mcasp *mcasp, u32 offset, + u32 val) { + void __iomem *reg = mcasp->base + offset; __raw_writel((__raw_readl(reg) & ~(val)), reg); } -static inline void mcasp_mod_bits(void __iomem *reg, u32 val, u32 mask) +static inline void mcasp_mod_bits(struct davinci_mcasp *mcasp, u32 offset, + u32 val, u32 mask) { + void __iomem *reg = mcasp->base + offset; __raw_writel((__raw_readl(reg) & ~mask) | val, reg); } -static inline void mcasp_set_reg(void __iomem *reg, u32 val) +static inline void mcasp_set_reg(struct davinci_mcasp *mcasp, u32 offset, + u32 val) { - __raw_writel(val, reg); + __raw_writel(val, mcasp->base + offset); } -static inline u32 mcasp_get_reg(void __iomem *reg) +static inline u32 mcasp_get_reg(struct davinci_mcasp *mcasp, u32 offset) { - return (unsigned int)__raw_readl(reg); + return (u32)__raw_readl(mcasp->base + offset); } -static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val) +static void mcasp_set_ctl_reg(struct davinci_mcasp *mcasp, u32 ctl_reg, u32 val) { int i = 0; - mcasp_set_bits(regs, val); + mcasp_set_bits(mcasp, ctl_reg, val); /* programming GBLCTL needs to read back from GBLCTL and verfiy */ /* loop count is to avoid the lock-up */ for (i = 0; i < 1000; i++) { - if ((mcasp_get_reg(regs) & val) == val) + if ((mcasp_get_reg(mcasp, ctl_reg) & val) == val) break; } - if (i == 1000 && ((mcasp_get_reg(regs) & val) != val)) + if (i == 1000 && ((mcasp_get_reg(mcasp, ctl_reg) & val) != val)) printk(KERN_ERR "GBLCTL write error\n"); } -static void mcasp_start_rx(struct davinci_audio_dev *dev) +static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp) { - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); - mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0); + u32 rxfmctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG); + u32 aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); - mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0); - - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); + return !(aclkxctl & TX_ASYNC) && rxfmctl & AFSRE; } -static void mcasp_start_tx(struct davinci_audio_dev *dev) +static void mcasp_start_rx(struct davinci_mcasp *mcasp) +{ + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST); + + /* + * When ASYNC == 0 the transmit and receive sections operate + * synchronously from the transmit clock and frame sync. We need to make + * sure that the TX signlas are enabled when starting reception. + */ + if (mcasp_is_synchronous(mcasp)) { + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); + } + + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXBUF_REG, 0); + + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXBUF_REG, 0); + + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST); + + if (mcasp_is_synchronous(mcasp)) + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); +} + +static void mcasp_start_tx(struct davinci_mcasp *mcasp) { u8 offset = 0, i; u32 cnt; - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); - mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); - for (i = 0; i < dev->num_serializer; i++) { - if (dev->serial_dir[i] == TX_MODE) { + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); + mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); + for (i = 0; i < mcasp->num_serializer; i++) { + if (mcasp->serial_dir[i] == TX_MODE) { offset = i; break; } @@ -383,156 +180,140 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) /* wait for TX ready */ cnt = 0; - while (!(mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(offset)) & + while (!(mcasp_get_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(offset)) & TXSTATE) && (cnt < 100000)) cnt++; - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXBUF_REG, 0); } -static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) +static void davinci_mcasp_start(struct davinci_mcasp *mcasp, int stream) { + u32 reg; + + mcasp->streams++; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (dev->txnumevt) { /* enable FIFO */ - switch (dev->version) { - case MCASP_VERSION_3: - mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL, - FIFO_ENABLE); - mcasp_set_bits(dev->base + MCASP_VER3_WFIFOCTL, - FIFO_ENABLE); - break; - default: - mcasp_clr_bits(dev->base + - DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); - mcasp_set_bits(dev->base + - DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); - } + if (mcasp->txnumevt) { /* enable FIFO */ + reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); + mcasp_set_bits(mcasp, reg, FIFO_ENABLE); } - mcasp_start_tx(dev); + mcasp_start_tx(mcasp); } else { - if (dev->rxnumevt) { /* enable FIFO */ - switch (dev->version) { - case MCASP_VERSION_3: - mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL, - FIFO_ENABLE); - mcasp_set_bits(dev->base + MCASP_VER3_RFIFOCTL, - FIFO_ENABLE); - break; - default: - mcasp_clr_bits(dev->base + - DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); - mcasp_set_bits(dev->base + - DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); - } + if (mcasp->rxnumevt) { /* enable FIFO */ + reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); + mcasp_set_bits(mcasp, reg, FIFO_ENABLE); } - mcasp_start_rx(dev); + mcasp_start_rx(mcasp); } } -static void mcasp_stop_rx(struct davinci_audio_dev *dev) +static void mcasp_stop_rx(struct davinci_mcasp *mcasp) { - mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0); - mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); + /* + * In synchronous mode stop the TX clocks if no other stream is + * running + */ + if (mcasp_is_synchronous(mcasp) && !mcasp->streams) + mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0); + + mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); } -static void mcasp_stop_tx(struct davinci_audio_dev *dev) +static void mcasp_stop_tx(struct davinci_mcasp *mcasp) { - mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0); - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); + u32 val = 0; + + /* + * In synchronous mode keep TX clocks running if the capture stream is + * still running. + */ + if (mcasp_is_synchronous(mcasp) && mcasp->streams) + val = TXHCLKRST | TXCLKRST | TXFSRST; + + mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); } -static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) +static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream) { + u32 reg; + + mcasp->streams--; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (dev->txnumevt) { /* disable FIFO */ - switch (dev->version) { - case MCASP_VERSION_3: - mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL, - FIFO_ENABLE); - break; - default: - mcasp_clr_bits(dev->base + - DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); - } + if (mcasp->txnumevt) { /* disable FIFO */ + reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); } - mcasp_stop_tx(dev); + mcasp_stop_tx(mcasp); } else { - if (dev->rxnumevt) { /* disable FIFO */ - switch (dev->version) { - case MCASP_VERSION_3: - mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL, - FIFO_ENABLE); - break; - - default: - mcasp_clr_bits(dev->base + - DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); - } + if (mcasp->rxnumevt) { /* disable FIFO */ + reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); } - mcasp_stop_rx(dev); + mcasp_stop_rx(mcasp); } } static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); - void __iomem *base = dev->base; + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_AC97: - mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); break; default: /* configure a full-word SYNC pulse (LRCLK) */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); - mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); /* make 1st data bit occur one ACLK cycle after the frame sync */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); - mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); break; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* codec is clock and frame slave */ - mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); - mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); - mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); - mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, - ACLKX | ACLKR); - mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, - AFSX | AFSR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); break; case SND_SOC_DAIFMT_CBM_CFS: /* codec is clock master and frame slave */ - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); - mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); - mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, - ACLKX | ACLKR); - mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, - AFSX | AFSR); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); break; case SND_SOC_DAIFMT_CBM_CFM: /* codec is clock and frame master */ - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); - mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE); - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); - mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); - mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, - ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, + ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); break; default: @@ -541,35 +322,35 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_NF: - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); break; case SND_SOC_DAIFMT_NB_IF: - mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); break; case SND_SOC_DAIFMT_IB_IF: - mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); break; case SND_SOC_DAIFMT_NB_NF: - mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); break; default: @@ -581,25 +362,25 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) { - struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); switch (div_id) { case 0: /* MCLK divider */ - mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, + mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(div - 1), AHCLKXDIV_MASK); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, + mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRDIV(div - 1), AHCLKRDIV_MASK); break; case 1: /* BCLK divider */ - mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, + mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXDIV(div - 1), ACLKXDIV_MASK); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_ACLKRCTL_REG, + mcasp_mod_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRDIV(div - 1), ACLKRDIV_MASK); break; case 2: /* BCLK/LRCLK ratio */ - dev->bclk_lrclk_ratio = div; + mcasp->bclk_lrclk_ratio = div; break; default: @@ -612,22 +393,22 @@ static int davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { - struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); if (dir == SND_SOC_CLOCK_OUT) { - mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); - mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); - mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); } else { - mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AHCLKX); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); } return 0; } -static int davinci_config_channel_size(struct davinci_audio_dev *dev, +static int davinci_config_channel_size(struct davinci_mcasp *mcasp, int word_length) { u32 fmt; @@ -644,71 +425,68 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, * both left and right channels), so it has to be divided by number of * tdm-slots (for I2S - divided by 2). */ - if (dev->bclk_lrclk_ratio) - word_length = dev->bclk_lrclk_ratio / dev->tdm_slots; + if (mcasp->bclk_lrclk_ratio) + word_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots; /* mapping of the XSSZ bit-field as described in the datasheet */ fmt = (word_length >> 1) - 1; - if (dev->op_mode != DAVINCI_MCASP_DIT_MODE) { - mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, - RXSSZ(fmt), RXSSZ(0x0F)); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, - TXSSZ(fmt), TXSSZ(0x0F)); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, - TXROT(tx_rotate), TXROT(7)); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, - RXROT(rx_rotate), RXROT(7)); - mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, - mask); + if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { + mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), + RXSSZ(0x0F)); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), + TXSSZ(0x0F)); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate), + TXROT(7)); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate), + RXROT(7)); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask); } - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, mask); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); return 0; } -static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream, +static int davinci_hw_common_param(struct davinci_mcasp *mcasp, int stream, int channels) { int i; u8 tx_ser = 0; u8 rx_ser = 0; u8 ser; - u8 slots = dev->tdm_slots; + u8 slots = mcasp->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; + u32 reg; /* Default configuration */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); + if (mcasp->version != MCASP_VERSION_4) + mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); /* All PINS as McASP */ - mcasp_set_reg(dev->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000); + mcasp_set_reg(mcasp, DAVINCI_MCASP_PFUNC_REG, 0x00000000); if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, - TXDATADMADIS); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS); } else { - mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_REVTCTL_REG, - RXDATADMADIS); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_REVTCTL_REG, RXDATADMADIS); } - for (i = 0; i < dev->num_serializer; i++) { - mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), - dev->serial_dir[i]); - if (dev->serial_dir[i] == TX_MODE && + for (i = 0; i < mcasp->num_serializer; i++) { + mcasp_set_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), + mcasp->serial_dir[i]); + if (mcasp->serial_dir[i] == TX_MODE && tx_ser < max_active_serializers) { - mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, - AXR(i)); + mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); tx_ser++; - } else if (dev->serial_dir[i] == RX_MODE && + } else if (mcasp->serial_dir[i] == RX_MODE && rx_ser < max_active_serializers) { - mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, - AXR(i)); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); rx_ser++; } else { - mcasp_mod_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), - SRMOD_INACTIVE, SRMOD_MASK); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), + SRMOD_INACTIVE, SRMOD_MASK); } } @@ -718,127 +496,113 @@ static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream, ser = rx_ser; if (ser < max_active_serializers) { - dev_warn(dev->dev, "stream has more channels (%d) than are " + dev_warn(mcasp->dev, "stream has more channels (%d) than are " "enabled in mcasp (%d)\n", channels, ser * slots); return -EINVAL; } - if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (dev->txnumevt * tx_ser > 64) - dev->txnumevt = 1; + if (mcasp->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (mcasp->txnumevt * tx_ser > 64) + mcasp->txnumevt = 1; - switch (dev->version) { - case MCASP_VERSION_3: - mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL, tx_ser, - NUMDMA_MASK); - mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL, - ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); - break; - default: - mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, - tx_ser, NUMDMA_MASK); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, - ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); - } + reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + mcasp_mod_bits(mcasp, reg, tx_ser, NUMDMA_MASK); + mcasp_mod_bits(mcasp, reg, ((mcasp->txnumevt * tx_ser) << 8), + NUMEVT_MASK); } - if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { - if (dev->rxnumevt * rx_ser > 64) - dev->rxnumevt = 1; - switch (dev->version) { - case MCASP_VERSION_3: - mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL, rx_ser, - NUMDMA_MASK); - mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL, - ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); - break; - default: - mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, - rx_ser, NUMDMA_MASK); - mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, - ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); - } + if (mcasp->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { + if (mcasp->rxnumevt * rx_ser > 64) + mcasp->rxnumevt = 1; + + reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + mcasp_mod_bits(mcasp, reg, rx_ser, NUMDMA_MASK); + mcasp_mod_bits(mcasp, reg, ((mcasp->rxnumevt * rx_ser) << 8), + NUMEVT_MASK); } return 0; } -static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) +static void davinci_hw_param(struct davinci_mcasp *mcasp, int stream) { int i, active_slots; u32 mask = 0; + u32 busel = 0; - active_slots = (dev->tdm_slots > 31) ? 32 : dev->tdm_slots; + active_slots = (mcasp->tdm_slots > 31) ? 32 : mcasp->tdm_slots; for (i = 0; i < active_slots; i++) mask |= (1 << i); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); + + if (!mcasp->dat_port) + busel = TXSEL; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { /* bit stream is MSB first with no delay */ /* DSP_B mode */ - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask); - mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); - if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) - mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, - FSXMOD(dev->tdm_slots), FSXMOD(0x1FF)); + if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, + FSXMOD(mcasp->tdm_slots), FSXMOD(0x1FF)); else printk(KERN_ERR "playback tdm slot %d not supported\n", - dev->tdm_slots); + mcasp->tdm_slots); } else { /* bit stream is MSB first with no delay */ /* DSP_B mode */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD); - mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); - if ((dev->tdm_slots >= 2) && (dev->tdm_slots <= 32)) - mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, - FSRMOD(dev->tdm_slots), FSRMOD(0x1FF)); + if ((mcasp->tdm_slots >= 2) && (mcasp->tdm_slots <= 32)) + mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, + FSRMOD(mcasp->tdm_slots), FSRMOD(0x1FF)); else printk(KERN_ERR "capture tdm slot %d not supported\n", - dev->tdm_slots); + mcasp->tdm_slots); } } /* S/PDIF */ -static void davinci_hw_dit_param(struct davinci_audio_dev *dev) +static void davinci_hw_dit_param(struct davinci_mcasp *mcasp) { /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 and LSB first */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, - TXROT(6) | TXSSZ(15)); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15)); /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */ - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG, - AFSXE | FSXMOD(0x180)); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE | FSXMOD(0x180)); /* Set the TX tdm : for all the slots */ - mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF); /* Set the TX clock controls : div = 1 and internal */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, - ACLKXE | TX_ASYNC); + mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE | TX_ASYNC); - mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS); /* Only 44100 and 48000 are valid, both have the same setting */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3)); + mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3)); /* Enable the DIT */ - mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN); + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); } static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *cpu_dai) { - struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); struct davinci_pcm_dma_params *dma_params = - &dev->dma_params[substream->stream]; + &mcasp->dma_params[substream->stream]; + struct snd_dmaengine_dai_dma_data *dma_data = + &mcasp->dma_data[substream->stream]; int word_length; u8 fifo_level; - u8 slots = dev->tdm_slots; + u8 slots = mcasp->tdm_slots; u8 active_serializers; int channels; struct snd_interval *pcm_channels = hw_param_interval(params, @@ -847,17 +611,17 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, active_serializers = (channels + slots - 1) / slots; - if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL) + if (davinci_hw_common_param(mcasp, substream->stream, channels) == -EINVAL) return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - fifo_level = dev->txnumevt * active_serializers; + fifo_level = mcasp->txnumevt * active_serializers; else - fifo_level = dev->rxnumevt * active_serializers; + fifo_level = mcasp->rxnumevt * active_serializers; - if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) - davinci_hw_dit_param(dev); + if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) + davinci_hw_dit_param(mcasp); else - davinci_hw_param(dev, substream->stream); + davinci_hw_param(mcasp, substream->stream); switch (params_format(params)) { case SNDRV_PCM_FORMAT_U8: @@ -891,13 +655,15 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - if (dev->version == MCASP_VERSION_2 && !fifo_level) + if (mcasp->version == MCASP_VERSION_2 && !fifo_level) dma_params->acnt = 4; else dma_params->acnt = dma_params->data_type; dma_params->fifo_level = fifo_level; - davinci_config_channel_size(dev, word_length); + dma_data->maxburst = fifo_level; + + davinci_config_channel_size(mcasp, word_length); return 0; } @@ -905,29 +671,29 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { - struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); int ret = 0; switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ret = pm_runtime_get_sync(dev->dev); + ret = pm_runtime_get_sync(mcasp->dev); if (IS_ERR_VALUE(ret)) - dev_err(dev->dev, "pm_runtime_get_sync() failed\n"); - davinci_mcasp_start(dev, substream->stream); + dev_err(mcasp->dev, "pm_runtime_get_sync() failed\n"); + davinci_mcasp_start(mcasp, substream->stream); break; case SNDRV_PCM_TRIGGER_SUSPEND: - davinci_mcasp_stop(dev, substream->stream); - ret = pm_runtime_put_sync(dev->dev); + davinci_mcasp_stop(mcasp, substream->stream); + ret = pm_runtime_put_sync(mcasp->dev); if (IS_ERR_VALUE(ret)) - dev_err(dev->dev, "pm_runtime_put_sync() failed\n"); + dev_err(mcasp->dev, "pm_runtime_put_sync() failed\n"); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - davinci_mcasp_stop(dev, substream->stream); + davinci_mcasp_stop(mcasp, substream->stream); break; default: @@ -940,9 +706,14 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, static int davinci_mcasp_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + + if (mcasp->version == MCASP_VERSION_4) + snd_soc_dai_set_dma_data(dai, substream, + &mcasp->dma_data[substream->stream]); + else + snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); - snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); return 0; } @@ -955,6 +726,8 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .set_sysclk = davinci_mcasp_set_sysclk, }; +#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000 + #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_U8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ @@ -985,7 +758,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }, { - "davinci-mcasp.1", + .name = "davinci-mcasp.1", .playback = { .channels_min = 1, .channels_max = 384, @@ -1016,13 +789,20 @@ static struct snd_platform_data da830_mcasp_pdata = { .version = MCASP_VERSION_2, }; -static struct snd_platform_data omap2_mcasp_pdata = { +static struct snd_platform_data am33xx_mcasp_pdata = { .tx_dma_offset = 0, .rx_dma_offset = 0, .asp_chan_q = EVENTQ_0, .version = MCASP_VERSION_3, }; +static struct snd_platform_data dra7_mcasp_pdata = { + .tx_dma_offset = 0x200, + .rx_dma_offset = 0x284, + .asp_chan_q = EVENTQ_0, + .version = MCASP_VERSION_4, +}; + static const struct of_device_id mcasp_dt_ids[] = { { .compatible = "ti,dm646x-mcasp-audio", @@ -1034,12 +814,56 @@ static const struct of_device_id mcasp_dt_ids[] = { }, { .compatible = "ti,am33xx-mcasp-audio", - .data = &omap2_mcasp_pdata, + .data = &am33xx_mcasp_pdata, + }, + { + .compatible = "ti,dra7-mcasp-audio", + .data = &dra7_mcasp_pdata, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mcasp_dt_ids); +static int mcasp_reparent_fck(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct clk *gfclk, *parent_clk; + const char *parent_name; + int ret; + + if (!node) + return 0; + + parent_name = of_get_property(node, "fck_parent", NULL); + if (!parent_name) + return 0; + + gfclk = clk_get(&pdev->dev, "fck"); + if (IS_ERR(gfclk)) { + dev_err(&pdev->dev, "failed to get fck\n"); + return PTR_ERR(gfclk); + } + + parent_clk = clk_get(NULL, parent_name); + if (IS_ERR(parent_clk)) { + dev_err(&pdev->dev, "failed to get parent clock\n"); + ret = PTR_ERR(parent_clk); + goto err1; + } + + ret = clk_set_parent(gfclk, parent_clk); + if (ret) { + dev_err(&pdev->dev, "failed to reparent fck\n"); + goto err2; + } + +err2: + clk_put(parent_clk); +err1: + clk_put(gfclk); + return ret; +} + static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( struct platform_device *pdev) { @@ -1152,7 +976,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) struct davinci_pcm_dma_params *dma_data; struct resource *mem, *ioarea, *res, *dat; struct snd_platform_data *pdata; - struct davinci_audio_dev *dev; + struct davinci_mcasp *mcasp; int ret; if (!pdev->dev.platform_data && !pdev->dev.of_node) { @@ -1160,9 +984,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) return -EINVAL; } - dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev), + mcasp = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcasp), GFP_KERNEL); - if (!dev) + if (!mcasp) return -ENOMEM; pdata = davinci_mcasp_set_pdata_from_of(pdev); @@ -1173,7 +997,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); if (!mem) { - dev_warn(dev->dev, + dev_warn(mcasp->dev, "\"mpu\" mem resource not found, using index 0\n"); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { @@ -1197,32 +1021,39 @@ static int davinci_mcasp_probe(struct platform_device *pdev) return ret; } - dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); - if (!dev->base) { + mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); + if (!mcasp->base) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; goto err_release_clk; } - dev->op_mode = pdata->op_mode; - dev->tdm_slots = pdata->tdm_slots; - dev->num_serializer = pdata->num_serializer; - dev->serial_dir = pdata->serial_dir; - dev->version = pdata->version; - dev->txnumevt = pdata->txnumevt; - dev->rxnumevt = pdata->rxnumevt; - dev->dev = &pdev->dev; + mcasp->op_mode = pdata->op_mode; + mcasp->tdm_slots = pdata->tdm_slots; + mcasp->num_serializer = pdata->num_serializer; + mcasp->serial_dir = pdata->serial_dir; + mcasp->version = pdata->version; + mcasp->txnumevt = pdata->txnumevt; + mcasp->rxnumevt = pdata->rxnumevt; + + mcasp->dev = &pdev->dev; dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); - if (!dat) - dat = mem; + if (dat) + mcasp->dat_port = true; - dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; + dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; dma_data->asp_chan_q = pdata->asp_chan_q; dma_data->ram_chan_q = pdata->ram_chan_q; dma_data->sram_pool = pdata->sram_pool; dma_data->sram_size = pdata->sram_size_playback; - dma_data->dma_addr = dat->start + pdata->tx_dma_offset; + if (dat) + dma_data->dma_addr = dat->start; + else + dma_data->dma_addr = mem->start + pdata->tx_dma_offset; + + /* Unconditional dmaengine stuff */ + mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_data->dma_addr; res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (res) @@ -1230,12 +1061,26 @@ static int davinci_mcasp_probe(struct platform_device *pdev) else dma_data->channel = pdata->tx_dma_channel; - dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; + dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; dma_data->asp_chan_q = pdata->asp_chan_q; dma_data->ram_chan_q = pdata->ram_chan_q; dma_data->sram_pool = pdata->sram_pool; dma_data->sram_size = pdata->sram_size_capture; - dma_data->dma_addr = dat->start + pdata->rx_dma_offset; + if (dat) + dma_data->dma_addr = dat->start; + else + dma_data->dma_addr = mem->start + pdata->rx_dma_offset; + + /* Unconditional dmaengine stuff */ + mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_data->dma_addr; + + if (mcasp->version < MCASP_VERSION_3) { + mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; + /* dma_data->dma_addr is pointing to the data port address */ + mcasp->dat_port = true; + } else { + mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; + } res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (res) @@ -1243,17 +1088,26 @@ static int davinci_mcasp_probe(struct platform_device *pdev) else dma_data->channel = pdata->rx_dma_channel; - dev_set_drvdata(&pdev->dev, dev); + /* Unconditional dmaengine stuff */ + mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx"; + mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = "rx"; + + dev_set_drvdata(&pdev->dev, mcasp); + + mcasp_reparent_fck(pdev); + ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, &davinci_mcasp_dai[pdata->op_mode], 1); if (ret != 0) goto err_release_clk; - ret = davinci_soc_platform_register(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - goto err_unregister_component; + if (mcasp->version != MCASP_VERSION_4) { + ret = davinci_soc_platform_register(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "register PCM failed: %d\n", ret); + goto err_unregister_component; + } } return 0; @@ -1268,9 +1122,11 @@ err_release_clk: static int davinci_mcasp_remove(struct platform_device *pdev) { + struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev); snd_soc_unregister_component(&pdev->dev); - davinci_soc_platform_unregister(&pdev->dev); + if (mcasp->version != MCASP_VERSION_4) + davinci_soc_platform_unregister(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1281,32 +1137,30 @@ static int davinci_mcasp_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int davinci_mcasp_suspend(struct device *dev) { - struct davinci_audio_dev *a = dev_get_drvdata(dev); - void __iomem *base = a->base; + struct davinci_mcasp *mcasp = dev_get_drvdata(dev); - a->context.txfmtctl = mcasp_get_reg(base + DAVINCI_MCASP_TXFMCTL_REG); - a->context.rxfmtctl = mcasp_get_reg(base + DAVINCI_MCASP_RXFMCTL_REG); - a->context.txfmt = mcasp_get_reg(base + DAVINCI_MCASP_TXFMT_REG); - a->context.rxfmt = mcasp_get_reg(base + DAVINCI_MCASP_RXFMT_REG); - a->context.aclkxctl = mcasp_get_reg(base + DAVINCI_MCASP_ACLKXCTL_REG); - a->context.aclkrctl = mcasp_get_reg(base + DAVINCI_MCASP_ACLKRCTL_REG); - a->context.pdir = mcasp_get_reg(base + DAVINCI_MCASP_PDIR_REG); + mcasp->context.txfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG); + mcasp->context.rxfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG); + mcasp->context.txfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMT_REG); + mcasp->context.rxfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMT_REG); + mcasp->context.aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG); + mcasp->context.aclkrctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG); + mcasp->context.pdir = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG); return 0; } static int davinci_mcasp_resume(struct device *dev) { - struct davinci_audio_dev *a = dev_get_drvdata(dev); - void __iomem *base = a->base; + struct davinci_mcasp *mcasp = dev_get_drvdata(dev); - mcasp_set_reg(base + DAVINCI_MCASP_TXFMCTL_REG, a->context.txfmtctl); - mcasp_set_reg(base + DAVINCI_MCASP_RXFMCTL_REG, a->context.rxfmtctl); - mcasp_set_reg(base + DAVINCI_MCASP_TXFMT_REG, a->context.txfmt); - mcasp_set_reg(base + DAVINCI_MCASP_RXFMT_REG, a->context.rxfmt); - mcasp_set_reg(base + DAVINCI_MCASP_ACLKXCTL_REG, a->context.aclkxctl); - mcasp_set_reg(base + DAVINCI_MCASP_ACLKRCTL_REG, a->context.aclkrctl); - mcasp_set_reg(base + DAVINCI_MCASP_PDIR_REG, a->context.pdir); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, mcasp->context.txfmtctl); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG, mcasp->context.rxfmtctl); + mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMT_REG, mcasp->context.txfmt); + mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMT_REG, mcasp->context.rxfmt); + mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, mcasp->context.aclkxctl); + mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, mcasp->context.aclkrctl); + mcasp_set_reg(mcasp, DAVINCI_MCASP_PDIR_REG, mcasp->context.pdir); return 0; } diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index a2e27e1c32f3..8fed757d6087 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h @@ -18,43 +18,271 @@ #ifndef DAVINCI_MCASP_H #define DAVINCI_MCASP_H -#include -#include +/* + * McASP register definitions + */ +#define DAVINCI_MCASP_PID_REG 0x00 +#define DAVINCI_MCASP_PWREMUMGT_REG 0x04 -#include "davinci-pcm.h" +#define DAVINCI_MCASP_PFUNC_REG 0x10 +#define DAVINCI_MCASP_PDIR_REG 0x14 +#define DAVINCI_MCASP_PDOUT_REG 0x18 +#define DAVINCI_MCASP_PDSET_REG 0x1c -#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000 -#define DAVINCI_MCASP_I2S_DAI 0 -#define DAVINCI_MCASP_DIT_DAI 1 +#define DAVINCI_MCASP_PDCLR_REG 0x20 -struct davinci_audio_dev { - struct davinci_pcm_dma_params dma_params[2]; - void __iomem *base; - struct device *dev; +#define DAVINCI_MCASP_TLGC_REG 0x30 +#define DAVINCI_MCASP_TLMR_REG 0x34 - /* McASP specific data */ - int tdm_slots; - u8 op_mode; - u8 num_serializer; - u8 *serial_dir; - u8 version; - u16 bclk_lrclk_ratio; +#define DAVINCI_MCASP_GBLCTL_REG 0x44 +#define DAVINCI_MCASP_AMUTE_REG 0x48 +#define DAVINCI_MCASP_LBCTL_REG 0x4c - /* McASP FIFO related */ - u8 txnumevt; - u8 rxnumevt; +#define DAVINCI_MCASP_TXDITCTL_REG 0x50 -#ifdef CONFIG_PM_SLEEP - struct { - u32 txfmtctl; - u32 rxfmtctl; - u32 txfmt; - u32 rxfmt; - u32 aclkxctl; - u32 aclkrctl; - u32 pdir; - } context; -#endif -}; +#define DAVINCI_MCASP_GBLCTLR_REG 0x60 +#define DAVINCI_MCASP_RXMASK_REG 0x64 +#define DAVINCI_MCASP_RXFMT_REG 0x68 +#define DAVINCI_MCASP_RXFMCTL_REG 0x6c + +#define DAVINCI_MCASP_ACLKRCTL_REG 0x70 +#define DAVINCI_MCASP_AHCLKRCTL_REG 0x74 +#define DAVINCI_MCASP_RXTDM_REG 0x78 +#define DAVINCI_MCASP_EVTCTLR_REG 0x7c + +#define DAVINCI_MCASP_RXSTAT_REG 0x80 +#define DAVINCI_MCASP_RXTDMSLOT_REG 0x84 +#define DAVINCI_MCASP_RXCLKCHK_REG 0x88 +#define DAVINCI_MCASP_REVTCTL_REG 0x8c + +#define DAVINCI_MCASP_GBLCTLX_REG 0xa0 +#define DAVINCI_MCASP_TXMASK_REG 0xa4 +#define DAVINCI_MCASP_TXFMT_REG 0xa8 +#define DAVINCI_MCASP_TXFMCTL_REG 0xac + +#define DAVINCI_MCASP_ACLKXCTL_REG 0xb0 +#define DAVINCI_MCASP_AHCLKXCTL_REG 0xb4 +#define DAVINCI_MCASP_TXTDM_REG 0xb8 +#define DAVINCI_MCASP_EVTCTLX_REG 0xbc + +#define DAVINCI_MCASP_TXSTAT_REG 0xc0 +#define DAVINCI_MCASP_TXTDMSLOT_REG 0xc4 +#define DAVINCI_MCASP_TXCLKCHK_REG 0xc8 +#define DAVINCI_MCASP_XEVTCTL_REG 0xcc + +/* Left(even TDM Slot) Channel Status Register File */ +#define DAVINCI_MCASP_DITCSRA_REG 0x100 +/* Right(odd TDM slot) Channel Status Register File */ +#define DAVINCI_MCASP_DITCSRB_REG 0x118 +/* Left(even TDM slot) User Data Register File */ +#define DAVINCI_MCASP_DITUDRA_REG 0x130 +/* Right(odd TDM Slot) User Data Register File */ +#define DAVINCI_MCASP_DITUDRB_REG 0x148 + +/* Serializer n Control Register */ +#define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180 +#define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \ + (n << 2)) + +/* Transmit Buffer for Serializer n */ +#define DAVINCI_MCASP_TXBUF_REG 0x200 +/* Receive Buffer for Serializer n */ +#define DAVINCI_MCASP_RXBUF_REG 0x280 + +/* McASP FIFO Registers */ +#define DAVINCI_MCASP_V2_AFIFO_BASE (0x1010) +#define DAVINCI_MCASP_V3_AFIFO_BASE (0x1000) + +/* FIFO register offsets from AFIFO base */ +#define MCASP_WFIFOCTL_OFFSET (0x0) +#define MCASP_WFIFOSTS_OFFSET (0x4) +#define MCASP_RFIFOCTL_OFFSET (0x8) +#define MCASP_RFIFOSTS_OFFSET (0xc) + +/* + * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management + * Register Bits + */ +#define MCASP_FREE BIT(0) +#define MCASP_SOFT BIT(1) + +/* + * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits + */ +#define AXR(n) (1< +#include +#include +#include +#include +#include +#include + +#include "fsl_esai.h" +#include "imx-pcm.h" + +#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 +#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +/** + * fsl_esai: ESAI private data + * + * @dma_params_rx: DMA parameters for receive channel + * @dma_params_tx: DMA parameters for transmit channel + * @pdev: platform device pointer + * @regmap: regmap handler + * @coreclk: clock source to access register + * @extalclk: esai clock source to derive HCK, SCK and FS + * @fsysclk: system clock source to derive HCK, SCK and FS + * @fifo_depth: depth of tx/rx FIFO + * @slot_width: width of each DAI slot + * @hck_rate: clock rate of desired HCKx clock + * @sck_div: if using PSR/PM dividers for SCKx clock + * @slave_mode: if fully using DAI slave mode + * @synchronous: if using tx/rx synchronous mode + * @name: driver name + */ +struct fsl_esai { + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_dai_dma_data dma_params_tx; + struct platform_device *pdev; + struct regmap *regmap; + struct clk *coreclk; + struct clk *extalclk; + struct clk *fsysclk; + u32 fifo_depth; + u32 slot_width; + u32 hck_rate[2]; + bool sck_div[2]; + bool slave_mode; + bool synchronous; + char name[32]; +}; + +static irqreturn_t esai_isr(int irq, void *devid) +{ + struct fsl_esai *esai_priv = (struct fsl_esai *)devid; + struct platform_device *pdev = esai_priv->pdev; + u32 esr; + + regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr); + + if (esr & ESAI_ESR_TINIT_MASK) + dev_dbg(&pdev->dev, "isr: Transmition Initialized\n"); + + if (esr & ESAI_ESR_RFF_MASK) + dev_warn(&pdev->dev, "isr: Receiving overrun\n"); + + if (esr & ESAI_ESR_TFE_MASK) + dev_warn(&pdev->dev, "isr: Transmition underrun\n"); + + if (esr & ESAI_ESR_TLS_MASK) + dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); + + if (esr & ESAI_ESR_TDE_MASK) + dev_dbg(&pdev->dev, "isr: Transmition data exception\n"); + + if (esr & ESAI_ESR_TED_MASK) + dev_dbg(&pdev->dev, "isr: Transmitting even slots\n"); + + if (esr & ESAI_ESR_TD_MASK) + dev_dbg(&pdev->dev, "isr: Transmitting data\n"); + + if (esr & ESAI_ESR_RLS_MASK) + dev_dbg(&pdev->dev, "isr: Just received the last slot\n"); + + if (esr & ESAI_ESR_RDE_MASK) + dev_dbg(&pdev->dev, "isr: Receiving data exception\n"); + + if (esr & ESAI_ESR_RED_MASK) + dev_dbg(&pdev->dev, "isr: Receiving even slots\n"); + + if (esr & ESAI_ESR_RD_MASK) + dev_dbg(&pdev->dev, "isr: Receiving data\n"); + + return IRQ_HANDLED; +} + +/** + * This function is used to calculate the divisors of psr, pm, fp and it is + * supposed to be called in set_dai_sysclk() and set_bclk(). + * + * @ratio: desired overall ratio for the paticipating dividers + * @usefp: for HCK setting, there is no need to set fp divider + * @fp: bypass other dividers by setting fp directly if fp != 0 + * @tx: current setting is for playback or capture + */ +static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio, + bool usefp, u32 fp) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j; + + maxfp = usefp ? 16 : 1; + + if (usefp && fp) + goto out_fp; + + if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) { + dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n", + 2 * 8 * 256 * maxfp); + return -EINVAL; + } else if (ratio % 2) { + dev_err(dai->dev, "the raio must be even if using upper divider\n"); + return -EINVAL; + } + + ratio /= 2; + + psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8; + + /* Set the max fluctuation -- 0.1% of the max devisor */ + savesub = (psr ? 1 : 8) * 256 * maxfp / 1000; + + /* Find the best value for PM */ + for (i = 1; i <= 256; i++) { + for (j = 1; j <= maxfp; j++) { + /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */ + prod = (psr ? 1 : 8) * i * j; + + if (prod == ratio) + sub = 0; + else if (prod / ratio == 1) + sub = prod - ratio; + else if (ratio / prod == 1) + sub = ratio - prod; + else + continue; + + /* Calculate the fraction */ + sub = sub * 1000 / ratio; + if (sub < savesub) { + savesub = sub; + pm = i; + fp = j; + } + + /* We are lucky */ + if (savesub == 0) + goto out; + } + } + + if (pm == 999) { + dev_err(dai->dev, "failed to calculate proper divisors\n"); + return -EINVAL; + } + +out: + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), + ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK, + psr | ESAI_xCCR_xPM(pm)); + +out_fp: + /* Bypass fp if not being required */ + if (maxfp <= 1) + return 0; + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), + ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp)); + + return 0; +} + +/** + * This function mainly configures the clock frequency of MCLK (HCKT/HCKR) + * + * @Parameters: + * clk_id: The clock source of HCKT/HCKR + * (Input from outside; output from inside, FSYS or EXTAL) + * freq: The required clock rate of HCKT/HCKR + * dir: The clock direction of HCKT/HCKR + * + * Note: If the direction is input, we do not care about clk_id. + */ +static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + struct clk *clksrc = esai_priv->extalclk; + bool tx = clk_id <= ESAI_HCKT_EXTAL; + bool in = dir == SND_SOC_CLOCK_IN; + u32 ret, ratio, ecr = 0; + unsigned long clk_rate; + + /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ + esai_priv->sck_div[tx] = true; + + /* Set the direction of HCKT/HCKR pins */ + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx), + ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD); + + if (in) + goto out; + + switch (clk_id) { + case ESAI_HCKT_FSYS: + case ESAI_HCKR_FSYS: + clksrc = esai_priv->fsysclk; + break; + case ESAI_HCKT_EXTAL: + ecr |= ESAI_ECR_ETI; + case ESAI_HCKR_EXTAL: + ecr |= ESAI_ECR_ERI; + break; + default: + return -EINVAL; + } + + if (IS_ERR(clksrc)) { + dev_err(dai->dev, "no assigned %s clock\n", + clk_id % 2 ? "extal" : "fsys"); + return PTR_ERR(clksrc); + } + clk_rate = clk_get_rate(clksrc); + + ratio = clk_rate / freq; + if (ratio * freq > clk_rate) + ret = ratio * freq - clk_rate; + else if (ratio * freq < clk_rate) + ret = clk_rate - ratio * freq; + else + ret = 0; + + /* Block if clock source can not be divided into the required rate */ + if (ret != 0 && clk_rate / ret < 1000) { + dev_err(dai->dev, "failed to derive required HCK%c rate\n", + tx ? 'T' : 'R'); + return -EINVAL; + } + + if (ratio == 1) { + /* Bypass all the dividers if not being needed */ + ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO; + goto out; + } + + ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0); + if (ret) + return ret; + + esai_priv->sck_div[tx] = false; + +out: + esai_priv->hck_rate[tx] = freq; + + regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, + tx ? ESAI_ECR_ETI | ESAI_ECR_ETO : + ESAI_ECR_ERI | ESAI_ECR_ERO, ecr); + + return 0; +} + +/** + * This function configures the related dividers according to the bclk rate + */ +static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + u32 hck_rate = esai_priv->hck_rate[tx]; + u32 sub, ratio = hck_rate / freq; + + /* Don't apply for fully slave mode*/ + if (esai_priv->slave_mode) + return 0; + + if (ratio * freq > hck_rate) + sub = ratio * freq - hck_rate; + else if (ratio * freq < hck_rate) + sub = hck_rate - ratio * freq; + else + sub = 0; + + /* Block if clock source can not be divided into the required rate */ + if (sub != 0 && hck_rate / sub < 1000) { + dev_err(dai->dev, "failed to derive required SCK%c rate\n", + tx ? 'T' : 'R'); + return -EINVAL; + } + + if (esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) { + dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n"); + return -EINVAL; + } + + return fsl_esai_divisor_cal(dai, tx, ratio, true, + esai_priv->sck_div[tx] ? 0 : ratio); +} + +static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, + u32 rx_mask, int slots, int slot_width) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, + ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA, + ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask)); + regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB, + ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask)); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, + ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots)); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA, + ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask)); + regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB, + ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask)); + + esai_priv->slot_width = slot_width; + + return 0; +} + +static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + u32 xcr = 0, xccr = 0, mask; + + /* DAI mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + /* Data on rising edge of bclk, frame low, 1clk before data */ + xcr |= ESAI_xCR_xFSR; + xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; + break; + case SND_SOC_DAIFMT_LEFT_J: + /* Data on rising edge of bclk, frame high */ + xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; + break; + case SND_SOC_DAIFMT_RIGHT_J: + /* Data on rising edge of bclk, frame high, right aligned */ + xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA; + break; + case SND_SOC_DAIFMT_DSP_A: + /* Data on rising edge of bclk, frame high, 1clk before data */ + xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR; + xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; + break; + case SND_SOC_DAIFMT_DSP_B: + /* Data on rising edge of bclk, frame high */ + xcr |= ESAI_xCR_xFSL; + xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; + break; + default: + return -EINVAL; + } + + /* DAI clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + /* Nothing to do for both normal cases */ + break; + case SND_SOC_DAIFMT_IB_NF: + /* Invert bit clock */ + xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP; + break; + case SND_SOC_DAIFMT_NB_IF: + /* Invert frame clock */ + xccr ^= ESAI_xCCR_xFSP; + break; + case SND_SOC_DAIFMT_IB_IF: + /* Invert both clocks */ + xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP; + break; + default: + return -EINVAL; + } + + esai_priv->slave_mode = false; + + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + esai_priv->slave_mode = true; + break; + case SND_SOC_DAIFMT_CBS_CFM: + xccr |= ESAI_xCCR_xCKD; + break; + case SND_SOC_DAIFMT_CBM_CFS: + xccr |= ESAI_xCCR_xFSD; + break; + case SND_SOC_DAIFMT_CBS_CFS: + xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD; + break; + default: + return -EINVAL; + } + + mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR; + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr); + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr); + + mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP | + ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA; + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr); + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr); + + return 0; +} + +static int fsl_esai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + + /* + * Some platforms might use the same bit to gate all three or two of + * clocks, so keep all clocks open/close at the same time for safety + */ + clk_prepare_enable(esai_priv->coreclk); + if (!IS_ERR(esai_priv->extalclk)) + clk_prepare_enable(esai_priv->extalclk); + if (!IS_ERR(esai_priv->fsysclk)) + clk_prepare_enable(esai_priv->fsysclk); + + if (!dai->active) { + /* Reset Port C */ + regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, + ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO)); + regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, + ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO)); + + /* Set synchronous mode */ + regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR, + ESAI_SAICR_SYNC, esai_priv->synchronous ? + ESAI_SAICR_SYNC : 0); + + /* Set a default slot number -- 2 */ + regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, + ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2)); + regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, + ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2)); + } + + return 0; +} + +static int fsl_esai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + u32 width = snd_pcm_format_width(params_format(params)); + u32 channels = params_channels(params); + u32 bclk, mask, val, ret; + + bclk = params_rate(params) * esai_priv->slot_width * 2; + + ret = fsl_esai_set_bclk(dai, tx, bclk); + if (ret) + return ret; + + /* Use Normal mode to support monaural audio */ + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), + ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ? + ESAI_xCR_xMOD_NETWORK : 0); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), + ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR); + + mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | + (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); + val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | + (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels)); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); + + mask = ESAI_xCR_xSWS_MASK | (tx ? ESAI_xCR_PADC : 0); + val = ESAI_xCR_xSWS(esai_priv->slot_width, width) | (tx ? ESAI_xCR_PADC : 0); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val); + + return 0; +} + +static void fsl_esai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + + if (!IS_ERR(esai_priv->fsysclk)) + clk_disable_unprepare(esai_priv->fsysclk); + if (!IS_ERR(esai_priv->extalclk)) + clk_disable_unprepare(esai_priv->extalclk); + clk_disable_unprepare(esai_priv->coreclk); +} + +static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + u8 i, channels = substream->runtime->channels; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), + ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN); + + /* Write initial words reqiured by ESAI as normal procedure */ + for (i = 0; tx && i < channels; i++) + regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0); + + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), + tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, + tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels)); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), + tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0); + + /* Disable and reset FIFO */ + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), + ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR); + regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), + ESAI_xFCR_xFR, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static struct snd_soc_dai_ops fsl_esai_dai_ops = { + .startup = fsl_esai_startup, + .shutdown = fsl_esai_shutdown, + .trigger = fsl_esai_trigger, + .hw_params = fsl_esai_hw_params, + .set_sysclk = fsl_esai_set_dai_sysclk, + .set_fmt = fsl_esai_set_dai_fmt, + .set_tdm_slot = fsl_esai_set_dai_tdm_slot, +}; + +static int fsl_esai_dai_probe(struct snd_soc_dai *dai) +{ + struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx, + &esai_priv->dma_params_rx); + + return 0; +} + +static struct snd_soc_dai_driver fsl_esai_dai = { + .probe = fsl_esai_dai_probe, + .playback = { + .channels_min = 1, + .channels_max = 12, + .rates = FSL_ESAI_RATES, + .formats = FSL_ESAI_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 8, + .rates = FSL_ESAI_RATES, + .formats = FSL_ESAI_FORMATS, + }, + .ops = &fsl_esai_dai_ops, +}; + +static const struct snd_soc_component_driver fsl_esai_component = { + .name = "fsl-esai", +}; + +static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case REG_ESAI_ERDR: + case REG_ESAI_ECR: + case REG_ESAI_ESR: + case REG_ESAI_TFCR: + case REG_ESAI_TFSR: + case REG_ESAI_RFCR: + case REG_ESAI_RFSR: + case REG_ESAI_RX0: + case REG_ESAI_RX1: + case REG_ESAI_RX2: + case REG_ESAI_RX3: + case REG_ESAI_SAISR: + case REG_ESAI_SAICR: + case REG_ESAI_TCR: + case REG_ESAI_TCCR: + case REG_ESAI_RCR: + case REG_ESAI_RCCR: + case REG_ESAI_TSMA: + case REG_ESAI_TSMB: + case REG_ESAI_RSMA: + case REG_ESAI_RSMB: + case REG_ESAI_PRRC: + case REG_ESAI_PCRC: + return true; + default: + return false; + } +} + +static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case REG_ESAI_ETDR: + case REG_ESAI_ECR: + case REG_ESAI_TFCR: + case REG_ESAI_RFCR: + case REG_ESAI_TX0: + case REG_ESAI_TX1: + case REG_ESAI_TX2: + case REG_ESAI_TX3: + case REG_ESAI_TX4: + case REG_ESAI_TX5: + case REG_ESAI_TSR: + case REG_ESAI_SAICR: + case REG_ESAI_TCR: + case REG_ESAI_TCCR: + case REG_ESAI_RCR: + case REG_ESAI_RCCR: + case REG_ESAI_TSMA: + case REG_ESAI_TSMB: + case REG_ESAI_RSMA: + case REG_ESAI_RSMB: + case REG_ESAI_PRRC: + case REG_ESAI_PCRC: + return true; + default: + return false; + } +} + +static const struct regmap_config fsl_esai_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + + .max_register = REG_ESAI_PCRC, + .readable_reg = fsl_esai_readable_reg, + .writeable_reg = fsl_esai_writeable_reg, +}; + +static int fsl_esai_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct fsl_esai *esai_priv; + struct resource *res; + const uint32_t *iprop; + void __iomem *regs; + int irq, ret; + + esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL); + if (!esai_priv) + return -ENOMEM; + + esai_priv->pdev = pdev; + strcpy(esai_priv->name, np->name); + + /* Get the addresses and IRQ */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + "core", regs, &fsl_esai_regmap_config); + if (IS_ERR(esai_priv->regmap)) { + dev_err(&pdev->dev, "failed to init regmap: %ld\n", + PTR_ERR(esai_priv->regmap)); + return PTR_ERR(esai_priv->regmap); + } + + esai_priv->coreclk = devm_clk_get(&pdev->dev, "core"); + if (IS_ERR(esai_priv->coreclk)) { + dev_err(&pdev->dev, "failed to get core clock: %ld\n", + PTR_ERR(esai_priv->coreclk)); + return PTR_ERR(esai_priv->coreclk); + } + + esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal"); + if (IS_ERR(esai_priv->extalclk)) + dev_warn(&pdev->dev, "failed to get extal clock: %ld\n", + PTR_ERR(esai_priv->extalclk)); + + esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys"); + if (IS_ERR(esai_priv->fsysclk)) + dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n", + PTR_ERR(esai_priv->fsysclk)); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); + return irq; + } + + ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, + esai_priv->name, esai_priv); + if (ret) { + dev_err(&pdev->dev, "failed to claim irq %u\n", irq); + return ret; + } + + /* Set a default slot size */ + esai_priv->slot_width = 32; + + /* Set a default master/slave state */ + esai_priv->slave_mode = true; + + /* Determine the FIFO depth */ + iprop = of_get_property(np, "fsl,fifo-depth", NULL); + if (iprop) + esai_priv->fifo_depth = be32_to_cpup(iprop); + else + esai_priv->fifo_depth = 64; + + esai_priv->dma_params_tx.maxburst = 16; + esai_priv->dma_params_rx.maxburst = 16; + esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR; + esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR; + + esai_priv->synchronous = + of_property_read_bool(np, "fsl,esai-synchronous"); + + /* Implement full symmetry for synchronous mode */ + if (esai_priv->synchronous) { + fsl_esai_dai.symmetric_rates = 1; + fsl_esai_dai.symmetric_channels = 1; + fsl_esai_dai.symmetric_samplebits = 1; + } + + dev_set_drvdata(&pdev->dev, esai_priv); + + /* Reset ESAI unit */ + ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST); + if (ret) { + dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret); + return ret; + } + + /* + * We need to enable ESAI so as to access some of its registers. + * Otherwise, we would fail to dump regmap from user space. + */ + ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN); + if (ret) { + dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret); + return ret; + } + + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, + &fsl_esai_dai, 1); + if (ret) { + dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); + return ret; + } + + ret = imx_pcm_dma_init(pdev); + if (ret) + dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret); + + return ret; +} + +static const struct of_device_id fsl_esai_dt_ids[] = { + { .compatible = "fsl,imx35-esai", }, + {} +}; +MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); + +static struct platform_driver fsl_esai_driver = { + .probe = fsl_esai_probe, + .driver = { + .name = "fsl-esai-dai", + .owner = THIS_MODULE, + .of_match_table = fsl_esai_dt_ids, + }, +}; + +module_platform_driver(fsl_esai_driver); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:fsl-esai-dai"); diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h new file mode 100644 index 000000000000..9c9f957fcae1 --- /dev/null +++ b/sound/soc/fsl/fsl_esai.h @@ -0,0 +1,354 @@ +/* + * fsl_esai.h - ALSA ESAI interface for the Freescale i.MX SoC + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * Author: Nicolin Chen + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef _FSL_ESAI_DAI_H +#define _FSL_ESAI_DAI_H + +/* ESAI Register Map */ +#define REG_ESAI_ETDR 0x00 +#define REG_ESAI_ERDR 0x04 +#define REG_ESAI_ECR 0x08 +#define REG_ESAI_ESR 0x0C +#define REG_ESAI_TFCR 0x10 +#define REG_ESAI_TFSR 0x14 +#define REG_ESAI_RFCR 0x18 +#define REG_ESAI_RFSR 0x1C +#define REG_ESAI_xFCR(tx) (tx ? REG_ESAI_TFCR : REG_ESAI_RFCR) +#define REG_ESAI_xFSR(tx) (tx ? REG_ESAI_TFSR : REG_ESAI_RFSR) +#define REG_ESAI_TX0 0x80 +#define REG_ESAI_TX1 0x84 +#define REG_ESAI_TX2 0x88 +#define REG_ESAI_TX3 0x8C +#define REG_ESAI_TX4 0x90 +#define REG_ESAI_TX5 0x94 +#define REG_ESAI_TSR 0x98 +#define REG_ESAI_RX0 0xA0 +#define REG_ESAI_RX1 0xA4 +#define REG_ESAI_RX2 0xA8 +#define REG_ESAI_RX3 0xAC +#define REG_ESAI_SAISR 0xCC +#define REG_ESAI_SAICR 0xD0 +#define REG_ESAI_TCR 0xD4 +#define REG_ESAI_TCCR 0xD8 +#define REG_ESAI_RCR 0xDC +#define REG_ESAI_RCCR 0xE0 +#define REG_ESAI_xCR(tx) (tx ? REG_ESAI_TCR : REG_ESAI_RCR) +#define REG_ESAI_xCCR(tx) (tx ? REG_ESAI_TCCR : REG_ESAI_RCCR) +#define REG_ESAI_TSMA 0xE4 +#define REG_ESAI_TSMB 0xE8 +#define REG_ESAI_RSMA 0xEC +#define REG_ESAI_RSMB 0xF0 +#define REG_ESAI_xSMA(tx) (tx ? REG_ESAI_TSMA : REG_ESAI_RSMA) +#define REG_ESAI_xSMB(tx) (tx ? REG_ESAI_TSMB : REG_ESAI_RSMB) +#define REG_ESAI_PRRC 0xF8 +#define REG_ESAI_PCRC 0xFC + +/* ESAI Control Register -- REG_ESAI_ECR 0x8 */ +#define ESAI_ECR_ETI_SHIFT 19 +#define ESAI_ECR_ETI_MASK (1 << ESAI_ECR_ETI_SHIFT) +#define ESAI_ECR_ETI (1 << ESAI_ECR_ETI_SHIFT) +#define ESAI_ECR_ETO_SHIFT 18 +#define ESAI_ECR_ETO_MASK (1 << ESAI_ECR_ETO_SHIFT) +#define ESAI_ECR_ETO (1 << ESAI_ECR_ETO_SHIFT) +#define ESAI_ECR_ERI_SHIFT 17 +#define ESAI_ECR_ERI_MASK (1 << ESAI_ECR_ERI_SHIFT) +#define ESAI_ECR_ERI (1 << ESAI_ECR_ERI_SHIFT) +#define ESAI_ECR_ERO_SHIFT 16 +#define ESAI_ECR_ERO_MASK (1 << ESAI_ECR_ERO_SHIFT) +#define ESAI_ECR_ERO (1 << ESAI_ECR_ERO_SHIFT) +#define ESAI_ECR_ERST_SHIFT 1 +#define ESAI_ECR_ERST_MASK (1 << ESAI_ECR_ERST_SHIFT) +#define ESAI_ECR_ERST (1 << ESAI_ECR_ERST_SHIFT) +#define ESAI_ECR_ESAIEN_SHIFT 0 +#define ESAI_ECR_ESAIEN_MASK (1 << ESAI_ECR_ESAIEN_SHIFT) +#define ESAI_ECR_ESAIEN (1 << ESAI_ECR_ESAIEN_SHIFT) + +/* ESAI Status Register -- REG_ESAI_ESR 0xC */ +#define ESAI_ESR_TINIT_SHIFT 10 +#define ESAI_ESR_TINIT_MASK (1 << ESAI_ESR_TINIT_SHIFT) +#define ESAI_ESR_TINIT (1 << ESAI_ESR_TINIT_SHIFT) +#define ESAI_ESR_RFF_SHIFT 9 +#define ESAI_ESR_RFF_MASK (1 << ESAI_ESR_RFF_SHIFT) +#define ESAI_ESR_RFF (1 << ESAI_ESR_RFF_SHIFT) +#define ESAI_ESR_TFE_SHIFT 8 +#define ESAI_ESR_TFE_MASK (1 << ESAI_ESR_TFE_SHIFT) +#define ESAI_ESR_TFE (1 << ESAI_ESR_TFE_SHIFT) +#define ESAI_ESR_TLS_SHIFT 7 +#define ESAI_ESR_TLS_MASK (1 << ESAI_ESR_TLS_SHIFT) +#define ESAI_ESR_TLS (1 << ESAI_ESR_TLS_SHIFT) +#define ESAI_ESR_TDE_SHIFT 6 +#define ESAI_ESR_TDE_MASK (1 << ESAI_ESR_TDE_SHIFT) +#define ESAI_ESR_TDE (1 << ESAI_ESR_TDE_SHIFT) +#define ESAI_ESR_TED_SHIFT 5 +#define ESAI_ESR_TED_MASK (1 << ESAI_ESR_TED_SHIFT) +#define ESAI_ESR_TED (1 << ESAI_ESR_TED_SHIFT) +#define ESAI_ESR_TD_SHIFT 4 +#define ESAI_ESR_TD_MASK (1 << ESAI_ESR_TD_SHIFT) +#define ESAI_ESR_TD (1 << ESAI_ESR_TD_SHIFT) +#define ESAI_ESR_RLS_SHIFT 3 +#define ESAI_ESR_RLS_MASK (1 << ESAI_ESR_RLS_SHIFT) +#define ESAI_ESR_RLS (1 << ESAI_ESR_RLS_SHIFT) +#define ESAI_ESR_RDE_SHIFT 2 +#define ESAI_ESR_RDE_MASK (1 << ESAI_ESR_RDE_SHIFT) +#define ESAI_ESR_RDE (1 << ESAI_ESR_RDE_SHIFT) +#define ESAI_ESR_RED_SHIFT 1 +#define ESAI_ESR_RED_MASK (1 << ESAI_ESR_RED_SHIFT) +#define ESAI_ESR_RED (1 << ESAI_ESR_RED_SHIFT) +#define ESAI_ESR_RD_SHIFT 0 +#define ESAI_ESR_RD_MASK (1 << ESAI_ESR_RD_SHIFT) +#define ESAI_ESR_RD (1 << ESAI_ESR_RD_SHIFT) + +/* + * Transmit FIFO Configuration Register -- REG_ESAI_TFCR 0x10 + * Receive FIFO Configuration Register -- REG_ESAI_RFCR 0x18 + */ +#define ESAI_xFCR_TIEN_SHIFT 19 +#define ESAI_xFCR_TIEN_MASK (1 << ESAI_xFCR_TIEN_SHIFT) +#define ESAI_xFCR_TIEN (1 << ESAI_xFCR_TIEN_SHIFT) +#define ESAI_xFCR_REXT_SHIFT 19 +#define ESAI_xFCR_REXT_MASK (1 << ESAI_xFCR_REXT_SHIFT) +#define ESAI_xFCR_REXT (1 << ESAI_xFCR_REXT_SHIFT) +#define ESAI_xFCR_xWA_SHIFT 16 +#define ESAI_xFCR_xWA_WIDTH 3 +#define ESAI_xFCR_xWA_MASK (((1 << ESAI_xFCR_xWA_WIDTH) - 1) << ESAI_xFCR_xWA_SHIFT) +#define ESAI_xFCR_xWA(v) (((8 - ((v) >> 2)) << ESAI_xFCR_xWA_SHIFT) & ESAI_xFCR_xWA_MASK) +#define ESAI_xFCR_xFWM_SHIFT 8 +#define ESAI_xFCR_xFWM_WIDTH 8 +#define ESAI_xFCR_xFWM_MASK (((1 << ESAI_xFCR_xFWM_WIDTH) - 1) << ESAI_xFCR_xFWM_SHIFT) +#define ESAI_xFCR_xFWM(v) ((((v) - 1) << ESAI_xFCR_xFWM_SHIFT) & ESAI_xFCR_xFWM_MASK) +#define ESAI_xFCR_xE_SHIFT 2 +#define ESAI_xFCR_TE_WIDTH 6 +#define ESAI_xFCR_RE_WIDTH 4 +#define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) +#define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) +#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_TE_MASK) +#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_RE_MASK) +#define ESAI_xFCR_xFR_SHIFT 1 +#define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT) +#define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT) +#define ESAI_xFCR_xFEN_SHIFT 0 +#define ESAI_xFCR_xFEN_MASK (1 << ESAI_xFCR_xFEN_SHIFT) +#define ESAI_xFCR_xFEN (1 << ESAI_xFCR_xFEN_SHIFT) + +/* + * Transmit FIFO Status Register -- REG_ESAI_TFSR 0x14 + * Receive FIFO Status Register --REG_ESAI_RFSR 0x1C + */ +#define ESAI_xFSR_NTFO_SHIFT 12 +#define ESAI_xFSR_NRFI_SHIFT 12 +#define ESAI_xFSR_NTFI_SHIFT 8 +#define ESAI_xFSR_NRFO_SHIFT 8 +#define ESAI_xFSR_NTFx_WIDTH 3 +#define ESAI_xFSR_NRFx_WIDTH 2 +#define ESAI_xFSR_NTFO_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFO_SHIFT) +#define ESAI_xFSR_NTFI_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFI_SHIFT) +#define ESAI_xFSR_NRFO_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFO_SHIFT) +#define ESAI_xFSR_NRFI_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFI_SHIFT) +#define ESAI_xFSR_xFCNT_SHIFT 0 +#define ESAI_xFSR_xFCNT_WIDTH 8 +#define ESAI_xFSR_xFCNT_MASK (((1 << ESAI_xFSR_xFCNT_WIDTH) - 1) << ESAI_xFSR_xFCNT_SHIFT) + +/* ESAI Transmit Slot Register -- REG_ESAI_TSR 0x98 */ +#define ESAI_TSR_SHIFT 0 +#define ESAI_TSR_WIDTH 24 +#define ESAI_TSR_MASK (((1 << ESAI_TSR_WIDTH) - 1) << ESAI_TSR_SHIFT) + +/* Serial Audio Interface Status Register -- REG_ESAI_SAISR 0xCC */ +#define ESAI_SAISR_TODFE_SHIFT 17 +#define ESAI_SAISR_TODFE_MASK (1 << ESAI_SAISR_TODFE_SHIFT) +#define ESAI_SAISR_TODFE (1 << ESAI_SAISR_TODFE_SHIFT) +#define ESAI_SAISR_TEDE_SHIFT 16 +#define ESAI_SAISR_TEDE_MASK (1 << ESAI_SAISR_TEDE_SHIFT) +#define ESAI_SAISR_TEDE (1 << ESAI_SAISR_TEDE_SHIFT) +#define ESAI_SAISR_TDE_SHIFT 15 +#define ESAI_SAISR_TDE_MASK (1 << ESAI_SAISR_TDE_SHIFT) +#define ESAI_SAISR_TDE (1 << ESAI_SAISR_TDE_SHIFT) +#define ESAI_SAISR_TUE_SHIFT 14 +#define ESAI_SAISR_TUE_MASK (1 << ESAI_SAISR_TUE_SHIFT) +#define ESAI_SAISR_TUE (1 << ESAI_SAISR_TUE_SHIFT) +#define ESAI_SAISR_TFS_SHIFT 13 +#define ESAI_SAISR_TFS_MASK (1 << ESAI_SAISR_TFS_SHIFT) +#define ESAI_SAISR_TFS (1 << ESAI_SAISR_TFS_SHIFT) +#define ESAI_SAISR_RODF_SHIFT 10 +#define ESAI_SAISR_RODF_MASK (1 << ESAI_SAISR_RODF_SHIFT) +#define ESAI_SAISR_RODF (1 << ESAI_SAISR_RODF_SHIFT) +#define ESAI_SAISR_REDF_SHIFT 9 +#define ESAI_SAISR_REDF_MASK (1 << ESAI_SAISR_REDF_SHIFT) +#define ESAI_SAISR_REDF (1 << ESAI_SAISR_REDF_SHIFT) +#define ESAI_SAISR_RDF_SHIFT 8 +#define ESAI_SAISR_RDF_MASK (1 << ESAI_SAISR_RDF_SHIFT) +#define ESAI_SAISR_RDF (1 << ESAI_SAISR_RDF_SHIFT) +#define ESAI_SAISR_ROE_SHIFT 7 +#define ESAI_SAISR_ROE_MASK (1 << ESAI_SAISR_ROE_SHIFT) +#define ESAI_SAISR_ROE (1 << ESAI_SAISR_ROE_SHIFT) +#define ESAI_SAISR_RFS_SHIFT 6 +#define ESAI_SAISR_RFS_MASK (1 << ESAI_SAISR_RFS_SHIFT) +#define ESAI_SAISR_RFS (1 << ESAI_SAISR_RFS_SHIFT) +#define ESAI_SAISR_IF2_SHIFT 2 +#define ESAI_SAISR_IF2_MASK (1 << ESAI_SAISR_IF2_SHIFT) +#define ESAI_SAISR_IF2 (1 << ESAI_SAISR_IF2_SHIFT) +#define ESAI_SAISR_IF1_SHIFT 1 +#define ESAI_SAISR_IF1_MASK (1 << ESAI_SAISR_IF1_SHIFT) +#define ESAI_SAISR_IF1 (1 << ESAI_SAISR_IF1_SHIFT) +#define ESAI_SAISR_IF0_SHIFT 0 +#define ESAI_SAISR_IF0_MASK (1 << ESAI_SAISR_IF0_SHIFT) +#define ESAI_SAISR_IF0 (1 << ESAI_SAISR_IF0_SHIFT) + +/* Serial Audio Interface Control Register -- REG_ESAI_SAICR 0xD0 */ +#define ESAI_SAICR_ALC_SHIFT 8 +#define ESAI_SAICR_ALC_MASK (1 << ESAI_SAICR_ALC_SHIFT) +#define ESAI_SAICR_ALC (1 << ESAI_SAICR_ALC_SHIFT) +#define ESAI_SAICR_TEBE_SHIFT 7 +#define ESAI_SAICR_TEBE_MASK (1 << ESAI_SAICR_TEBE_SHIFT) +#define ESAI_SAICR_TEBE (1 << ESAI_SAICR_TEBE_SHIFT) +#define ESAI_SAICR_SYNC_SHIFT 6 +#define ESAI_SAICR_SYNC_MASK (1 << ESAI_SAICR_SYNC_SHIFT) +#define ESAI_SAICR_SYNC (1 << ESAI_SAICR_SYNC_SHIFT) +#define ESAI_SAICR_OF2_SHIFT 2 +#define ESAI_SAICR_OF2_MASK (1 << ESAI_SAICR_OF2_SHIFT) +#define ESAI_SAICR_OF2 (1 << ESAI_SAICR_OF2_SHIFT) +#define ESAI_SAICR_OF1_SHIFT 1 +#define ESAI_SAICR_OF1_MASK (1 << ESAI_SAICR_OF1_SHIFT) +#define ESAI_SAICR_OF1 (1 << ESAI_SAICR_OF1_SHIFT) +#define ESAI_SAICR_OF0_SHIFT 0 +#define ESAI_SAICR_OF0_MASK (1 << ESAI_SAICR_OF0_SHIFT) +#define ESAI_SAICR_OF0 (1 << ESAI_SAICR_OF0_SHIFT) + +/* + * Transmit Control Register -- REG_ESAI_TCR 0xD4 + * Receive Control Register -- REG_ESAI_RCR 0xDC + */ +#define ESAI_xCR_xLIE_SHIFT 23 +#define ESAI_xCR_xLIE_MASK (1 << ESAI_xCR_xLIE_SHIFT) +#define ESAI_xCR_xLIE (1 << ESAI_xCR_xLIE_SHIFT) +#define ESAI_xCR_xIE_SHIFT 22 +#define ESAI_xCR_xIE_MASK (1 << ESAI_xCR_xIE_SHIFT) +#define ESAI_xCR_xIE (1 << ESAI_xCR_xIE_SHIFT) +#define ESAI_xCR_xEDIE_SHIFT 21 +#define ESAI_xCR_xEDIE_MASK (1 << ESAI_xCR_xEDIE_SHIFT) +#define ESAI_xCR_xEDIE (1 << ESAI_xCR_xEDIE_SHIFT) +#define ESAI_xCR_xEIE_SHIFT 20 +#define ESAI_xCR_xEIE_MASK (1 << ESAI_xCR_xEIE_SHIFT) +#define ESAI_xCR_xEIE (1 << ESAI_xCR_xEIE_SHIFT) +#define ESAI_xCR_xPR_SHIFT 19 +#define ESAI_xCR_xPR_MASK (1 << ESAI_xCR_xPR_SHIFT) +#define ESAI_xCR_xPR (1 << ESAI_xCR_xPR_SHIFT) +#define ESAI_xCR_PADC_SHIFT 17 +#define ESAI_xCR_PADC_MASK (1 << ESAI_xCR_PADC_SHIFT) +#define ESAI_xCR_PADC (1 << ESAI_xCR_PADC_SHIFT) +#define ESAI_xCR_xFSR_SHIFT 16 +#define ESAI_xCR_xFSR_MASK (1 << ESAI_xCR_xFSR_SHIFT) +#define ESAI_xCR_xFSR (1 << ESAI_xCR_xFSR_SHIFT) +#define ESAI_xCR_xFSL_SHIFT 15 +#define ESAI_xCR_xFSL_MASK (1 << ESAI_xCR_xFSL_SHIFT) +#define ESAI_xCR_xFSL (1 << ESAI_xCR_xFSL_SHIFT) +#define ESAI_xCR_xSWS_SHIFT 10 +#define ESAI_xCR_xSWS_WIDTH 5 +#define ESAI_xCR_xSWS_MASK (((1 << ESAI_xCR_xSWS_WIDTH) - 1) << ESAI_xCR_xSWS_SHIFT) +#define ESAI_xCR_xSWS(s, w) ((w < 24 ? (s - w + ((w - 8) >> 2)) : (s < 32 ? 0x1e : 0x1f)) << ESAI_xCR_xSWS_SHIFT) +#define ESAI_xCR_xMOD_SHIFT 8 +#define ESAI_xCR_xMOD_WIDTH 2 +#define ESAI_xCR_xMOD_MASK (((1 << ESAI_xCR_xMOD_WIDTH) - 1) << ESAI_xCR_xMOD_SHIFT) +#define ESAI_xCR_xMOD_ONDEMAND (0x1 << ESAI_xCR_xMOD_SHIFT) +#define ESAI_xCR_xMOD_NETWORK (0x1 << ESAI_xCR_xMOD_SHIFT) +#define ESAI_xCR_xMOD_AC97 (0x3 << ESAI_xCR_xMOD_SHIFT) +#define ESAI_xCR_xWA_SHIFT 7 +#define ESAI_xCR_xWA_MASK (1 << ESAI_xCR_xWA_SHIFT) +#define ESAI_xCR_xWA (1 << ESAI_xCR_xWA_SHIFT) +#define ESAI_xCR_xSHFD_SHIFT 6 +#define ESAI_xCR_xSHFD_MASK (1 << ESAI_xCR_xSHFD_SHIFT) +#define ESAI_xCR_xSHFD (1 << ESAI_xCR_xSHFD_SHIFT) +#define ESAI_xCR_xE_SHIFT 0 +#define ESAI_xCR_TE_WIDTH 6 +#define ESAI_xCR_RE_WIDTH 4 +#define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) +#define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) +#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_TE_MASK) +#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_RE_MASK) + +/* + * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8 + * Receive Clock Control Register -- REG_ESAI_RCCR 0xE0 + */ +#define ESAI_xCCR_xHCKD_SHIFT 23 +#define ESAI_xCCR_xHCKD_MASK (1 << ESAI_xCCR_xHCKD_SHIFT) +#define ESAI_xCCR_xHCKD (1 << ESAI_xCCR_xHCKD_SHIFT) +#define ESAI_xCCR_xFSD_SHIFT 22 +#define ESAI_xCCR_xFSD_MASK (1 << ESAI_xCCR_xFSD_SHIFT) +#define ESAI_xCCR_xFSD (1 << ESAI_xCCR_xFSD_SHIFT) +#define ESAI_xCCR_xCKD_SHIFT 21 +#define ESAI_xCCR_xCKD_MASK (1 << ESAI_xCCR_xCKD_SHIFT) +#define ESAI_xCCR_xCKD (1 << ESAI_xCCR_xCKD_SHIFT) +#define ESAI_xCCR_xHCKP_SHIFT 20 +#define ESAI_xCCR_xHCKP_MASK (1 << ESAI_xCCR_xHCKP_SHIFT) +#define ESAI_xCCR_xHCKP (1 << ESAI_xCCR_xHCKP_SHIFT) +#define ESAI_xCCR_xFSP_SHIFT 19 +#define ESAI_xCCR_xFSP_MASK (1 << ESAI_xCCR_xFSP_SHIFT) +#define ESAI_xCCR_xFSP (1 << ESAI_xCCR_xFSP_SHIFT) +#define ESAI_xCCR_xCKP_SHIFT 18 +#define ESAI_xCCR_xCKP_MASK (1 << ESAI_xCCR_xCKP_SHIFT) +#define ESAI_xCCR_xCKP (1 << ESAI_xCCR_xCKP_SHIFT) +#define ESAI_xCCR_xFP_SHIFT 14 +#define ESAI_xCCR_xFP_WIDTH 4 +#define ESAI_xCCR_xFP_MASK (((1 << ESAI_xCCR_xFP_WIDTH) - 1) << ESAI_xCCR_xFP_SHIFT) +#define ESAI_xCCR_xFP(v) ((((v) - 1) << ESAI_xCCR_xFP_SHIFT) & ESAI_xCCR_xFP_MASK) +#define ESAI_xCCR_xDC_SHIFT 9 +#define ESAI_xCCR_xDC_WIDTH 4 +#define ESAI_xCCR_xDC_MASK (((1 << ESAI_xCCR_xDC_WIDTH) - 1) << ESAI_xCCR_xDC_SHIFT) +#define ESAI_xCCR_xDC(v) ((((v) - 1) << ESAI_xCCR_xDC_SHIFT) & ESAI_xCCR_xDC_MASK) +#define ESAI_xCCR_xPSR_SHIFT 8 +#define ESAI_xCCR_xPSR_MASK (1 << ESAI_xCCR_xPSR_SHIFT) +#define ESAI_xCCR_xPSR_BYPASS (1 << ESAI_xCCR_xPSR_SHIFT) +#define ESAI_xCCR_xPSR_DIV8 (0 << ESAI_xCCR_xPSR_SHIFT) +#define ESAI_xCCR_xPM_SHIFT 0 +#define ESAI_xCCR_xPM_WIDTH 8 +#define ESAI_xCCR_xPM_MASK (((1 << ESAI_xCCR_xPM_WIDTH) - 1) << ESAI_xCCR_xPM_SHIFT) +#define ESAI_xCCR_xPM(v) ((((v) - 1) << ESAI_xCCR_xPM_SHIFT) & ESAI_xCCR_xPM_MASK) + +/* Transmit Slot Mask Register A/B -- REG_ESAI_TSMA/B 0xE4 ~ 0xF0 */ +#define ESAI_xSMA_xS_SHIFT 0 +#define ESAI_xSMA_xS_WIDTH 16 +#define ESAI_xSMA_xS_MASK (((1 << ESAI_xSMA_xS_WIDTH) - 1) << ESAI_xSMA_xS_SHIFT) +#define ESAI_xSMA_xS(v) ((v) & ESAI_xSMA_xS_MASK) +#define ESAI_xSMB_xS_SHIFT 0 +#define ESAI_xSMB_xS_WIDTH 16 +#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT) +#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK) + +/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */ +#define ESAI_PRRC_PDC_SHIFT 0 +#define ESAI_PRRC_PDC_WIDTH 12 +#define ESAI_PRRC_PDC_MASK (((1 << ESAI_PRRC_PDC_WIDTH) - 1) << ESAI_PRRC_PDC_SHIFT) +#define ESAI_PRRC_PDC(v) ((v) & ESAI_PRRC_PDC_MASK) + +/* Port C Control Register -- REG_ESAI_PCRC 0xFC */ +#define ESAI_PCRC_PC_SHIFT 0 +#define ESAI_PCRC_PC_WIDTH 12 +#define ESAI_PCRC_PC_MASK (((1 << ESAI_PCRC_PC_WIDTH) - 1) << ESAI_PCRC_PC_SHIFT) +#define ESAI_PCRC_PC(v) ((v) & ESAI_PCRC_PC_MASK) + +#define ESAI_GPIO 0xfff + +/* ESAI clock source */ +#define ESAI_HCKT_FSYS 0 +#define ESAI_HCKT_EXTAL 1 +#define ESAI_HCKR_FSYS 2 +#define ESAI_HCKR_EXTAL 3 + +/* ESAI clock divider */ +#define ESAI_TX_DIV_PSR 0 +#define ESAI_TX_DIV_PM 1 +#define ESAI_TX_DIV_FP 2 +#define ESAI_RX_DIV_PSR 3 +#define ESAI_RX_DIV_PM 4 +#define ESAI_RX_DIV_FP 5 +#endif /* _FSL_ESAI_DAI_H */ diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c new file mode 100644 index 000000000000..cdd3fa830704 --- /dev/null +++ b/sound/soc/fsl/fsl_sai.c @@ -0,0 +1,459 @@ +/* + * Freescale ALSA SoC Digital Audio Interface (SAI) driver. + * + * Copyright 2012-2013 Freescale Semiconductor, Inc. + * + * This program is free software, you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 2 of the License, or(at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsl_sai.h" + +static inline u32 sai_readl(struct fsl_sai *sai, + const void __iomem *addr) +{ + u32 val; + + val = __raw_readl(addr); + + if (likely(sai->big_endian_regs)) + val = be32_to_cpu(val); + else + val = le32_to_cpu(val); + rmb(); + + return val; +} + +static inline void sai_writel(struct fsl_sai *sai, + u32 val, void __iomem *addr) +{ + wmb(); + if (likely(sai->big_endian_regs)) + val = cpu_to_be32(val); + else + val = cpu_to_le32(val); + + __raw_writel(val, addr); +} + +static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int fsl_dir) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + u32 val_cr2, reg_cr2; + + if (fsl_dir == FSL_FMT_TRANSMITTER) + reg_cr2 = FSL_SAI_TCR2; + else + reg_cr2 = FSL_SAI_RCR2; + + val_cr2 = sai_readl(sai, sai->base + reg_cr2); + val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; + + switch (clk_id) { + case FSL_SAI_CLK_BUS: + val_cr2 |= FSL_SAI_CR2_MSEL_BUS; + break; + case FSL_SAI_CLK_MAST1: + val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1; + break; + case FSL_SAI_CLK_MAST2: + val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2; + break; + case FSL_SAI_CLK_MAST3: + val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3; + break; + default: + return -EINVAL; + } + + sai_writel(sai, val_cr2, sai->base + reg_cr2); + + return 0; +} + +static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + int ret; + + if (dir == SND_SOC_CLOCK_IN) + return 0; + + ret = clk_prepare_enable(sai->clk); + if (ret) + return ret; + + ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, + FSL_FMT_TRANSMITTER); + if (ret) { + dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret); + goto err_clk; + } + + ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, + FSL_FMT_RECEIVER); + if (ret) { + dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret); + goto err_clk; + } + +err_clk: + clk_disable_unprepare(sai->clk); + + return ret; +} + +static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, + unsigned int fmt, int fsl_dir) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + u32 val_cr2, val_cr4, reg_cr2, reg_cr4; + + if (fsl_dir == FSL_FMT_TRANSMITTER) { + reg_cr2 = FSL_SAI_TCR2; + reg_cr4 = FSL_SAI_TCR4; + } else { + reg_cr2 = FSL_SAI_RCR2; + reg_cr4 = FSL_SAI_RCR4; + } + + val_cr2 = sai_readl(sai, sai->base + reg_cr2); + val_cr4 = sai_readl(sai, sai->base + reg_cr4); + + if (sai->big_endian_data) + val_cr4 &= ~FSL_SAI_CR4_MF; + else + val_cr4 |= FSL_SAI_CR4_MF; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + val_cr4 |= FSL_SAI_CR4_FSE; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_IF: + val_cr4 |= FSL_SAI_CR4_FSP; + val_cr2 &= ~FSL_SAI_CR2_BCP; + break; + case SND_SOC_DAIFMT_IB_NF: + val_cr4 &= ~FSL_SAI_CR4_FSP; + val_cr2 &= ~FSL_SAI_CR2_BCP; + break; + case SND_SOC_DAIFMT_NB_IF: + val_cr4 |= FSL_SAI_CR4_FSP; + val_cr2 |= FSL_SAI_CR2_BCP; + break; + case SND_SOC_DAIFMT_NB_NF: + val_cr4 &= ~FSL_SAI_CR4_FSP; + val_cr2 |= FSL_SAI_CR2_BCP; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + val_cr2 |= FSL_SAI_CR2_BCD_MSTR; + val_cr4 |= FSL_SAI_CR4_FSD_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; + val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; + break; + default: + return -EINVAL; + } + + sai_writel(sai, val_cr2, sai->base + reg_cr2); + sai_writel(sai, val_cr4, sai->base + reg_cr4); + + return 0; +} + +static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + int ret; + + ret = clk_prepare_enable(sai->clk); + if (ret) + return ret; + + ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); + if (ret) { + dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); + goto err_clk; + } + + ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); + if (ret) { + dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); + goto err_clk; + } + +err_clk: + clk_disable_unprepare(sai->clk); + + return ret; +} + +static int fsl_sai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *cpu_dai) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + u32 val_cr4, val_cr5, val_mr, reg_cr4, reg_cr5, reg_mr; + unsigned int channels = params_channels(params); + u32 word_width = snd_pcm_format_width(params_format(params)); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + reg_cr4 = FSL_SAI_TCR4; + reg_cr5 = FSL_SAI_TCR5; + reg_mr = FSL_SAI_TMR; + } else { + reg_cr4 = FSL_SAI_RCR4; + reg_cr5 = FSL_SAI_RCR5; + reg_mr = FSL_SAI_RMR; + } + + val_cr4 = sai_readl(sai, sai->base + reg_cr4); + val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; + val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; + + val_cr5 = sai_readl(sai, sai->base + reg_cr5); + val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; + val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; + val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; + + val_cr4 |= FSL_SAI_CR4_SYWD(word_width); + val_cr5 |= FSL_SAI_CR5_WNW(word_width); + val_cr5 |= FSL_SAI_CR5_W0W(word_width); + + val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; + if (sai->big_endian_data) + val_cr5 |= FSL_SAI_CR5_FBT(0); + else + val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); + + val_cr4 |= FSL_SAI_CR4_FRSZ(channels); + val_mr = ~0UL - ((1 << channels) - 1); + + sai_writel(sai, val_cr4, sai->base + reg_cr4); + sai_writel(sai, val_cr5, sai->base + reg_cr5); + sai_writel(sai, val_mr, sai->base + reg_mr); + + return 0; +} + +static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *cpu_dai) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3; + + val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2); + val_cr2 &= ~FSL_SAI_CR2_SYNC; + sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2); + + val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2); + val_cr2 |= FSL_SAI_CR2_SYNC; + sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2); + + tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR); + rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + tcsr |= FSL_SAI_CSR_FRDE; + rcsr &= ~FSL_SAI_CSR_FRDE; + reg_cr3 = FSL_SAI_TCR3; + } else { + rcsr |= FSL_SAI_CSR_FRDE; + tcsr &= ~FSL_SAI_CSR_FRDE; + reg_cr3 = FSL_SAI_RCR3; + } + + val_cr3 = sai_readl(sai, sai->base + reg_cr3); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + tcsr |= FSL_SAI_CSR_TERE; + rcsr |= FSL_SAI_CSR_TERE; + val_cr3 |= FSL_SAI_CR3_TRCE; + + sai_writel(sai, val_cr3, sai->base + reg_cr3); + sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); + sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (!(cpu_dai->playback_active || cpu_dai->capture_active)) { + tcsr &= ~FSL_SAI_CSR_TERE; + rcsr &= ~FSL_SAI_CSR_TERE; + } + + val_cr3 &= ~FSL_SAI_CR3_TRCE; + + sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR); + sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR); + sai_writel(sai, val_cr3, sai->base + reg_cr3); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int fsl_sai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + + return clk_prepare_enable(sai->clk); +} + +static void fsl_sai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *cpu_dai) +{ + struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + + clk_disable_unprepare(sai->clk); +} + +static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { + .set_sysclk = fsl_sai_set_dai_sysclk, + .set_fmt = fsl_sai_set_dai_fmt, + .hw_params = fsl_sai_hw_params, + .trigger = fsl_sai_trigger, + .startup = fsl_sai_startup, + .shutdown = fsl_sai_shutdown, +}; + +static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) +{ + struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); + int ret; + + ret = clk_prepare_enable(sai->clk); + if (ret) + return ret; + + sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR); + sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR); + sai_writel(sai, FSL_SAI_MAXBURST_TX * 2, sai->base + FSL_SAI_TCR1); + sai_writel(sai, FSL_SAI_MAXBURST_RX - 1, sai->base + FSL_SAI_RCR1); + + clk_disable_unprepare(sai->clk); + + snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, + &sai->dma_params_rx); + + snd_soc_dai_set_drvdata(cpu_dai, sai); + + return 0; +} + +static struct snd_soc_dai_driver fsl_sai_dai = { + .probe = fsl_sai_dai_probe, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = FSL_SAI_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = FSL_SAI_FORMATS, + }, + .ops = &fsl_sai_pcm_dai_ops, +}; + +static const struct snd_soc_component_driver fsl_component = { + .name = "fsl-sai", +}; + +static int fsl_sai_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct fsl_sai *sai; + struct resource *res; + int ret; + + sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); + if (!sai) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + sai->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(sai->base)) + return PTR_ERR(sai->base); + + sai->clk = devm_clk_get(&pdev->dev, "sai"); + if (IS_ERR(sai->clk)) { + dev_err(&pdev->dev, "Cannot get SAI's clock\n"); + return PTR_ERR(sai->clk); + } + + sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; + sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; + sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; + sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; + + sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); + sai->big_endian_data = of_property_read_bool(np, "big-endian-data"); + + platform_set_drvdata(pdev, sai); + + ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, + &fsl_sai_dai, 1); + if (ret) + return ret; + + return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); +} + +static const struct of_device_id fsl_sai_ids[] = { + { .compatible = "fsl,vf610-sai", }, + { /* sentinel */ } +}; + +static struct platform_driver fsl_sai_driver = { + .probe = fsl_sai_probe, + .driver = { + .name = "fsl-sai", + .owner = THIS_MODULE, + .of_match_table = fsl_sai_ids, + }, +}; +module_platform_driver(fsl_sai_driver); + +MODULE_DESCRIPTION("Freescale Soc SAI Interface"); +MODULE_AUTHOR("Xiubo Li, "); +MODULE_ALIAS("platform:fsl-sai"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h new file mode 100644 index 000000000000..41bb62e69361 --- /dev/null +++ b/sound/soc/fsl/fsl_sai.h @@ -0,0 +1,114 @@ +/* + * Copyright 2012-2013 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __FSL_SAI_H +#define __FSL_SAI_H + +#include + +#define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +/* SAI Transmit/Recieve Control Register */ +#define FSL_SAI_TCSR 0x00 +#define FSL_SAI_RCSR 0x80 +#define FSL_SAI_CSR_TERE BIT(31) +#define FSL_SAI_CSR_FWF BIT(17) +#define FSL_SAI_CSR_FRIE BIT(8) +#define FSL_SAI_CSR_FRDE BIT(0) + +/* SAI Transmit Data/FIFO/MASK Register */ +#define FSL_SAI_TDR 0x20 +#define FSL_SAI_TFR 0x40 +#define FSL_SAI_TMR 0x60 + +/* SAI Recieve Data/FIFO/MASK Register */ +#define FSL_SAI_RDR 0xa0 +#define FSL_SAI_RFR 0xc0 +#define FSL_SAI_RMR 0xe0 + +/* SAI Transmit and Recieve Configuration 1 Register */ +#define FSL_SAI_TCR1 0x04 +#define FSL_SAI_RCR1 0x84 + +/* SAI Transmit and Recieve Configuration 2 Register */ +#define FSL_SAI_TCR2 0x08 +#define FSL_SAI_RCR2 0x88 +#define FSL_SAI_CR2_SYNC BIT(30) +#define FSL_SAI_CR2_MSEL_MASK (0xff << 26) +#define FSL_SAI_CR2_MSEL_BUS 0 +#define FSL_SAI_CR2_MSEL_MCLK1 BIT(26) +#define FSL_SAI_CR2_MSEL_MCLK2 BIT(27) +#define FSL_SAI_CR2_MSEL_MCLK3 (BIT(26) | BIT(27)) +#define FSL_SAI_CR2_BCP BIT(25) +#define FSL_SAI_CR2_BCD_MSTR BIT(24) + +/* SAI Transmit and Recieve Configuration 3 Register */ +#define FSL_SAI_TCR3 0x0c +#define FSL_SAI_RCR3 0x8c +#define FSL_SAI_CR3_TRCE BIT(16) +#define FSL_SAI_CR3_WDFL(x) (x) +#define FSL_SAI_CR3_WDFL_MASK 0x1f + +/* SAI Transmit and Recieve Configuration 4 Register */ +#define FSL_SAI_TCR4 0x10 +#define FSL_SAI_RCR4 0x90 +#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) +#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) +#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) +#define FSL_SAI_CR4_SYWD_MASK (0x1f << 8) +#define FSL_SAI_CR4_MF BIT(4) +#define FSL_SAI_CR4_FSE BIT(3) +#define FSL_SAI_CR4_FSP BIT(1) +#define FSL_SAI_CR4_FSD_MSTR BIT(0) + +/* SAI Transmit and Recieve Configuration 5 Register */ +#define FSL_SAI_TCR5 0x14 +#define FSL_SAI_RCR5 0x94 +#define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24) +#define FSL_SAI_CR5_WNW_MASK (0x1f << 24) +#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16) +#define FSL_SAI_CR5_W0W_MASK (0x1f << 16) +#define FSL_SAI_CR5_FBT(x) ((x) << 8) +#define FSL_SAI_CR5_FBT_MASK (0x1f << 8) + +/* SAI type */ +#define FSL_SAI_DMA BIT(0) +#define FSL_SAI_USE_AC97 BIT(1) +#define FSL_SAI_NET BIT(2) +#define FSL_SAI_TRA_SYN BIT(3) +#define FSL_SAI_REC_SYN BIT(4) +#define FSL_SAI_USE_I2S_SLAVE BIT(5) + +#define FSL_FMT_TRANSMITTER 0 +#define FSL_FMT_RECEIVER 1 + +/* SAI clock sources */ +#define FSL_SAI_CLK_BUS 0 +#define FSL_SAI_CLK_MAST1 1 +#define FSL_SAI_CLK_MAST2 2 +#define FSL_SAI_CLK_MAST3 3 + +/* SAI data transfer numbers per DMA request */ +#define FSL_SAI_MAXBURST_TX 6 +#define FSL_SAI_MAXBURST_RX 6 + +struct fsl_sai { + struct clk *clk; + + void __iomem *base; + + bool big_endian_regs; + bool big_endian_data; + + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_dai_dma_data dma_params_tx; +}; + +#endif /* __FSL_SAI_H */ diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 55193a5596ca..4d075f1abe78 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1181,13 +1181,6 @@ static int fsl_spdif_probe(struct platform_device *pdev) return ret; } -static int fsl_spdif_remove(struct platform_device *pdev) -{ - imx_pcm_dma_exit(pdev); - - return 0; -} - static const struct of_device_id fsl_spdif_dt_ids[] = { { .compatible = "fsl,imx35-spdif", }, {} @@ -1201,7 +1194,6 @@ static struct platform_driver fsl_spdif_driver = { .of_match_table = fsl_spdif_dt_ids, }, .probe = fsl_spdif_probe, - .remove = fsl_spdif_remove, }; module_platform_driver(fsl_spdif_driver); diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 35e277379b86..f9090b167ad7 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -35,9 +35,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -79,8 +81,7 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) * ALSA that we support all rates and let the codec driver decide what rates * are really supported. */ -#define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ - SNDRV_PCM_RATE_CONTINUOUS) +#define FSLSSI_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS /** * FSLSSI_I2S_FORMATS: audio formats supported by the SSI @@ -106,12 +107,33 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) #endif -/* SIER bitflag of interrupts to enable */ -#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \ - CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \ - CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \ - CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \ - CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN) +#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \ + CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \ + CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN) +#define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ + CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ + CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) +#define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS) + + +enum fsl_ssi_type { + FSL_SSI_MCP8610, + FSL_SSI_MX21, + FSL_SSI_MX35, + FSL_SSI_MX51, +}; + +struct fsl_ssi_reg_val { + u32 sier; + u32 srcr; + u32 stcr; + u32 scr; +}; + +struct fsl_ssi_rxtx_reg_val { + struct fsl_ssi_reg_val rx; + struct fsl_ssi_reg_val tx; +}; /** * fsl_ssi_private: per-SSI private data @@ -119,8 +141,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) * @ssi: pointer to the SSI's registers * @ssi_phys: physical address of the SSI registers * @irq: IRQ of this SSI - * @first_stream: pointer to the stream that was opened first - * @second_stream: pointer to second stream * @playback: the number of playback streams opened * @capture: the number of capture streams opened * @cpu_dai: the CPU DAI for this device @@ -132,23 +152,29 @@ struct fsl_ssi_private { struct ccsr_ssi __iomem *ssi; dma_addr_t ssi_phys; unsigned int irq; - struct snd_pcm_substream *first_stream; - struct snd_pcm_substream *second_stream; unsigned int fifo_depth; struct snd_soc_dai_driver cpu_dai_drv; - struct device_attribute dev_attr; struct platform_device *pdev; + enum fsl_ssi_type hw_type; bool new_binding; bool ssi_on_imx; bool imx_ac97; bool use_dma; + bool baudclk_locked; + bool irq_stats; + bool offline_config; + u8 i2s_mode; + spinlock_t baudclk_lock; + struct clk *baudclk; struct clk *clk; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; struct imx_dma_data filter_data_tx; struct imx_dma_data filter_data_rx; struct imx_pcm_fiq_params fiq_params; + /* Register values for rx/tx configuration */ + struct fsl_ssi_rxtx_reg_val rxtx_reg_val; struct { unsigned int rfrc; @@ -173,10 +199,21 @@ struct fsl_ssi_private { unsigned int tfe1; unsigned int tfe0; } stats; + struct dentry *dbg_dir; + struct dentry *dbg_stats; char name[1]; }; +static const struct of_device_id fsl_ssi_ids[] = { + { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, + { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, + { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35}, + { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, + {} +}; +MODULE_DEVICE_TABLE(of, fsl_ssi_ids); + /** * fsl_ssi_isr: SSI interrupt handler * @@ -195,23 +232,40 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) struct ccsr_ssi __iomem *ssi = ssi_private->ssi; irqreturn_t ret = IRQ_NONE; __be32 sisr; - __be32 sisr2 = 0; + __be32 sisr2; + __be32 sisr_write_mask = 0; + + switch (ssi_private->hw_type) { + case FSL_SSI_MX21: + sisr_write_mask = 0; + break; + + case FSL_SSI_MCP8610: + case FSL_SSI_MX35: + sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | + CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | + CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; + break; + + case FSL_SSI_MX51: + sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | + CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; + break; + } /* We got an interrupt, so read the status register to see what we were interrupted for. We mask it with the Interrupt Enable register so that we only check for events that we're interested in. */ - sisr = read_ssi(&ssi->sisr) & SIER_FLAGS; + sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK; if (sisr & CCSR_SSI_SISR_RFRC) { ssi_private->stats.rfrc++; - sisr2 |= CCSR_SSI_SISR_RFRC; ret = IRQ_HANDLED; } if (sisr & CCSR_SSI_SISR_TFRC) { ssi_private->stats.tfrc++; - sisr2 |= CCSR_SSI_SISR_TFRC; ret = IRQ_HANDLED; } @@ -252,25 +306,21 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) if (sisr & CCSR_SSI_SISR_ROE1) { ssi_private->stats.roe1++; - sisr2 |= CCSR_SSI_SISR_ROE1; ret = IRQ_HANDLED; } if (sisr & CCSR_SSI_SISR_ROE0) { ssi_private->stats.roe0++; - sisr2 |= CCSR_SSI_SISR_ROE0; ret = IRQ_HANDLED; } if (sisr & CCSR_SSI_SISR_TUE1) { ssi_private->stats.tue1++; - sisr2 |= CCSR_SSI_SISR_TUE1; ret = IRQ_HANDLED; } if (sisr & CCSR_SSI_SISR_TUE0) { ssi_private->stats.tue0++; - sisr2 |= CCSR_SSI_SISR_TUE0; ret = IRQ_HANDLED; } @@ -314,6 +364,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) ret = IRQ_HANDLED; } + sisr2 = sisr & sisr_write_mask; /* Clear the bits that we set */ if (sisr2) write_ssi(sisr2, &ssi->sisr); @@ -321,17 +372,287 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) return ret; } +#if IS_ENABLED(CONFIG_DEBUG_FS) +/* Show the statistics of a flag only if its interrupt is enabled. The + * compiler will optimze this code to a no-op if the interrupt is not + * enabled. + */ +#define SIER_SHOW(flag, name) \ + do { \ + if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \ + seq_printf(s, #name "=%u\n", ssi_private->stats.name); \ + } while (0) + + +/** + * fsl_sysfs_ssi_show: display SSI statistics + * + * Display the statistics for the current SSI device. To avoid confusion, + * we only show those counts that are enabled. + */ +static int fsl_ssi_stats_show(struct seq_file *s, void *unused) +{ + struct fsl_ssi_private *ssi_private = s->private; + + SIER_SHOW(RFRC_EN, rfrc); + SIER_SHOW(TFRC_EN, tfrc); + SIER_SHOW(CMDAU_EN, cmdau); + SIER_SHOW(CMDDU_EN, cmddu); + SIER_SHOW(RXT_EN, rxt); + SIER_SHOW(RDR1_EN, rdr1); + SIER_SHOW(RDR0_EN, rdr0); + SIER_SHOW(TDE1_EN, tde1); + SIER_SHOW(TDE0_EN, tde0); + SIER_SHOW(ROE1_EN, roe1); + SIER_SHOW(ROE0_EN, roe0); + SIER_SHOW(TUE1_EN, tue1); + SIER_SHOW(TUE0_EN, tue0); + SIER_SHOW(TFS_EN, tfs); + SIER_SHOW(RFS_EN, rfs); + SIER_SHOW(TLS_EN, tls); + SIER_SHOW(RLS_EN, rls); + SIER_SHOW(RFF1_EN, rff1); + SIER_SHOW(RFF0_EN, rff0); + SIER_SHOW(TFE1_EN, tfe1); + SIER_SHOW(TFE0_EN, tfe0); + + return 0; +} + +static int fsl_ssi_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, fsl_ssi_stats_show, inode->i_private); +} + +static const struct file_operations fsl_ssi_stats_ops = { + .open = fsl_ssi_stats_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, + struct device *dev) +{ + ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL); + if (!ssi_private->dbg_dir) + return -ENOMEM; + + ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO, + ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops); + if (!ssi_private->dbg_stats) { + debugfs_remove(ssi_private->dbg_dir); + return -ENOMEM; + } + + return 0; +} + +static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) +{ + debugfs_remove(ssi_private->dbg_stats); + debugfs_remove(ssi_private->dbg_dir); +} + +#else + +static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, + struct device *dev) +{ + return 0; +} + +static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) +{ +} + +#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ + +/* + * Enable/Disable all rx/tx config flags at once. + */ +static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, + bool enable) +{ + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val; + + if (enable) { + write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier); + write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr); + write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr); + } else { + write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0); + write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0); + write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0); + } +} + +/* + * Enable/Disable a ssi configuration. You have to pass either + * ssi_private->rxtx_reg_val.rx or tx as vals parameter. + */ +static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, + struct fsl_ssi_reg_val *vals) +{ + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + struct fsl_ssi_reg_val *avals; + u32 scr_val = read_ssi(&ssi->scr); + int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + + !!(scr_val & CCSR_SSI_SCR_RE); + + /* Find the other direction values rx or tx which we do not want to + * modify */ + if (&ssi_private->rxtx_reg_val.rx == vals) + avals = &ssi_private->rxtx_reg_val.tx; + else + avals = &ssi_private->rxtx_reg_val.rx; + + /* If vals should be disabled, start with disabling the unit */ + if (!enable) { + u32 scr = vals->scr & (vals->scr ^ avals->scr); + write_ssi_mask(&ssi->scr, scr, 0); + } + + /* + * We are running on a SoC which does not support online SSI + * reconfiguration, so we have to enable all necessary flags at once + * even if we do not use them later (capture and playback configuration) + */ + if (ssi_private->offline_config) { + if ((enable && !nr_active_streams) || + (!enable && nr_active_streams == 1)) + fsl_ssi_rxtx_config(ssi_private, enable); + + goto config_done; + } + + /* + * Configure single direction units while the SSI unit is running + * (online configuration) + */ + if (enable) { + write_ssi_mask(&ssi->sier, 0, vals->sier); + write_ssi_mask(&ssi->srcr, 0, vals->srcr); + write_ssi_mask(&ssi->stcr, 0, vals->stcr); + } else { + u32 sier; + u32 srcr; + u32 stcr; + + /* + * Disabling the necessary flags for one of rx/tx while the + * other stream is active is a little bit more difficult. We + * have to disable only those flags that differ between both + * streams (rx XOR tx) and that are set in the stream that is + * disabled now. Otherwise we could alter flags of the other + * stream + */ + + /* These assignments are simply vals without bits set in avals*/ + sier = vals->sier & (vals->sier ^ avals->sier); + srcr = vals->srcr & (vals->srcr ^ avals->srcr); + stcr = vals->stcr & (vals->stcr ^ avals->stcr); + + write_ssi_mask(&ssi->srcr, srcr, 0); + write_ssi_mask(&ssi->stcr, stcr, 0); + write_ssi_mask(&ssi->sier, sier, 0); + } + +config_done: + /* Enabling of subunits is done after configuration */ + if (enable) + write_ssi_mask(&ssi->scr, 0, vals->scr); +} + + +static void fsl_ssi_rx_config(struct fsl_ssi_private *ssi_private, bool enable) +{ + fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.rx); +} + +static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable) +{ + fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx); +} + +/* + * Setup rx/tx register values used to enable/disable the streams. These will + * be used later in fsl_ssi_config to setup the streams without the need to + * check for all different SSI modes. + */ +static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private) +{ + struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val; + + reg->rx.sier = CCSR_SSI_SIER_RFF0_EN; + reg->rx.srcr = CCSR_SSI_SRCR_RFEN0; + reg->rx.scr = 0; + reg->tx.sier = CCSR_SSI_SIER_TFE0_EN; + reg->tx.stcr = CCSR_SSI_STCR_TFEN0; + reg->tx.scr = 0; + + if (!ssi_private->imx_ac97) { + reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE; + reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN; + reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE; + reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN; + } + + if (ssi_private->use_dma) { + reg->rx.sier |= CCSR_SSI_SIER_RDMAE; + reg->tx.sier |= CCSR_SSI_SIER_TDMAE; + } else { + reg->rx.sier |= CCSR_SSI_SIER_RIE; + reg->tx.sier |= CCSR_SSI_SIER_TIE; + } + + reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS; + reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS; +} + +static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) +{ + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + + /* + * Setup the clock control register + */ + write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), + &ssi->stccr); + write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), + &ssi->srccr); + + /* + * Enable AC97 mode and startup the SSI + */ + write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV, + &ssi->sacnt); + write_ssi(0xff, &ssi->saccdis); + write_ssi(0x300, &ssi->saccen); + + /* + * Enable SSI, Transmit and Receive. AC97 has to communicate with the + * codec before a stream is started. + */ + write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN | + CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); + + write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); +} + static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) { struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - u8 i2s_mode; u8 wm; int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; + fsl_ssi_setup_reg_vals(ssi_private); + if (ssi_private->imx_ac97) - i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; + ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; else - i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; + ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; /* * Section 16.5 of the MPC8610 reference manual says that the SSI needs @@ -348,16 +669,15 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, CCSR_SSI_SCR_TFR_CLK_DIS | - i2s_mode | + ssi_private->i2s_mode | (synchronous ? CCSR_SSI_SCR_SYN : 0)); - write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | - CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | - CCSR_SSI_STCR_TSCKP, &ssi->stcr); + write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI | + CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr); + + write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI | + CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr); - write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 | - CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS | - CCSR_SSI_SRCR_RSCKP, &ssi->srcr); /* * The DC and PM bits are only used if the SSI is the clock master. */ @@ -387,30 +707,18 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) * because it is also running without an active substream. Normally SSI * is only enabled when there is a substream. */ - if (ssi_private->imx_ac97) { - /* - * Setup the clock control register - */ - write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), - &ssi->stccr); - write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), - &ssi->srccr); + if (ssi_private->imx_ac97) + fsl_ssi_setup_ac97(ssi_private); - /* - * Enable AC97 mode and startup the SSI - */ - write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV, - &ssi->sacnt); - write_ssi(0xff, &ssi->saccdis); - write_ssi(0x300, &ssi->saccen); - - /* - * Enable SSI, Transmit and Receive - */ - write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN | - CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); - - write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); + /* + * Set a default slot number so that there is no need for those common + * cases like I2S mode to call the extra set_tdm_slot() any more. + */ + if (!ssi_private->imx_ac97) { + write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(2)); + write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(2)); } return 0; @@ -431,53 +739,17 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); - int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; + unsigned long flags; - /* - * If this is the first stream opened, then request the IRQ - * and initialize the SSI registers. + /* First, we only do fsl_ssi_setup() when SSI is going to be active. + * Second, fsl_ssi_setup was already called by ac97_init earlier if + * the driver is in ac97 mode. */ - if (!ssi_private->first_stream) { - ssi_private->first_stream = substream; - - /* - * fsl_ssi_setup was already called by ac97_init earlier if - * the driver is in ac97 mode. - */ - if (!ssi_private->imx_ac97) - fsl_ssi_setup(ssi_private); - } else { - if (synchronous) { - struct snd_pcm_runtime *first_runtime = - ssi_private->first_stream->runtime; - /* - * This is the second stream open, and we're in - * synchronous mode, so we need to impose sample - * sample size constraints. This is because STCCR is - * used for playback and capture in synchronous mode, - * so there's no way to specify different word - * lengths. - * - * Note that this can cause a race condition if the - * second stream is opened before the first stream is - * fully initialized. We provide some protection by - * checking to make sure the first stream is - * initialized, but it's not perfect. ALSA sometimes - * re-initializes the driver with a different sample - * rate or size. If the second stream is opened - * before the first stream has received its final - * parameters, then the second stream may be - * constrained to the wrong sample rate or size. - */ - if (first_runtime->sample_bits) { - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - first_runtime->sample_bits, - first_runtime->sample_bits); - } - } - - ssi_private->second_stream = substream; + if (!dai->active && !ssi_private->imx_ac97) { + fsl_ssi_setup(ssi_private); + spin_lock_irqsave(&ssi_private->baudclk_lock, flags); + ssi_private->baudclk_locked = false; + spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); } return 0; @@ -501,6 +773,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + unsigned int channels = params_channels(hw_params); unsigned int sample_size = snd_pcm_format_width(params_format(hw_params)); u32 wl = CCSR_SSI_SxCCR_WL(sample_size); @@ -530,6 +803,248 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, else write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); + if (!ssi_private->imx_ac97) + write_ssi_mask(&ssi->scr, + CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, + channels == 1 ? 0 : ssi_private->i2s_mode); + + return 0; +} + +/** + * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format. + */ +static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) +{ + struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + u32 strcr = 0, stcr, srcr, scr, mask; + + scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); + scr |= CCSR_SSI_SCR_NET; + + mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | + CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | + CCSR_SSI_STCR_TEFS; + stcr = read_ssi(&ssi->stcr) & ~mask; + srcr = read_ssi(&ssi->srcr) & ~mask; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER; + break; + case SND_SOC_DAIFMT_CBM_CFM: + ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; + break; + default: + return -EINVAL; + } + scr |= ssi_private->i2s_mode; + + /* Data on rising edge of bclk, frame low, 1clk before data */ + strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | + CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS; + break; + case SND_SOC_DAIFMT_LEFT_J: + /* Data on rising edge of bclk, frame high */ + strcr |= CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TSCKP; + break; + case SND_SOC_DAIFMT_DSP_A: + /* Data on rising edge of bclk, frame high, 1clk before data */ + strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | + CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS; + break; + case SND_SOC_DAIFMT_DSP_B: + /* Data on rising edge of bclk, frame high */ + strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | + CCSR_SSI_STCR_TXBIT0; + break; + default: + return -EINVAL; + } + + /* DAI clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + /* Nothing to do for both normal cases */ + break; + case SND_SOC_DAIFMT_IB_NF: + /* Invert bit clock */ + strcr ^= CCSR_SSI_STCR_TSCKP; + break; + case SND_SOC_DAIFMT_NB_IF: + /* Invert frame clock */ + strcr ^= CCSR_SSI_STCR_TFSI; + break; + case SND_SOC_DAIFMT_IB_IF: + /* Invert both clocks */ + strcr ^= CCSR_SSI_STCR_TSCKP; + strcr ^= CCSR_SSI_STCR_TFSI; + break; + default: + return -EINVAL; + } + + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + strcr |= CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR; + scr |= CCSR_SSI_SCR_SYS_CLK_EN; + break; + case SND_SOC_DAIFMT_CBM_CFM: + scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; + break; + default: + return -EINVAL; + } + + stcr |= strcr; + srcr |= strcr; + + if (ssi_private->cpu_dai_drv.symmetric_rates) { + /* Need to clear RXDIR when using SYNC mode */ + srcr &= ~CCSR_SSI_SRCR_RXDIR; + scr |= CCSR_SSI_SCR_SYN; + } + + write_ssi(stcr, &ssi->stcr); + write_ssi(srcr, &ssi->srcr); + write_ssi(scr, &ssi->scr); + + return 0; +} + +/** + * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock + * + * Note: This function can be only called when using SSI as DAI master + * + * Quick instruction for parameters: + * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels + * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. + */ +static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; + u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; + unsigned long flags, clkrate, baudrate, tmprate; + u64 sub, savesub = 100000; + + /* Don't apply it to any non-baudclk circumstance */ + if (IS_ERR(ssi_private->baudclk)) + return -EINVAL; + + /* It should be already enough to divide clock by setting pm alone */ + psr = 0; + div2 = 0; + + factor = (div2 + 1) * (7 * psr + 1) * 2; + + for (i = 0; i < 255; i++) { + /* The bclk rate must be smaller than 1/5 sysclk rate */ + if (factor * (i + 1) < 5) + continue; + + tmprate = freq * factor * (i + 2); + clkrate = clk_round_rate(ssi_private->baudclk, tmprate); + + do_div(clkrate, factor); + afreq = (u32)clkrate / (i + 1); + + if (freq == afreq) + sub = 0; + else if (freq / afreq == 1) + sub = freq - afreq; + else if (afreq / freq == 1) + sub = afreq - freq; + else + continue; + + /* Calculate the fraction */ + sub *= 100000; + do_div(sub, freq); + + if (sub < savesub) { + baudrate = tmprate; + savesub = sub; + pm = i; + } + + /* We are lucky */ + if (savesub == 0) + break; + } + + /* No proper pm found if it is still remaining the initial value */ + if (pm == 999) { + dev_err(cpu_dai->dev, "failed to handle the required sysclk\n"); + return -EINVAL; + } + + stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) | + (psr ? CCSR_SSI_SxCCR_PSR : 0); + mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR; + + if (dir == SND_SOC_CLOCK_OUT || synchronous) + write_ssi_mask(&ssi->stccr, mask, stccr); + else + write_ssi_mask(&ssi->srccr, mask, stccr); + + spin_lock_irqsave(&ssi_private->baudclk_lock, flags); + if (!ssi_private->baudclk_locked) { + ret = clk_set_rate(ssi_private->baudclk, baudrate); + if (ret) { + spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); + dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); + return -EINVAL; + } + ssi_private->baudclk_locked = true; + } + spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); + + return 0; +} + +/** + * fsl_ssi_set_dai_tdm_slot - set TDM slot number + * + * Note: This function can be only called when using SSI as DAI master + */ +static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, + u32 rx_mask, int slots, int slot_width) +{ + struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); + struct ccsr_ssi __iomem *ssi = ssi_private->ssi; + u32 val; + + /* The slot number should be >= 2 if using Network mode or I2S mode */ + val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET); + if (val && slots < 2) { + dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n"); + return -EINVAL; + } + + write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(slots)); + write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, + CCSR_SSI_SxCCR_DC(slots)); + + /* The register SxMSKs needs SSI to provide essential clock due to + * hardware design. So we here temporarily enable SSI to set them. + */ + val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; + write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN); + + write_ssi(tx_mask, &ssi->stmsk); + write_ssi(rx_mask, &ssi->srmsk); + + write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val); + return 0; } @@ -548,77 +1063,46 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - unsigned int sier_bits; - - /* - * Enable only the interrupts and DMA requests - * that are needed for the channel. As the fiq - * is polling for this bits, we have to ensure - * that this are aligned with the preallocated - * buffers - */ - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (ssi_private->use_dma) - sier_bits = SIER_FLAGS; - else - sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN; - } else { - if (ssi_private->use_dma) - sier_bits = SIER_FLAGS; - else - sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN; - } + unsigned long flags; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - write_ssi_mask(&ssi->scr, 0, - CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); + fsl_ssi_tx_config(ssi_private, true); else - write_ssi_mask(&ssi->scr, 0, - CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); + fsl_ssi_rx_config(ssi_private, true); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); + fsl_ssi_tx_config(ssi_private, false); else - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); + fsl_ssi_rx_config(ssi_private, false); if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & - (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); + (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { + spin_lock_irqsave(&ssi_private->baudclk_lock, flags); + ssi_private->baudclk_locked = false; + spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); + } break; default: return -EINVAL; } - write_ssi(sier_bits, &ssi->sier); + if (ssi_private->imx_ac97) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor); + else + write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor); + } return 0; } -/** - * fsl_ssi_shutdown: shutdown the SSI - * - * Shutdown the SSI if there are no other substreams open. - */ -static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); - - if (ssi_private->first_stream == substream) - ssi_private->first_stream = ssi_private->second_stream; - - ssi_private->second_stream = NULL; -} - static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) { struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); @@ -634,7 +1118,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { .startup = fsl_ssi_startup, .hw_params = fsl_ssi_hw_params, - .shutdown = fsl_ssi_shutdown, + .set_fmt = fsl_ssi_set_dai_fmt, + .set_sysclk = fsl_ssi_set_dai_sysclk, + .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, .trigger = fsl_ssi_trigger, }; @@ -642,14 +1128,13 @@ static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { static struct snd_soc_dai_driver fsl_ssi_dai_template = { .probe = fsl_ssi_dai_probe, .playback = { - /* The SSI does not support monaural audio. */ - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = FSLSSI_I2S_RATES, .formats = FSLSSI_I2S_FORMATS, }, .capture = { - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = FSLSSI_I2S_RATES, .formats = FSLSSI_I2S_FORMATS, @@ -661,59 +1146,6 @@ static const struct snd_soc_component_driver fsl_ssi_component = { .name = "fsl-ssi", }; -/** - * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit. - * - * This function is called by ALSA to start, stop, pause, and resume the - * transfer of data. - */ -static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata( - rtd->cpu_dai); - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE | - CCSR_SSI_SIER_TFE0_EN); - else - write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE | - CCSR_SSI_SIER_RFF0_EN); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE | - CCSR_SSI_SIER_TFE0_EN, 0); - else - write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE | - CCSR_SSI_SIER_RFF0_EN, 0); - break; - - default: - return -EINVAL; - } - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor); - else - write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor); - - return 0; -} - -static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = { - .startup = fsl_ssi_startup, - .shutdown = fsl_ssi_shutdown, - .trigger = fsl_ssi_ac97_trigger, -}; - static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { .ac97_control = 1, .playback = { @@ -730,7 +1162,7 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { .rates = SNDRV_PCM_RATE_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &fsl_ssi_ac97_dai_ops, + .ops = &fsl_ssi_dai_ops, }; @@ -788,56 +1220,6 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = { .write = fsl_ssi_ac97_write, }; -/* Show the statistics of a flag only if its interrupt is enabled. The - * compiler will optimze this code to a no-op if the interrupt is not - * enabled. - */ -#define SIER_SHOW(flag, name) \ - do { \ - if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \ - length += sprintf(buf + length, #name "=%u\n", \ - ssi_private->stats.name); \ - } while (0) - - -/** - * fsl_sysfs_ssi_show: display SSI statistics - * - * Display the statistics for the current SSI device. To avoid confusion, - * we only show those counts that are enabled. - */ -static ssize_t fsl_sysfs_ssi_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fsl_ssi_private *ssi_private = - container_of(attr, struct fsl_ssi_private, dev_attr); - ssize_t length = 0; - - SIER_SHOW(RFRC_EN, rfrc); - SIER_SHOW(TFRC_EN, tfrc); - SIER_SHOW(CMDAU_EN, cmdau); - SIER_SHOW(CMDDU_EN, cmddu); - SIER_SHOW(RXT_EN, rxt); - SIER_SHOW(RDR1_EN, rdr1); - SIER_SHOW(RDR0_EN, rdr0); - SIER_SHOW(TDE1_EN, tde1); - SIER_SHOW(TDE0_EN, tde0); - SIER_SHOW(ROE1_EN, roe1); - SIER_SHOW(ROE0_EN, roe0); - SIER_SHOW(TUE1_EN, tue1); - SIER_SHOW(TUE0_EN, tue0); - SIER_SHOW(TFS_EN, tfs); - SIER_SHOW(RFS_EN, rfs); - SIER_SHOW(TLS_EN, tls); - SIER_SHOW(RLS_EN, rls); - SIER_SHOW(RFF1_EN, rff1); - SIER_SHOW(RFF0_EN, rff0); - SIER_SHOW(TFE1_EN, tfe1); - SIER_SHOW(TFE0_EN, tfe0); - - return length; -} - /** * Make every character in a string lower-case */ @@ -859,6 +1241,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) int ret = 0; struct device_attribute *dev_attr = NULL; struct device_node *np = pdev->dev.of_node; + const struct of_device_id *of_id; + enum fsl_ssi_type hw_type; const char *p, *sprop; const uint32_t *iprop; struct resource res; @@ -873,6 +1257,11 @@ static int fsl_ssi_probe(struct platform_device *pdev) if (!of_device_is_available(np)) return -ENODEV; + of_id = of_match_device(fsl_ssi_ids, &pdev->dev); + if (!of_id) + return -EINVAL; + hw_type = (enum fsl_ssi_type) of_id->data; + /* We only support the SSI in "I2S Slave" mode */ sprop = of_get_property(np, "fsl,mode", NULL); if (!sprop) { @@ -899,6 +1288,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); + ssi_private->hw_type = hw_type; if (ac97) { memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, @@ -935,8 +1325,11 @@ static int fsl_ssi_probe(struct platform_device *pdev) } /* Are the RX and the TX clocks locked? */ - if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) + if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) { ssi_private->cpu_dai_drv.symmetric_rates = 1; + ssi_private->cpu_dai_drv.symmetric_channels = 1; + ssi_private->cpu_dai_drv.symmetric_samplebits = 1; + } /* Determine the FIFO depth. */ iprop = of_get_property(np, "fsl,fifo-depth", NULL); @@ -946,7 +1339,37 @@ static int fsl_ssi_probe(struct platform_device *pdev) /* Older 8610 DTs didn't have the fifo-depth property */ ssi_private->fifo_depth = 8; - if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { + ssi_private->baudclk_locked = false; + spin_lock_init(&ssi_private->baudclk_lock); + + /* + * imx51 and later SoCs have a slightly different IP that allows the + * SSI configuration while the SSI unit is running. + * + * More important, it is necessary on those SoCs to configure the + * sperate TX/RX DMA bits just before starting the stream + * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi + * sends any DMA requests to the SDMA unit, otherwise it is not defined + * how the SDMA unit handles the DMA request. + * + * SDMA units are present on devices starting at imx35 but the imx35 + * reference manual states that the DMA bits should not be changed + * while the SSI unit is running (SSIEN). So we support the necessary + * online configuration of fsl-ssi starting at imx51. + */ + switch (hw_type) { + case FSL_SSI_MCP8610: + case FSL_SSI_MX21: + case FSL_SSI_MX35: + ssi_private->offline_config = true; + break; + case FSL_SSI_MX51: + ssi_private->offline_config = false; + break; + } + + if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 || + hw_type == FSL_SSI_MX35) { u32 dma_events[2]; ssi_private->ssi_on_imx = true; @@ -963,6 +1386,16 @@ static int fsl_ssi_probe(struct platform_device *pdev) goto error_irqmap; } + /* For those SLAVE implementations, we ingore non-baudclk cases + * and, instead, abandon MASTER mode that needs baud clock. + */ + ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); + if (IS_ERR(ssi_private->baudclk)) + dev_warn(&pdev->dev, "could not get baud clock: %ld\n", + PTR_ERR(ssi_private->baudclk)); + else + clk_prepare_enable(ssi_private->baudclk); + /* * We have burstsize be "fifo_depth - 2" to match the SSI * watermark setting in fsl_ssi_startup(). @@ -1001,32 +1434,25 @@ static int fsl_ssi_probe(struct platform_device *pdev) dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); - } else if (ssi_private->use_dma) { + } + + /* + * Enable interrupts only for MCP8610 and MX51. The other MXs have + * different writeable interrupt status registers. + */ + if (ssi_private->use_dma) { /* The 'name' should not have any slashes in it. */ ret = devm_request_irq(&pdev->dev, ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name, ssi_private); + ssi_private->irq_stats = true; if (ret < 0) { dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq); - goto error_irqmap; + goto error_clk; } } - /* Initialize the the device_attribute structure */ - dev_attr = &ssi_private->dev_attr; - sysfs_attr_init(&dev_attr->attr); - dev_attr->attr.name = "statistics"; - dev_attr->attr.mode = S_IRUGO; - dev_attr->show = fsl_sysfs_ssi_show; - - ret = device_create_file(&pdev->dev, dev_attr); - if (ret) { - dev_err(&pdev->dev, "could not create sysfs %s file\n", - ssi_private->dev_attr.attr.name); - goto error_clk; - } - /* Register with ASoC */ dev_set_drvdata(&pdev->dev, ssi_private); @@ -1037,6 +1463,10 @@ static int fsl_ssi_probe(struct platform_device *pdev) goto error_dev; } + ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev); + if (ret) + goto error_dbgfs; + if (ssi_private->ssi_on_imx) { if (!ssi_private->use_dma) { @@ -1056,11 +1486,11 @@ static int fsl_ssi_probe(struct platform_device *pdev) ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); if (ret) - goto error_dev; + goto error_pcm; } else { ret = imx_pcm_dma_init(pdev); if (ret) - goto error_dev; + goto error_pcm; } } @@ -1102,19 +1532,28 @@ done: return 0; error_dai: - if (ssi_private->ssi_on_imx) - imx_pcm_dma_exit(pdev); + if (ssi_private->ssi_on_imx && !ssi_private->use_dma) + imx_pcm_fiq_exit(pdev); + +error_pcm: + fsl_ssi_debugfs_remove(ssi_private); + +error_dbgfs: snd_soc_unregister_component(&pdev->dev); error_dev: device_remove_file(&pdev->dev, dev_attr); error_clk: - if (ssi_private->ssi_on_imx) + if (ssi_private->ssi_on_imx) { + if (!IS_ERR(ssi_private->baudclk)) + clk_disable_unprepare(ssi_private->baudclk); clk_disable_unprepare(ssi_private->clk); + } error_irqmap: - irq_dispose_mapping(ssi_private->irq); + if (ssi_private->irq_stats) + irq_dispose_mapping(ssi_private->irq); return ret; } @@ -1123,26 +1562,22 @@ static int fsl_ssi_remove(struct platform_device *pdev) { struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); + fsl_ssi_debugfs_remove(ssi_private); + if (!ssi_private->new_binding) platform_device_unregister(ssi_private->pdev); - if (ssi_private->ssi_on_imx) - imx_pcm_dma_exit(pdev); snd_soc_unregister_component(&pdev->dev); - device_remove_file(&pdev->dev, &ssi_private->dev_attr); - if (ssi_private->ssi_on_imx) + if (ssi_private->ssi_on_imx) { + if (!IS_ERR(ssi_private->baudclk)) + clk_disable_unprepare(ssi_private->baudclk); clk_disable_unprepare(ssi_private->clk); - irq_dispose_mapping(ssi_private->irq); + } + if (ssi_private->irq_stats) + irq_dispose_mapping(ssi_private->irq); return 0; } -static const struct of_device_id fsl_ssi_ids[] = { - { .compatible = "fsl,mpc8610-ssi", }, - { .compatible = "fsl,imx21-ssi", }, - {} -}; -MODULE_DEVICE_TABLE(of, fsl_ssi_ids); - static struct platform_driver fsl_ssi_driver = { .driver = { .name = "fsl-ssi-dai", diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index e6b9a69e2a68..e6b63240a3d7 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h @@ -125,7 +125,9 @@ struct ccsr_ssi { #define CCSR_SSI_SRCR_REFS 0x00000001 /* STCCR and SRCCR */ +#define CCSR_SSI_SxCCR_DIV2_SHIFT 18 #define CCSR_SSI_SxCCR_DIV2 0x00040000 +#define CCSR_SSI_SxCCR_PSR_SHIFT 17 #define CCSR_SSI_SxCCR_PSR 0x00020000 #define CCSR_SSI_SxCCR_WL_SHIFT 13 #define CCSR_SSI_SxCCR_WL_MASK 0x0001E000 diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index aee23077080a..2585ae44e634 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -41,9 +41,6 @@ static const struct snd_pcm_hardware imx_pcm_hardware = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 8000, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .period_bytes_min = 128, .period_bytes_max = 65535, /* Limited by SDMA engine */ @@ -61,16 +58,11 @@ static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = { int imx_pcm_dma_init(struct platform_device *pdev) { - return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config, + return devm_snd_dmaengine_pcm_register(&pdev->dev, + &imx_dmaengine_pcm_config, SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | SND_DMAENGINE_PCM_FLAG_COMPAT); } EXPORT_SYMBOL_GPL(imx_pcm_dma_init); -void imx_pcm_dma_exit(struct platform_device *pdev) -{ - snd_dmaengine_pcm_unregister(&pdev->dev); -} -EXPORT_SYMBOL_GPL(imx_pcm_dma_exit); - MODULE_LICENSE("GPL"); diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index c75d43bb2e92..6553202dd48c 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -162,9 +162,6 @@ static struct snd_pcm_hardware snd_imx_hardware = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 8000, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .period_bytes_min = 128, .period_bytes_max = 16 * 1024, diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h index 5d5b73303e11..c79cb27473be 100644 --- a/sound/soc/fsl/imx-pcm.h +++ b/sound/soc/fsl/imx-pcm.h @@ -40,16 +40,11 @@ struct imx_pcm_fiq_params { #if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA) int imx_pcm_dma_init(struct platform_device *pdev); -void imx_pcm_dma_exit(struct platform_device *pdev); #else static inline int imx_pcm_dma_init(struct platform_device *pdev) { return -ENODEV; } - -static inline void imx_pcm_dma_exit(struct platform_device *pdev) -{ -} #endif #if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ) diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c index 8499d5292f08..e1dc40143600 100644 --- a/sound/soc/fsl/imx-spdif.c +++ b/sound/soc/fsl/imx-spdif.c @@ -14,17 +14,15 @@ #include struct imx_spdif_data { - struct snd_soc_dai_link dai[2]; + struct snd_soc_dai_link dai; struct snd_soc_card card; - struct platform_device *txdev; - struct platform_device *rxdev; }; static int imx_spdif_audio_probe(struct platform_device *pdev) { struct device_node *spdif_np, *np = pdev->dev.of_node; struct imx_spdif_data *data; - int ret = 0, num_links = 0; + int ret = 0; spdif_np = of_parse_phandle(np, "spdif-controller", 0); if (!spdif_np) { @@ -35,74 +33,46 @@ static int imx_spdif_audio_probe(struct platform_device *pdev) data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { - dev_err(&pdev->dev, "failed to allocate memory\n"); ret = -ENOMEM; goto end; } - if (of_property_read_bool(np, "spdif-out")) { - data->dai[num_links].name = "S/PDIF TX"; - data->dai[num_links].stream_name = "S/PDIF PCM Playback"; - data->dai[num_links].codec_dai_name = "dit-hifi"; - data->dai[num_links].codec_name = "spdif-dit"; - data->dai[num_links].cpu_of_node = spdif_np; - data->dai[num_links].platform_of_node = spdif_np; - num_links++; + data->dai.name = "S/PDIF PCM"; + data->dai.stream_name = "S/PDIF PCM"; + data->dai.codec_dai_name = "snd-soc-dummy-dai"; + data->dai.codec_name = "snd-soc-dummy"; + data->dai.cpu_of_node = spdif_np; + data->dai.platform_of_node = spdif_np; + data->dai.playback_only = true; + data->dai.capture_only = true; - data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0); - if (IS_ERR(data->txdev)) { - ret = PTR_ERR(data->txdev); - dev_err(&pdev->dev, "register dit failed: %d\n", ret); - goto end; - } - } + if (of_property_read_bool(np, "spdif-out")) + data->dai.capture_only = false; - if (of_property_read_bool(np, "spdif-in")) { - data->dai[num_links].name = "S/PDIF RX"; - data->dai[num_links].stream_name = "S/PDIF PCM Capture"; - data->dai[num_links].codec_dai_name = "dir-hifi"; - data->dai[num_links].codec_name = "spdif-dir"; - data->dai[num_links].cpu_of_node = spdif_np; - data->dai[num_links].platform_of_node = spdif_np; - num_links++; + if (of_property_read_bool(np, "spdif-in")) + data->dai.playback_only = false; - data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0); - if (IS_ERR(data->rxdev)) { - ret = PTR_ERR(data->rxdev); - dev_err(&pdev->dev, "register dir failed: %d\n", ret); - goto error_dit; - } - } - - if (!num_links) { + if (data->dai.playback_only && data->dai.capture_only) { dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n"); - goto error_dir; + goto end; } data->card.dev = &pdev->dev; - data->card.num_links = num_links; - data->card.dai_link = data->dai; + data->card.dai_link = &data->dai; + data->card.num_links = 1; ret = snd_soc_of_parse_card_name(&data->card, "model"); if (ret) - goto error_dir; + goto end; ret = devm_snd_soc_register_card(&pdev->dev, &data->card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret); - goto error_dir; + goto end; } platform_set_drvdata(pdev, data); - goto end; - -error_dir: - if (data->rxdev) - platform_device_unregister(data->rxdev); -error_dit: - if (data->txdev) - platform_device_unregister(data->txdev); end: if (spdif_np) of_node_put(spdif_np); @@ -110,18 +80,6 @@ end: return ret; } -static int imx_spdif_audio_remove(struct platform_device *pdev) -{ - struct imx_spdif_data *data = platform_get_drvdata(pdev); - - if (data->rxdev) - platform_device_unregister(data->rxdev); - if (data->txdev) - platform_device_unregister(data->txdev); - - return 0; -} - static const struct of_device_id imx_spdif_dt_ids[] = { { .compatible = "fsl,imx-audio-spdif", }, { /* sentinel */ } @@ -135,7 +93,6 @@ static struct platform_driver imx_spdif_driver = { .of_match_table = imx_spdif_dt_ids, }, .probe = imx_spdif_audio_probe, - .remove = imx_spdif_audio_remove, }; module_platform_driver(imx_spdif_driver); diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index f5f248c91c16..df552fa1aa65 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -304,8 +304,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, scr |= SSI_SCR_RE; sier |= sier_bits; - if (++ssi->enabled == 1) - scr |= SSI_SCR_SSIEN; + scr |= SSI_SCR_SSIEN; break; @@ -318,7 +317,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, scr &= ~SSI_SCR_RE; sier &= ~sier_bits; - if (--ssi->enabled == 0) + if (!(scr & (SSI_SCR_TE | SSI_SCR_RE))) scr &= ~SSI_SCR_SSIEN; break; @@ -536,7 +535,9 @@ static int imx_ssi_probe(struct platform_device *pdev) ret); goto failed_clk; } - clk_prepare_enable(ssi->clk); + ret = clk_prepare_enable(ssi->clk); + if (ret) + goto failed_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ssi->base = devm_ioremap_resource(&pdev->dev, res); @@ -624,9 +625,6 @@ static int imx_ssi_remove(struct platform_device *pdev) { struct imx_ssi *ssi = platform_get_drvdata(pdev); - if (!ssi->dma_init) - imx_pcm_dma_exit(pdev); - if (!ssi->fiq_init) imx_pcm_fiq_exit(pdev); diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h index 560c40fc9ebb..be6562365b6a 100644 --- a/sound/soc/fsl/imx-ssi.h +++ b/sound/soc/fsl/imx-ssi.h @@ -213,7 +213,6 @@ struct imx_ssi { int fiq_init; int dma_init; - int enabled; }; #endif /* _IMX_SSI_H */ diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 71bf2f248cd4..f2b5d756b1f3 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -200,10 +200,6 @@ static const struct snd_pcm_hardware psc_dma_hardware = { SNDRV_PCM_INFO_BATCH, .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, .period_bytes_max = 1024 * 1024, .period_bytes_min = 32, .periods_min = 2, diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index f4efaadb80a2..5d07e8a74a21 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -26,8 +26,7 @@ * ALSA that we support all rates and let the codec driver decide what rates * are really supported. */ -#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ - SNDRV_PCM_RATE_CONTINUOUS) +#define PSC_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS /** * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index b2fbb7075a6c..2a1b1b5b5221 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -8,14 +8,13 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - -#include +#include #include +#include +#include +#include #include -#define asoc_simple_get_card_info(p) \ - container_of(p->dai_link, struct asoc_simple_card_info, snd_link) - static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, struct asoc_simple_dai *set, unsigned int daifmt) @@ -24,7 +23,7 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, daifmt |= set->fmt; - if (!ret && daifmt) + if (daifmt) ret = snd_soc_dai_set_fmt(dai, daifmt); if (ret == -ENOTSUPP) { @@ -40,7 +39,8 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) { - struct asoc_simple_card_info *info = asoc_simple_get_card_info(rtd); + struct asoc_simple_card_info *info = + snd_soc_card_get_drvdata(rtd->card); struct snd_soc_dai *codec = rtd->codec_dai; struct snd_soc_dai *cpu = rtd->cpu_dai; unsigned int daifmt = info->daifmt; @@ -57,22 +57,182 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int +asoc_simple_card_sub_parse_of(struct device_node *np, + struct asoc_simple_dai *dai, + struct device_node **node) +{ + struct clk *clk; + int ret; + + /* + * get node via "sound-dai = <&phandle port>" + * it will be used as xxx_of_node on soc_bind_dai_link() + */ + *node = of_parse_phandle(np, "sound-dai", 0); + if (!*node) + return -ENODEV; + + /* get dai->name */ + ret = snd_soc_of_get_dai_name(np, &dai->name); + if (ret < 0) + goto parse_error; + + /* + * bitclock-inversion, frame-inversion + * bitclock-master, frame-master + * and specific "format" if it has + */ + dai->fmt = snd_soc_of_parse_daifmt(np, NULL); + + /* + * dai->sysclk come from + * "clocks = <&xxx>" (if system has common clock) + * or "system-clock-frequency = " + * or device's module clock. + */ + if (of_property_read_bool(np, "clocks")) { + clk = of_clk_get(np, 0); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto parse_error; + } + + dai->sysclk = clk_get_rate(clk); + } else if (of_property_read_bool(np, "system-clock-frequency")) { + of_property_read_u32(np, + "system-clock-frequency", + &dai->sysclk); + } else { + clk = of_clk_get(*node, 0); + if (!IS_ERR(clk)) + dai->sysclk = clk_get_rate(clk); + } + + ret = 0; + +parse_error: + of_node_put(*node); + + return ret; +} + +static int asoc_simple_card_parse_of(struct device_node *node, + struct asoc_simple_card_info *info, + struct device *dev, + struct device_node **of_cpu, + struct device_node **of_codec, + struct device_node **of_platform) +{ + struct device_node *np; + char *name; + int ret; + + /* get CPU/CODEC common format via simple-audio-card,format */ + info->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & + (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); + + /* DAPM routes */ + if (of_property_read_bool(node, "simple-audio-card,routing")) { + ret = snd_soc_of_parse_audio_routing(&info->snd_card, + "simple-audio-card,routing"); + if (ret) + return ret; + } + + /* CPU sub-node */ + ret = -EINVAL; + np = of_get_child_by_name(node, "simple-audio-card,cpu"); + if (np) + ret = asoc_simple_card_sub_parse_of(np, + &info->cpu_dai, + of_cpu); + if (ret < 0) + return ret; + + /* CODEC sub-node */ + ret = -EINVAL; + np = of_get_child_by_name(node, "simple-audio-card,codec"); + if (np) + ret = asoc_simple_card_sub_parse_of(np, + &info->codec_dai, + of_codec); + if (ret < 0) + return ret; + + if (!info->cpu_dai.name || !info->codec_dai.name) + return -EINVAL; + + /* card name is created from CPU/CODEC dai name */ + name = devm_kzalloc(dev, + strlen(info->cpu_dai.name) + + strlen(info->codec_dai.name) + 2, + GFP_KERNEL); + sprintf(name, "%s-%s", info->cpu_dai.name, info->codec_dai.name); + info->name = info->card = name; + + /* simple-card assumes platform == cpu */ + *of_platform = *of_cpu; + + dev_dbg(dev, "card-name : %s\n", info->card); + dev_dbg(dev, "platform : %04x\n", info->daifmt); + dev_dbg(dev, "cpu : %s / %04x / %d\n", + info->cpu_dai.name, + info->cpu_dai.fmt, + info->cpu_dai.sysclk); + dev_dbg(dev, "codec : %s / %04x / %d\n", + info->codec_dai.name, + info->codec_dai.fmt, + info->codec_dai.sysclk); + + return 0; +} + static int asoc_simple_card_probe(struct platform_device *pdev) { - struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; + struct asoc_simple_card_info *cinfo; + struct device_node *np = pdev->dev.of_node; + struct device_node *of_cpu, *of_codec, *of_platform; struct device *dev = &pdev->dev; + int ret; - if (!cinfo) { - dev_err(dev, "no info for asoc-simple-card\n"); - return -EINVAL; + cinfo = NULL; + of_cpu = NULL; + of_codec = NULL; + of_platform = NULL; + + cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL); + if (!cinfo) + return -ENOMEM; + + if (np && of_device_is_available(np)) { + cinfo->snd_card.dev = dev; + + ret = asoc_simple_card_parse_of(np, cinfo, dev, + &of_cpu, + &of_codec, + &of_platform); + if (ret < 0) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "parse error %d\n", ret); + return ret; + } + } else { + if (!dev->platform_data) { + dev_err(dev, "no info for asoc-simple-card\n"); + return -EINVAL; + } + + memcpy(cinfo, dev->platform_data, sizeof(*cinfo)); + cinfo->snd_card.dev = dev; } if (!cinfo->name || !cinfo->card || - !cinfo->codec || - !cinfo->platform || - !cinfo->cpu_dai.name || - !cinfo->codec_dai.name) { + !cinfo->codec_dai.name || + !(cinfo->codec || of_codec) || + !(cinfo->platform || of_platform) || + !(cinfo->cpu_dai.name || of_cpu)) { dev_err(dev, "insufficient asoc_simple_card_info settings\n"); return -EINVAL; } @@ -86,6 +246,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev) cinfo->snd_link.platform_name = cinfo->platform; cinfo->snd_link.codec_name = cinfo->codec; cinfo->snd_link.codec_dai_name = cinfo->codec_dai.name; + cinfo->snd_link.cpu_of_node = of_cpu; + cinfo->snd_link.codec_of_node = of_codec; + cinfo->snd_link.platform_of_node = of_platform; cinfo->snd_link.init = asoc_simple_card_dai_init; /* @@ -95,25 +258,25 @@ static int asoc_simple_card_probe(struct platform_device *pdev) cinfo->snd_card.owner = THIS_MODULE; cinfo->snd_card.dai_link = &cinfo->snd_link; cinfo->snd_card.num_links = 1; - cinfo->snd_card.dev = &pdev->dev; - return snd_soc_register_card(&cinfo->snd_card); + snd_soc_card_set_drvdata(&cinfo->snd_card, cinfo); + + return devm_snd_soc_register_card(&pdev->dev, &cinfo->snd_card); } -static int asoc_simple_card_remove(struct platform_device *pdev) -{ - struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; - - return snd_soc_unregister_card(&cinfo->snd_card); -} +static const struct of_device_id asoc_simple_of_match[] = { + { .compatible = "simple-audio-card", }, + {}, +}; +MODULE_DEVICE_TABLE(of, asoc_simple_of_match); static struct platform_driver asoc_simple_card = { .driver = { .name = "asoc-simple-card", .owner = THIS_MODULE, + .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, - .remove = asoc_simple_card_remove, }; module_platform_driver(asoc_simple_card); diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/intel/Kconfig similarity index 100% rename from sound/soc/mid-x86/Kconfig rename to sound/soc/intel/Kconfig diff --git a/sound/soc/mid-x86/Makefile b/sound/soc/intel/Makefile similarity index 100% rename from sound/soc/mid-x86/Makefile rename to sound/soc/intel/Makefile diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/intel/mfld_machine.c similarity index 100% rename from sound/soc/mid-x86/mfld_machine.c rename to sound/soc/intel/mfld_machine.c diff --git a/sound/soc/mid-x86/sst_dsp.h b/sound/soc/intel/sst_dsp.h similarity index 100% rename from sound/soc/mid-x86/sst_dsp.h rename to sound/soc/intel/sst_dsp.h diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/intel/sst_platform.c similarity index 98% rename from sound/soc/mid-x86/sst_platform.c rename to sound/soc/intel/sst_platform.c index b6b5eb698d33..f465a8180863 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/intel/sst_platform.c @@ -89,16 +89,6 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_U16 | - SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_U24 | - SNDRV_PCM_FMTBIT_S32 | SNDRV_PCM_FMTBIT_U32), - .rates = (SNDRV_PCM_RATE_8000| - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000), - .rate_min = SST_MIN_RATE, - .rate_max = SST_MAX_RATE, - .channels_min = SST_MIN_CHANNEL, - .channels_max = SST_MAX_CHANNEL, .buffer_bytes_max = SST_MAX_BUFFER, .period_bytes_min = SST_MIN_PERIOD_BYTES, .period_bytes_max = SST_MAX_PERIOD_BYTES, diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/intel/sst_platform.h similarity index 97% rename from sound/soc/mid-x86/sst_platform.h rename to sound/soc/intel/sst_platform.h index cacc9066ec52..bee64fb7d2ef 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/intel/sst_platform.h @@ -33,10 +33,6 @@ #define SST_STEREO 2 #define SST_MAX_CAP 5 -#define SST_MIN_RATE 8000 -#define SST_MAX_RATE 48000 -#define SST_MIN_CHANNEL 1 -#define SST_MAX_CHANNEL 5 #define SST_MAX_BUFFER (800*1024) #define SST_MIN_BUFFER (800*1024) #define SST_MIN_PERIOD_BYTES 32 diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig index 5351cba66c9e..29f76af5d963 100644 --- a/sound/soc/jz4740/Kconfig +++ b/sound/soc/jz4740/Kconfig @@ -1,6 +1,7 @@ config SND_JZ4740_SOC tristate "SoC Audio for Ingenic JZ4740 SoC" depends on MACH_JZ4740 && SND_SOC + select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the JZ4740 I2S interface. You will also need to select the audio diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 4c849a49c72a..8f220009e0f6 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -29,9 +29,11 @@ #include #include #include +#include + +#include #include "jz4740-i2s.h" -#include "jz4740-pcm.h" #define JZ_REG_AIC_CONF 0x00 #define JZ_REG_AIC_CTRL 0x04 @@ -89,8 +91,8 @@ struct jz4740_i2s { struct clk *clk_aic; struct clk *clk_i2s; - struct jz4740_pcm_config pcm_config_playback; - struct jz4740_pcm_config pcm_config_capture; + struct snd_dmaengine_dai_dma_data playback_dma_data; + struct snd_dmaengine_dai_dma_data capture_dma_data; }; static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, @@ -233,8 +235,6 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); - enum jz4740_dma_width dma_width; - struct jz4740_pcm_config *pcm_config; unsigned int sample_size; uint32_t ctrl; @@ -243,11 +243,9 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: sample_size = 0; - dma_width = JZ4740_DMA_WIDTH_8BIT; break; case SNDRV_PCM_FORMAT_S16: sample_size = 1; - dma_width = JZ4740_DMA_WIDTH_16BIT; break; default: return -EINVAL; @@ -260,22 +258,13 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream, ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO; else ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO; - - pcm_config = &i2s->pcm_config_playback; - pcm_config->dma_config.dst_width = dma_width; - } else { ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; - - pcm_config = &i2s->pcm_config_capture; - pcm_config->dma_config.src_width = dma_width; } jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); - snd_soc_dai_set_dma_data(dai, substream, pcm_config); - return 0; } @@ -342,25 +331,19 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai) static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s) { - struct jz4740_dma_config *dma_config; + struct snd_dmaengine_dai_dma_data *dma_data; /* Playback */ - dma_config = &i2s->pcm_config_playback.dma_config; - dma_config->src_width = JZ4740_DMA_WIDTH_32BIT; - dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; - dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT; - dma_config->flags = JZ4740_DMA_SRC_AUTOINC; - dma_config->mode = JZ4740_DMA_MODE_SINGLE; - i2s->pcm_config_playback.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO; + dma_data = &i2s->playback_dma_data; + dma_data->maxburst = 16; + dma_data->slave_id = JZ4740_DMA_TYPE_AIC_TRANSMIT; + dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO; /* Capture */ - dma_config = &i2s->pcm_config_capture.dma_config; - dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT; - dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; - dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE; - dma_config->flags = JZ4740_DMA_DST_AUTOINC; - dma_config->mode = JZ4740_DMA_MODE_SINGLE; - i2s->pcm_config_capture.fifo_addr = i2s->phys_base + JZ_REG_AIC_FIFO; + dma_data = &i2s->capture_dma_data; + dma_data->maxburst = 16; + dma_data->slave_id = JZ4740_DMA_TYPE_AIC_RECEIVE; + dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO; } static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) @@ -371,6 +354,8 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) clk_prepare_enable(i2s->clk_aic); jz4740_i2c_init_pcm_config(i2s); + snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, + &i2s->capture_dma_data); conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | @@ -432,91 +417,41 @@ static const struct snd_soc_component_driver jz4740_i2s_component = { static int jz4740_i2s_dev_probe(struct platform_device *pdev) { struct jz4740_i2s *i2s; + struct resource *mem; int ret; - i2s = kzalloc(sizeof(*i2s), GFP_KERNEL); - + i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); if (!i2s) return -ENOMEM; - i2s->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!i2s->mem) { - ret = -ENOENT; - goto err_free; - } + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + i2s->base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(i2s->base)) + return PTR_ERR(i2s->base); - i2s->mem = request_mem_region(i2s->mem->start, resource_size(i2s->mem), - pdev->name); - if (!i2s->mem) { - ret = -EBUSY; - goto err_free; - } + i2s->phys_base = mem->start; - i2s->base = ioremap_nocache(i2s->mem->start, resource_size(i2s->mem)); - if (!i2s->base) { - ret = -EBUSY; - goto err_release_mem_region; - } + i2s->clk_aic = devm_clk_get(&pdev->dev, "aic"); + if (IS_ERR(i2s->clk_aic)) + return PTR_ERR(i2s->clk_aic); - i2s->phys_base = i2s->mem->start; - - i2s->clk_aic = clk_get(&pdev->dev, "aic"); - if (IS_ERR(i2s->clk_aic)) { - ret = PTR_ERR(i2s->clk_aic); - goto err_iounmap; - } - - i2s->clk_i2s = clk_get(&pdev->dev, "i2s"); - if (IS_ERR(i2s->clk_i2s)) { - ret = PTR_ERR(i2s->clk_i2s); - goto err_clk_put_aic; - } + i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s"); + if (IS_ERR(i2s->clk_i2s)) + return PTR_ERR(i2s->clk_i2s); platform_set_drvdata(pdev, i2s); - ret = snd_soc_register_component(&pdev->dev, &jz4740_i2s_component, - &jz4740_i2s_dai, 1); - if (ret) { - dev_err(&pdev->dev, "Failed to register DAI\n"); - goto err_clk_put_i2s; - } + ret = devm_snd_soc_register_component(&pdev->dev, + &jz4740_i2s_component, &jz4740_i2s_dai, 1); + if (ret) + return ret; - return 0; - -err_clk_put_i2s: - clk_put(i2s->clk_i2s); -err_clk_put_aic: - clk_put(i2s->clk_aic); -err_iounmap: - iounmap(i2s->base); -err_release_mem_region: - release_mem_region(i2s->mem->start, resource_size(i2s->mem)); -err_free: - kfree(i2s); - - return ret; -} - -static int jz4740_i2s_dev_remove(struct platform_device *pdev) -{ - struct jz4740_i2s *i2s = platform_get_drvdata(pdev); - - snd_soc_unregister_component(&pdev->dev); - - clk_put(i2s->clk_i2s); - clk_put(i2s->clk_aic); - - iounmap(i2s->base); - release_mem_region(i2s->mem->start, resource_size(i2s->mem)); - - kfree(i2s); - - return 0; + return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, + SND_DMAENGINE_PCM_FLAG_COMPAT); } static struct platform_driver jz4740_i2s_driver = { .probe = jz4740_i2s_dev_probe, - .remove = jz4740_i2s_dev_remove, .driver = { .name = "jz4740-i2s", .owner = THIS_MODULE, diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c deleted file mode 100644 index 1d7ef28585e1..000000000000 --- a/sound/soc/jz4740/jz4740-pcm.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include "jz4740-pcm.h" - -struct jz4740_runtime_data { - unsigned long dma_period; - dma_addr_t dma_start; - dma_addr_t dma_pos; - dma_addr_t dma_end; - - struct jz4740_dma_chan *dma; - - dma_addr_t fifo_addr; -}; - -/* identify hardware playback capabilities */ -static const struct snd_pcm_hardware jz4740_pcm_hardware = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER, - .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, - - .rates = SNDRV_PCM_RATE_8000_48000, - .channels_min = 1, - .channels_max = 2, - .period_bytes_min = 16, - .period_bytes_max = 2 * PAGE_SIZE, - .periods_min = 2, - .periods_max = 128, - .buffer_bytes_max = 128 * 2 * PAGE_SIZE, - .fifo_size = 32, -}; - -static void jz4740_pcm_start_transfer(struct jz4740_runtime_data *prtd, - struct snd_pcm_substream *substream) -{ - unsigned long count; - - if (prtd->dma_pos == prtd->dma_end) - prtd->dma_pos = prtd->dma_start; - - if (prtd->dma_pos + prtd->dma_period > prtd->dma_end) - count = prtd->dma_end - prtd->dma_pos; - else - count = prtd->dma_period; - - jz4740_dma_disable(prtd->dma); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - jz4740_dma_set_src_addr(prtd->dma, prtd->dma_pos); - jz4740_dma_set_dst_addr(prtd->dma, prtd->fifo_addr); - } else { - jz4740_dma_set_src_addr(prtd->dma, prtd->fifo_addr); - jz4740_dma_set_dst_addr(prtd->dma, prtd->dma_pos); - } - - jz4740_dma_set_transfer_count(prtd->dma, count); - - prtd->dma_pos += count; - - jz4740_dma_enable(prtd->dma); -} - -static void jz4740_pcm_dma_transfer_done(struct jz4740_dma_chan *dma, int err, - void *dev_id) -{ - struct snd_pcm_substream *substream = dev_id; - struct snd_pcm_runtime *runtime = substream->runtime; - struct jz4740_runtime_data *prtd = runtime->private_data; - - snd_pcm_period_elapsed(substream); - - jz4740_pcm_start_transfer(prtd, substream); -} - -static int jz4740_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct jz4740_runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct jz4740_pcm_config *config; - - config = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - if (!config) - return 0; - - if (!prtd->dma) { - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - prtd->dma = jz4740_dma_request(substream, "PCM Capture"); - else - prtd->dma = jz4740_dma_request(substream, "PCM Playback"); - } - - if (!prtd->dma) - return -EBUSY; - - jz4740_dma_configure(prtd->dma, &config->dma_config); - prtd->fifo_addr = config->fifo_addr; - - jz4740_dma_set_complete_cb(prtd->dma, jz4740_pcm_dma_transfer_done); - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - runtime->dma_bytes = params_buffer_bytes(params); - - prtd->dma_period = params_period_bytes(params); - prtd->dma_start = runtime->dma_addr; - prtd->dma_pos = prtd->dma_start; - prtd->dma_end = prtd->dma_start + runtime->dma_bytes; - - return 0; -} - -static int jz4740_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct jz4740_runtime_data *prtd = substream->runtime->private_data; - - snd_pcm_set_runtime_buffer(substream, NULL); - if (prtd->dma) { - jz4740_dma_free(prtd->dma); - prtd->dma = NULL; - } - - return 0; -} - -static int jz4740_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct jz4740_runtime_data *prtd = substream->runtime->private_data; - - if (!prtd->dma) - return -EBUSY; - - prtd->dma_pos = prtd->dma_start; - - return 0; -} - -static int jz4740_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct jz4740_runtime_data *prtd = runtime->private_data; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - jz4740_pcm_start_transfer(prtd, substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - jz4740_dma_disable(prtd->dma); - break; - default: - break; - } - - return 0; -} - -static snd_pcm_uframes_t jz4740_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct jz4740_runtime_data *prtd = runtime->private_data; - unsigned long byte_offset; - snd_pcm_uframes_t offset; - struct jz4740_dma_chan *dma = prtd->dma; - - /* prtd->dma_pos points to the end of the current transfer. So by - * subtracting prdt->dma_start we get the offset to the end of the - * current period in bytes. By subtracting the residue of the transfer - * we get the current offset in bytes. */ - byte_offset = prtd->dma_pos - prtd->dma_start; - byte_offset -= jz4740_dma_get_residue(dma); - - offset = bytes_to_frames(runtime, byte_offset); - if (offset >= runtime->buffer_size) - offset = 0; - - return offset; -} - -static int jz4740_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct jz4740_runtime_data *prtd; - - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); - if (prtd == NULL) - return -ENOMEM; - - snd_soc_set_runtime_hwparams(substream, &jz4740_pcm_hardware); - - runtime->private_data = prtd; - - return 0; -} - -static int jz4740_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct jz4740_runtime_data *prtd = runtime->private_data; - - kfree(prtd); - - return 0; -} - -static int jz4740_pcm_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - return remap_pfn_range(vma, vma->vm_start, - substream->dma_buffer.addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot); -} - -static struct snd_pcm_ops jz4740_pcm_ops = { - .open = jz4740_pcm_open, - .close = jz4740_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = jz4740_pcm_hw_params, - .hw_free = jz4740_pcm_hw_free, - .prepare = jz4740_pcm_prepare, - .trigger = jz4740_pcm_trigger, - .pointer = jz4740_pcm_pointer, - .mmap = jz4740_pcm_mmap, -}; - -static int jz4740_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = jz4740_pcm_hardware.buffer_bytes_max; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - - buf->area = dma_alloc_noncoherent(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - - buf->bytes = size; - - return 0; -} - -static void jz4740_pcm_free(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - for (stream = 0; stream < SNDRV_PCM_STREAM_LAST; ++stream) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_noncoherent(pcm->card->dev, buf->bytes, buf->area, - buf->addr); - buf->area = NULL; - } -} - -static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - int ret; - - ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { - ret = jz4740_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto err; - } - - if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { - ret = jz4740_pcm_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto err; - } - -err: - return ret; -} - -static struct snd_soc_platform_driver jz4740_soc_platform = { - .ops = &jz4740_pcm_ops, - .pcm_new = jz4740_pcm_new, - .pcm_free = jz4740_pcm_free, -}; - -static int jz4740_pcm_probe(struct platform_device *pdev) -{ - return snd_soc_register_platform(&pdev->dev, &jz4740_soc_platform); -} - -static int jz4740_pcm_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver jz4740_pcm_driver = { - .probe = jz4740_pcm_probe, - .remove = jz4740_pcm_remove, - .driver = { - .name = "jz4740-pcm-audio", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(jz4740_pcm_driver); - -MODULE_AUTHOR("Lars-Peter Clausen "); -MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/jz4740/jz4740-pcm.h b/sound/soc/jz4740/jz4740-pcm.h deleted file mode 100644 index 1220cbb4382c..000000000000 --- a/sound/soc/jz4740/jz4740-pcm.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _JZ4740_PCM_H -#define _JZ4740_PCM_H - -#include -#include - - -struct jz4740_pcm_config { - struct jz4740_dma_config dma_config; - phys_addr_t fifo_addr; -}; - -#endif diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 55fd6b5df55f..82b5f37cd2c7 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -73,7 +73,7 @@ static struct snd_soc_dai_link qi_lb60_dai = { .name = "jz4740", .stream_name = "jz4740", .cpu_dai_name = "jz4740-i2s", - .platform_name = "jz4740-pcm-audio", + .platform_name = "jz4740-i2s", .codec_dai_name = "jz4740-hifi", .codec_name = "jz4740-codec", .init = qi_lb60_codec_init, diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index 4af1936cf0f4..aac22fccdcdc 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -21,16 +21,6 @@ #include #include "kirkwood.h" -#define KIRKWOOD_RATES \ - (SNDRV_PCM_RATE_8000_192000 | \ - SNDRV_PCM_RATE_CONTINUOUS | \ - SNDRV_PCM_RATE_KNOT) - -#define KIRKWOOD_FORMATS \ - (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) { struct snd_soc_pcm_runtime *soc_runtime = subs->private_data; @@ -43,12 +33,6 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE), - .formats = KIRKWOOD_FORMATS, - .rates = KIRKWOOD_RATES, - .rate_min = 8000, - .rate_max = 384000, - .channels_min = 1, - .channels_max = 8, .buffer_bytes_max = KIRKWOOD_SND_MAX_BUFFER_BYTES, .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index b16abbbf7764..a371b4f91c53 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -36,11 +36,6 @@ static const struct snd_pcm_hardware snd_mxs_hardware = { SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_HALF_DUPLEX, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S20_3LE | - SNDRV_PCM_FMTBIT_S24_LE, - .channels_min = 2, - .channels_max = 2, .period_bytes_min = 32, .period_bytes_max = 8192, .periods_min = 1, @@ -56,16 +51,9 @@ static const struct snd_dmaengine_pcm_config mxs_dmaengine_pcm_config = { int mxs_pcm_platform_register(struct device *dev) { - return snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + return devm_snd_dmaengine_pcm_register(dev, &mxs_dmaengine_pcm_config, SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX); } EXPORT_SYMBOL_GPL(mxs_pcm_platform_register); -void mxs_pcm_platform_unregister(struct device *dev) -{ - snd_dmaengine_pcm_unregister(dev); -} -EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister); - MODULE_LICENSE("GPL"); diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h index bc685b67cac7..035ea0436ca5 100644 --- a/sound/soc/mxs/mxs-pcm.h +++ b/sound/soc/mxs/mxs-pcm.h @@ -20,6 +20,5 @@ #define _MXS_PCM_H int mxs_pcm_platform_register(struct device *dev); -void mxs_pcm_platform_unregister(struct device *dev); #endif diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 54e622acac33..231d7e7b0711 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -50,9 +50,9 @@ static struct mxs_saif *mxs_saif[2]; * This also means that both SAIFs must operate at the same sample rate. * * We abstract this as each saif has a master, the master could be - * himself or other saifs. In the generic saif driver, saif does not need - * to know the different clkmux. Saif only needs to know who is his master - * and operating his master to generate the proper clock rate for him. + * itself or other saifs. In the generic saif driver, saif does not need + * to know the different clkmux. Saif only needs to know who is its master + * and operating its master to generate the proper clock rate for it. * The master id is provided in mach-specific layer according to different * clkmux setting. */ @@ -76,7 +76,7 @@ static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai, * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK * is provided by other SAIF, we provide a interface here to get its master * from its master_id. - * Note that the master could be himself. + * Note that the master could be itself. */ static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif) { @@ -516,7 +516,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, } /* - * If the saif's master is not himself, we also need to enable + * If the saif's master is not itself, we also need to enable * itself clk for its internal basic logic to work. */ if (saif != master_saif) { @@ -804,13 +804,6 @@ static int mxs_saif_probe(struct platform_device *pdev) return 0; } -static int mxs_saif_remove(struct platform_device *pdev) -{ - mxs_pcm_platform_unregister(&pdev->dev); - - return 0; -} - static const struct of_device_id mxs_saif_dt_ids[] = { { .compatible = "fsl,imx28-saif", }, { /* sentinel */ } @@ -819,7 +812,6 @@ MODULE_DEVICE_TABLE(of, mxs_saif_dt_ids); static struct platform_driver mxs_saif_driver = { .probe = mxs_saif_probe, - .remove = mxs_saif_remove, .driver = { .name = "mxs-saif", diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index f588ee45b4fd..f434ed79d1b6 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c @@ -32,9 +32,6 @@ static const struct snd_pcm_hardware nuc900_pcm_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 1, - .channels_max = 2, .buffer_bytes_max = 4*1024, .period_bytes_min = 1*1024, .period_bytes_max = 4*1024, diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 83433fdea32a..86c75384c3c8 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -36,10 +36,10 @@ static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) if (mcbsp->pdata->reg_size == 2) { ((u16 *)mcbsp->reg_cache)[reg] = (u16)val; - __raw_writew((u16)val, addr); + writew_relaxed((u16)val, addr); } else { ((u32 *)mcbsp->reg_cache)[reg] = val; - __raw_writel(val, addr); + writel_relaxed(val, addr); } } @@ -48,22 +48,22 @@ static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache) void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step; if (mcbsp->pdata->reg_size == 2) { - return !from_cache ? __raw_readw(addr) : + return !from_cache ? readw_relaxed(addr) : ((u16 *)mcbsp->reg_cache)[reg]; } else { - return !from_cache ? __raw_readl(addr) : + return !from_cache ? readl_relaxed(addr) : ((u32 *)mcbsp->reg_cache)[reg]; } } static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) { - __raw_writel(val, mcbsp->st_data->io_base_st + reg); + writel_relaxed(val, mcbsp->st_data->io_base_st + reg); } static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg) { - return __raw_readl(mcbsp->st_data->io_base_st + reg); + return readl_relaxed(mcbsp->st_data->io_base_st + reg); } #define MCBSP_READ(mcbsp, reg) \ diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 12e566be3793..1bd531d718f9 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -61,12 +61,12 @@ struct omap_dmic { static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) { - __raw_writel(val, dmic->io_base + reg); + writel_relaxed(val, dmic->io_base + reg); } static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg) { - return __raw_readl(dmic->io_base + reg); + return readl_relaxed(dmic->io_base + reg); } static inline void omap_dmic_start(struct omap_dmic *dmic) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index cd9ee167959d..2f5b1536477e 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -74,12 +74,12 @@ struct omap_mcpdm { static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val) { - __raw_writel(val, mcpdm->io_base + reg); + writel_relaxed(val, mcpdm->io_base + reg); } static inline int omap_mcpdm_read(struct omap_mcpdm *mcpdm, u16 reg) { - return __raw_readl(mcpdm->io_base + reg); + return readl_relaxed(mcpdm->io_base + reg); } #ifdef DEBUG diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index b8fa9862e54c..07b8b7bc9d20 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -45,8 +45,6 @@ static const struct snd_pcm_hardware omap_pcm_hardware = { SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S32_LE, .period_bytes_min = 32, .period_bytes_max = 64 * 1024, .periods_min = 2, diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 4db74a083db1..6473052b6899 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -11,7 +11,7 @@ config SND_PXA2XX_SOC config SND_MMP_SOC bool "Soc Audio for Marvell MMP chips" depends on ARCH_MMP - select SND_DMAENGINE_PCM + select SND_SOC_GENERIC_DMAENGINE_PCM select SND_ARM help Say Y if you want to add support for codecs attached to diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 7929e19b0ef5..5e8d81330173 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -36,14 +36,9 @@ struct mmp_dma_data { SNDRV_PCM_INFO_PAUSE | \ SNDRV_PCM_INFO_RESUME) -#define MMP_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - static struct snd_pcm_hardware mmp_pcm_hardware[] = { { .info = MMP_PCM_INFO, - .formats = MMP_PCM_FORMATS, .period_bytes_min = 1024, .period_bytes_max = 2048, .periods_min = 2, @@ -53,7 +48,6 @@ static struct snd_pcm_hardware mmp_pcm_hardware[] = { }, { .info = MMP_PCM_INFO, - .formats = MMP_PCM_FORMATS, .period_bytes_min = 1024, .period_bytes_max = 2048, .periods_min = 2, @@ -67,27 +61,15 @@ static int mmp_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_dmaengine_dai_dma_data *dma_params; struct dma_slave_config slave_config; int ret; - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - if (!dma_params) - return 0; - - ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); + ret = + snd_dmaengine_pcm_prepare_slave_config(substream, params, + &slave_config); if (ret) return ret; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - slave_config.dst_addr = dma_params->addr; - slave_config.dst_maxburst = 4; - } else { - slave_config.src_addr = dma_params->addr; - slave_config.src_maxburst = 4; - } - ret = dmaengine_slave_config(chan, &slave_config); if (ret) return ret; diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index 73bb99f0109a..7eba7979b9af 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -405,8 +405,7 @@ static int s6000_i2s_dai_probe(struct snd_soc_dai *dai) return 0; } -#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ - SNDRV_PCM_RATE_8000_192000) +#define S6000_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS #define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops s6000_i2s_dai_ops = { diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index d219880815c0..fb8461e1b1f6 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -33,13 +33,6 @@ static struct snd_pcm_hardware s6000_pcm_hardware = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX), - .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE), - .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ - SNDRV_PCM_RATE_8000_192000), - .rate_min = 0, - .rate_max = 1562500, - .channels_min = 2, - .channels_max = 8, .buffer_bytes_max = 0x7ffffff0, .period_bytes_min = 16, .period_bytes_max = 0xfffff0, diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 37459dfd168d..27930fc432dc 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,13 +1,22 @@ config SND_SOC_SAMSUNG tristate "ASoC support for Samsung" depends on PLAT_SAMSUNG - select S3C64XX_DMA if ARCH_S3C64XX - select S3C24XX_DMA if ARCH_S3C24XX + select S3C2410_DMA if ARCH_S3C24XX + select S3C64XX_PL080 if ARCH_S3C64XX + select SND_S3C_DMA if !ARCH_S3C24XX + select SND_S3C_DMA_LEGACY if ARCH_S3C24XX + select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX help Say Y or M if you want to add support for codecs attached to the Samsung SoCs' Audio interfaces. You will also need to select the audio interfaces to support below. +config SND_S3C_DMA + tristate + +config SND_S3C_DMA_LEGACY + tristate + config SND_S3C24XX_I2S tristate select S3C2410_DMA diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 709f6059ad67..86715d8efee6 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -1,5 +1,6 @@ # S3c24XX Platform Support -snd-soc-s3c24xx-objs := dma.o +snd-soc-s3c-dma-objs := dmaengine.o +snd-soc-s3c-dma-legacy-objs := dma.o snd-soc-idma-objs := idma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o @@ -9,7 +10,8 @@ snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o snd-soc-i2s-objs := i2s.o -obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C_DMA) += snd-soc-s3c-dma.o +obj-$(CONFIG_SND_S3C_DMA_LEGACY) += snd-soc-s3c-dma-legacy.o obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 350ba23a9893..4a88e36c82ec 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -221,24 +221,6 @@ static struct snd_ac97_bus_ops s3c_ac97_ops = { .reset = s3c_ac97_cold_reset, }; -static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct s3c_dma_params *dma_data; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &s3c_ac97_pcm_out; - else - dma_data = &s3c_ac97_pcm_in; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - return 0; -} - static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -279,21 +261,6 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); - - return 0; -} - static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -329,15 +296,27 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops s3c_ac97_dai_ops = { - .hw_params = s3c_ac97_hw_params, .trigger = s3c_ac97_trigger, }; static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { - .hw_params = s3c_ac97_hw_mic_params, .trigger = s3c_ac97_mic_trigger, }; +static int s3c_ac97_dai_probe(struct snd_soc_dai *dai) +{ + samsung_asoc_init_dma_data(dai, &s3c_ac97_pcm_out, &s3c_ac97_pcm_in); + + return 0; +} + +static int s3c_ac97_mic_dai_probe(struct snd_soc_dai *dai) +{ + samsung_asoc_init_dma_data(dai, NULL, &s3c_ac97_mic_in); + + return 0; +} + static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { .name = "samsung-ac97", @@ -354,6 +333,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .probe = s3c_ac97_dai_probe, .ops = &s3c_ac97_dai_ops, }, [S3C_AC97_DAI_MIC] = { @@ -365,6 +345,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .channels_max = 1, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .probe = s3c_ac97_mic_dai_probe, .ops = &s3c_ac97_mic_dai_ops, }, }; diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index fe2748b494d4..dc09b71b7d9f 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -35,12 +35,6 @@ static const struct snd_pcm_hardware dma_hardware = { SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = 128*1024, .period_bytes_min = PAGE_SIZE, .period_bytes_max = PAGE_SIZE*2, @@ -441,6 +435,14 @@ static struct snd_soc_platform_driver samsung_asoc_platform = { .pcm_free = dma_free_dma_buffers, }; +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture) +{ + snd_soc_dai_init_dma_data(dai, playback, capture); +} +EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); + int samsung_asoc_dma_platform_register(struct device *dev) { return snd_soc_register_platform(dev, &samsung_asoc_platform); diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index 0e86315a3eaf..225e5378014e 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h @@ -12,6 +12,8 @@ #ifndef _S3C_AUDIO_H #define _S3C_AUDIO_H +#include + struct s3c_dma_params { struct s3c2410_dma_client *client; /* stream identifier */ int channel; /* Channel ID */ @@ -20,8 +22,12 @@ struct s3c_dma_params { unsigned ch; struct samsung_dma_ops *ops; char *ch_name; + struct snd_dmaengine_dai_dma_data dma_data; }; +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture); int samsung_asoc_dma_platform_register(struct device *dev); void samsung_asoc_dma_platform_unregister(struct device *dev); diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c new file mode 100644 index 000000000000..750ce5808d9f --- /dev/null +++ b/sound/soc/samsung/dmaengine.c @@ -0,0 +1,83 @@ +/* + * dmaengine.c - Samsung dmaengine wrapper + * + * Author: Mark Brown + * Copyright 2013 Linaro + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "dma.h" + +#ifdef CONFIG_ARCH_S3C64XX +#define filter_fn pl08x_filter_id +#else +#define filter_fn NULL +#endif + +static const struct snd_dmaengine_pcm_config samsung_dmaengine_pcm_config = { + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, + .compat_filter_fn = filter_fn, +}; + +void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, + struct s3c_dma_params *playback, + struct s3c_dma_params *capture) +{ + struct snd_dmaengine_dai_dma_data *playback_data = NULL; + struct snd_dmaengine_dai_dma_data *capture_data = NULL; + + if (playback) { + playback_data = &playback->dma_data; + playback_data->filter_data = (void *)playback->channel; + playback_data->chan_name = playback->ch_name; + playback_data->addr = playback->dma_addr; + playback_data->addr_width = playback->dma_size; + } + if (capture) { + capture_data = &capture->dma_data; + capture_data->filter_data = (void *)capture->channel; + capture_data->chan_name = capture->ch_name; + capture_data->addr = capture->dma_addr; + capture_data->addr_width = capture->dma_size; + } + + snd_soc_dai_init_dma_data(dai, playback_data, capture_data); +} +EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); + +int samsung_asoc_dma_platform_register(struct device *dev) +{ + return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config, + SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | + SND_DMAENGINE_PCM_FLAG_COMPAT); +} +EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); + +void samsung_asoc_dma_platform_unregister(struct device *dev) +{ + return snd_dmaengine_pcm_unregister(dev); +} +EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister); + +MODULE_AUTHOR("Mark Brown "); +MODULE_DESCRIPTION("Samsung dmaengine ASoC driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index a5cbdb4f1655..92f64363427d 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -702,6 +702,8 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, } writel(mod, i2s->addr + I2SMOD); + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + i2s->frmclk = params_rate(params); return 0; @@ -946,8 +948,11 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - if (other && other->clk) /* If this is probe on secondary */ + if (other && other->clk) { /* If this is probe on secondary */ + samsung_asoc_init_dma_data(dai, &other->sec_dai->dma_playback, + NULL); goto probe_exit; + } i2s->addr = ioremap(i2s->base, 0x100); if (i2s->addr == NULL) { @@ -963,7 +968,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) } clk_prepare_enable(i2s->clk); - snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); if (other) { other->addr = i2s->addr; diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index e4f318fc2f82..3d5cf1530b6f 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -35,14 +35,6 @@ static const struct snd_pcm_hardware idma_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_U24_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = MAX_IDMA_BUFFER, .period_bytes_min = 128, .period_bytes_max = MAX_IDMA_PERIOD, diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index e54256fc4b2c..6a5e4bf6ac96 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -275,7 +275,6 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - struct s3c_dma_params *dma_data; void __iomem *regs = pcm->regs; struct clk *clk; int sclk_div, sync_div; @@ -284,13 +283,6 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, dev_dbg(pcm->dev, "Entered %s\n", __func__); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = pcm->dma_playback; - else - dma_data = pcm->dma_capture; - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - /* Strictly check for sample size */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -461,10 +453,20 @@ static const struct snd_soc_dai_ops s3c_pcm_dai_ops = { .set_fmt = s3c_pcm_set_fmt, }; +static int s3c_pcm_dai_probe(struct snd_soc_dai *dai) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, pcm->dma_playback, pcm->dma_capture); + + return 0; +} + #define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 #define S3C_PCM_DAI_DECLARE \ .symmetric_rates = 1, \ + .probe = s3c_pcm_dai_probe, \ .ops = &s3c_pcm_dai_ops, \ .playback = { \ .channels_min = 2, \ diff --git a/sound/soc/samsung/regs-ac97.h b/sound/soc/samsung/regs-ac97.h index c3878f7acb83..a71be45bbffc 100644 --- a/sound/soc/samsung/regs-ac97.h +++ b/sound/soc/samsung/regs-ac97.h @@ -1,5 +1,4 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h - * +/* * Copyright (c) 2006 Simtec Electronics * http://www.simtec.co.uk/products/SWLINUX/ * @@ -10,8 +9,8 @@ * S3C2440 AC97 Controller */ -#ifndef __ASM_ARCH_REGS_AC97_H -#define __ASM_ARCH_REGS_AC97_H __FILE__ +#ifndef __SAMSUNG_REGS_AC97_H__ +#define __SAMSUNG_REGS_AC97_H__ #define S3C_AC97_GLBCTRL (0x00) @@ -64,4 +63,4 @@ #define S3C_AC97_PCM_DATA (0x18) #define S3C_AC97_MIC_DATA (0x1C) -#endif /* __ASM_ARCH_REGS_AC97_H */ +#endif /* __SAMSUNG_REGS_AC97_H__ */ diff --git a/sound/soc/samsung/regs-iis.h b/sound/soc/samsung/regs-iis.h index a18d35e7a735..dc6cbbe9c4f0 100644 --- a/sound/soc/samsung/regs-iis.h +++ b/sound/soc/samsung/regs-iis.h @@ -1,5 +1,4 @@ -/* arch/arm/plat-samsung/include/plat/regs-iis.h - * +/* * Copyright (c) 2003 Simtec Electronics * http://www.simtec.co.uk/products/SWLINUX/ * @@ -10,8 +9,8 @@ * S3C2410 IIS register definition */ -#ifndef __ASM_ARCH_REGS_IIS_H -#define __ASM_ARCH_REGS_IIS_H +#ifndef __SAMSUNG_REGS_IIS_H__ +#define __SAMSUNG_REGS_IIS_H__ #define S3C2410_IISCON (0x00) @@ -67,4 +66,4 @@ #define S3C2410_IISFIFO (0x10) -#endif /* __ASM_ARCH_REGS_IIS_H */ +#endif /* __SAMSUNG_REGS_IIS_H__ */ diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 1a8b03e4b41b..c85f8eb66c97 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -89,29 +89,12 @@ struct camelot_pcm { #define DMABRG_PREALLOC_BUFFER 32 * 1024 #define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 -/* support everything the SSI supports */ -#define DMABRG_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define DMABRG_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - static struct snd_pcm_hardware camelot_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BATCH), - .formats = DMABRG_FMTS, - .rates = DMABRG_RATES, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 8, /* max of the SSI */ .buffer_bytes_max = DMABRG_PERIOD_MAX, .period_bytes_min = DMABRG_PERIOD_MIN, .period_bytes_max = DMABRG_PERIOD_MAX / 2, diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index b33ca7cd085b..1967f44e7cd4 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -232,9 +232,9 @@ struct fsi_stream { * these are for DMAEngine */ struct dma_chan *chan; - struct sh_dmae_slave slave; /* see fsi_handler_init() */ struct work_struct work; dma_addr_t dma; + int dma_id; int loop_cnt; int additional_pos; }; @@ -1410,15 +1410,6 @@ static void fsi_dma_do_work(struct work_struct *work) } } -static bool fsi_dma_filter(struct dma_chan *chan, void *param) -{ - struct sh_dmae_slave *slave = param; - - chan->private = slave; - - return true; -} - static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io) { schedule_work(&io->work); @@ -1446,15 +1437,34 @@ static int fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) { dma_cap_mask_t mask; + int is_play = fsi_stream_is_play(fsi, io); dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); + io->chan = dma_request_slave_channel_compat(mask, + shdma_chan_filter, (void *)io->dma_id, + dev, is_play ? "tx" : "rx"); + if (io->chan) { + struct dma_slave_config cfg; + int ret; + + cfg.slave_id = io->dma_id; + cfg.dst_addr = 0; /* use default addr */ + cfg.src_addr = 0; /* use default addr */ + cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; + + ret = dmaengine_slave_config(io->chan, &cfg); + if (ret < 0) { + dma_release_channel(io->chan); + io->chan = NULL; + } + } + if (!io->chan) { /* switch to PIO handler */ - if (fsi_stream_is_play(fsi, io)) + if (is_play) fsi->playback.handler = &fsi_pio_push_handler; else fsi->capture.handler = &fsi_pio_pop_handler; @@ -1777,12 +1787,6 @@ static struct snd_pcm_hardware fsi_pcm_hardware = { SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE, - .formats = FSI_FMTS, - .rates = FSI_RATES, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = 64 * 1024, .period_bytes_min = 32, .period_bytes_max = 8192, @@ -1960,7 +1964,7 @@ static void fsi_handler_init(struct fsi_priv *fsi, fsi->capture.priv = fsi; if (info->tx_id) { - fsi->playback.slave.shdma_slave.slave_id = info->tx_id; + fsi->playback.dma_id = info->tx_id; fsi->playback.handler = &fsi_dma_push_handler; } } diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 9430097979a5..a53235c4d1b0 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -19,8 +19,8 @@ struct rsnd_adg { struct clk *clk[CLKMAX]; - int rate_of_441khz_div_6; - int rate_of_48khz_div_6; + int rbga_rate_for_441khz_div_6; /* RBGA */ + int rbgb_rate_for_48khz_div_6; /* RBGB */ u32 ckr; }; @@ -30,41 +30,114 @@ struct rsnd_adg { i++, (pos) = adg->clk[i]) #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) -static enum rsnd_reg rsnd_adg_ssi_reg_get(int id) +static int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, + struct rsnd_mod *mod, + unsigned int src_rate, + unsigned int dst_rate) { - enum rsnd_reg reg; + struct rsnd_adg *adg = rsnd_priv_to_adg(priv); + struct device *dev = rsnd_priv_to_dev(priv); + int idx, sel, div, shift; + u32 mask, val; + int id = rsnd_mod_id(mod); + unsigned int sel_rate [] = { + clk_get_rate(adg->clk[CLKA]), /* 000: CLKA */ + clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */ + clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */ + 0, /* 011: MLBCLK (not used) */ + adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */ + adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */ + }; + + /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */ + for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) { + for (div = 128, idx = 0; + div <= 2048; + div *= 2, idx++) { + if (src_rate == sel_rate[sel] / div) { + val = (idx << 4) | sel; + goto find_rate; + } + } + } + dev_err(dev, "can't find convert src clk\n"); + return -EINVAL; + +find_rate: + shift = (id % 4) * 8; + mask = 0xFF << shift; + val = val << shift; + + dev_dbg(dev, "adg convert src clk = %02x\n", val); + + switch (id / 4) { + case 0: + rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val); + break; + case 1: + rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val); + break; + case 2: + rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val); + break; + } + + /* + * Gen1 doesn't need dst_rate settings, + * since it uses SSI WS pin. + * see also rsnd_src_set_route_if_gen1() + */ + + return 0; +} + +int rsnd_adg_set_convert_clk(struct rsnd_priv *priv, + struct rsnd_mod *mod, + unsigned int src_rate, + unsigned int dst_rate) +{ + if (rsnd_is_gen1(priv)) + return rsnd_adg_set_convert_clk_gen1(priv, mod, + src_rate, dst_rate); + + return -EINVAL; +} + +static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val) +{ + int id = rsnd_mod_id(mod); + int shift = (id % 4) * 8; + u32 mask = 0xFF << shift; + + val = val << shift; /* * SSI 8 is not connected to ADG. * it works with SSI 7 */ if (id == 8) - return RSND_REG_MAX; + return; - if (0 <= id && id <= 3) - reg = RSND_REG_AUDIO_CLK_SEL0; - else if (4 <= id && id <= 7) - reg = RSND_REG_AUDIO_CLK_SEL1; - else - reg = RSND_REG_AUDIO_CLK_SEL2; - - return reg; + switch (id / 4) { + case 0: + rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val); + break; + case 1: + rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val); + break; + case 2: + rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val); + break; + } } int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - enum rsnd_reg reg; - int id; - /* * "mod" = "ssi" here. * we can get "ssi id" from mod */ - id = rsnd_mod_id(mod); - reg = rsnd_adg_ssi_reg_get(id); - - rsnd_write(priv, mod, reg, 0); + rsnd_adg_set_ssi_clk(mod, 0); return 0; } @@ -75,8 +148,7 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) struct rsnd_adg *adg = rsnd_priv_to_adg(priv); struct device *dev = rsnd_priv_to_dev(priv); struct clk *clk; - enum rsnd_reg reg; - int id, shift, i; + int i; u32 data; int sel_table[] = { [CLKA] = 0x1, @@ -102,12 +174,12 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) /* * find 1/6 clock from BRGA/BRGB */ - if (rate == adg->rate_of_441khz_div_6) { + if (rate == adg->rbga_rate_for_441khz_div_6) { data = 0x10; goto found_clock; } - if (rate == adg->rate_of_48khz_div_6) { + if (rate == adg->rbgb_rate_for_48khz_div_6) { data = 0x20; goto found_clock; } @@ -125,19 +197,10 @@ found_clock: * This "mod" = "ssi" here. * we can get "ssi id" from mod */ - id = rsnd_mod_id(mod); - reg = rsnd_adg_ssi_reg_get(id); + rsnd_adg_set_ssi_clk(mod, data); - dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", id, i, rate); - - /* - * Enable SSIx clock - */ - shift = (id % 4) * 8; - - rsnd_bset(priv, mod, reg, - 0xFF << shift, - data << shift); + dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", + rsnd_mod_id(mod), i, rate); return 0; } @@ -166,8 +229,8 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) * rsnd_adg_ssi_clk_try_start() */ ckr = 0; - adg->rate_of_441khz_div_6 = 0; - adg->rate_of_48khz_div_6 = 0; + adg->rbga_rate_for_441khz_div_6 = 0; + adg->rbgb_rate_for_48khz_div_6 = 0; for_each_rsnd_clk(clk, adg, i) { rate = clk_get_rate(clk); @@ -175,14 +238,14 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) continue; /* RBGA */ - if (!adg->rate_of_441khz_div_6 && (0 == rate % 44100)) { - adg->rate_of_441khz_div_6 = rate / 6; + if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) { + adg->rbga_rate_for_441khz_div_6 = rate / 6; ckr |= brg_table[i] << 20; } /* RBGB */ - if (!adg->rate_of_48khz_div_6 && (0 == rate % 48000)) { - adg->rate_of_48khz_div_6 = rate / 6; + if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) { + adg->rbgb_rate_for_48khz_div_6 = rate / 6; ckr |= brg_table[i] << 16; } } diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index b3653d37f75f..743de5e3b1e1 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -628,12 +628,6 @@ static struct snd_pcm_hardware rsnd_pcm_hardware = { SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE, - .formats = RSND_FMTS, - .rates = RSND_RATES, - .rate_min = 8000, - .rate_max = 192000, - .channels_min = 2, - .channels_max = 2, .buffer_bytes_max = 64 * 1024, .period_bytes_min = 32, .period_bytes_max = 8192, diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 61212ee97c28..add088bd4b2a 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -10,20 +10,6 @@ */ #include "rsnd.h" -struct rsnd_gen_ops { - int (*probe)(struct platform_device *pdev, - struct rcar_snd_info *info, - struct rsnd_priv *priv); - void (*remove)(struct platform_device *pdev, - struct rsnd_priv *priv); - int (*path_init)(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io); - int (*path_exit)(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io); -}; - struct rsnd_gen { void __iomem *base[RSND_BASE_MAX]; @@ -86,12 +72,28 @@ static struct regmap_bus rsnd_regmap_bus = { .val_format_endian_default = REGMAP_ENDIAN_NATIVE, }; +static int rsnd_is_accessible_reg(struct rsnd_priv *priv, + struct rsnd_gen *gen, enum rsnd_reg reg) +{ + if (!gen->regs[reg]) { + struct device *dev = rsnd_priv_to_dev(priv); + + dev_err(dev, "unsupported register access %x\n", reg); + return 0; + } + + return 1; +} + u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg) { struct rsnd_gen *gen = rsnd_priv_to_gen(priv); u32 val; + if (!rsnd_is_accessible_reg(priv, gen, reg)) + return 0; + regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); return val; @@ -103,6 +105,9 @@ void rsnd_write(struct rsnd_priv *priv, { struct rsnd_gen *gen = rsnd_priv_to_gen(priv); + if (!rsnd_is_accessible_reg(priv, gen, reg)) + return; + regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); } @@ -111,21 +116,48 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, { struct rsnd_gen *gen = rsnd_priv_to_gen(priv); + if (!rsnd_is_accessible_reg(priv, gen, reg)) + return; + regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), mask, data); } -/* - * Gen2 - * will be filled in the future - */ +static int rsnd_gen_regmap_init(struct rsnd_priv *priv, + struct rsnd_gen *gen, + struct reg_field *regf) +{ + int i; + struct device *dev = rsnd_priv_to_dev(priv); + struct regmap_config regc; -/* - * Gen1 - */ -static int rsnd_gen1_path_init(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) + memset(®c, 0, sizeof(regc)); + regc.reg_bits = 32; + regc.val_bits = 32; + + gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, ®c); + if (IS_ERR(gen->regmap)) { + dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap)); + return PTR_ERR(gen->regmap); + } + + for (i = 0; i < RSND_REG_MAX; i++) { + gen->regs[i] = NULL; + if (!regf[i].reg) + continue; + + gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]); + if (IS_ERR(gen->regs[i])) + return PTR_ERR(gen->regs[i]); + + } + + return 0; +} + +int rsnd_gen_path_init(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) { struct rsnd_mod *mod; int ret; @@ -163,9 +195,9 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv, return ret; } -static int rsnd_gen1_path_exit(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +int rsnd_gen_path_exit(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) { struct rsnd_mod *mod, *n; int ret = 0; @@ -179,6 +211,94 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv, return ret; } +/* + * Gen2 + */ + +/* single address mapping */ +#define RSND_GEN2_S_REG(gen, reg, id, offset) \ + RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 10) + +/* multi address mapping */ +#define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset) \ + RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 10) + +static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) +{ + struct reg_field regf[RSND_REG_MAX] = { + RSND_GEN2_S_REG(gen, SSIU, SSI_MODE0, 0x800), + RSND_GEN2_S_REG(gen, SSIU, SSI_MODE1, 0x804), + /* FIXME: it needs SSI_MODE2/3 in the future */ + RSND_GEN2_M_REG(gen, SSIU, INT_ENABLE, 0x18, 0x80), + + RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), + RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), + RSND_GEN2_S_REG(gen, ADG, SSICKR, 0x08), + RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), + RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), + RSND_GEN2_S_REG(gen, ADG, AUDIO_CLK_SEL2, 0x14), + + RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), + RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), + RSND_GEN2_M_REG(gen, SSI, SSITDR, 0x08, 0x40), + RSND_GEN2_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40), + RSND_GEN2_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), + }; + + return rsnd_gen_regmap_init(priv, gen, regf); +} + +static int rsnd_gen2_probe(struct platform_device *pdev, + struct rcar_snd_info *info, + struct rsnd_priv *priv) +{ + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_gen *gen = rsnd_priv_to_gen(priv); + struct resource *scu_res; + struct resource *adg_res; + struct resource *ssiu_res; + struct resource *ssi_res; + int ret; + + /* + * map address + */ + scu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU); + adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG); + ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU); + ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI); + + gen->base[RSND_GEN2_SCU] = devm_ioremap_resource(dev, scu_res); + gen->base[RSND_GEN2_ADG] = devm_ioremap_resource(dev, adg_res); + gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res); + gen->base[RSND_GEN2_SSI] = devm_ioremap_resource(dev, ssi_res); + if (IS_ERR(gen->base[RSND_GEN2_SCU]) || + IS_ERR(gen->base[RSND_GEN2_ADG]) || + IS_ERR(gen->base[RSND_GEN2_SSIU]) || + IS_ERR(gen->base[RSND_GEN2_SSI])) + return -ENODEV; + + ret = rsnd_gen2_regmap_init(priv, gen); + if (ret < 0) + return ret; + + dev_dbg(dev, "Gen2 device probed\n"); + dev_dbg(dev, "SRU : %08x => %p\n", scu_res->start, + gen->base[RSND_GEN2_SCU]); + dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, + gen->base[RSND_GEN2_ADG]); + dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start, + gen->base[RSND_GEN2_SSIU]); + dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, + gen->base[RSND_GEN2_SSI]); + + return 0; +} + +/* + * Gen1 + */ + /* single address mapping */ #define RSND_GEN1_S_REG(gen, reg, id, offset) \ RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9) @@ -189,19 +309,23 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv, static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) { - int i; - struct device *dev = rsnd_priv_to_dev(priv); - struct regmap_config regc; struct reg_field regf[RSND_REG_MAX] = { RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_SEL, 0x00), RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL0, 0x08), RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL1, 0x0c), RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL2, 0x10), - RSND_GEN1_S_REG(gen, SRU, SRC_CTRL, 0xc0), + RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_CTRL, 0xc0), RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0), RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4), RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4), - RSND_GEN1_M_REG(gen, SRU, BUSIF_ADINR, 0x214, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_ROUTE_MODE0,0x50, 0x8), + RSND_GEN1_M_REG(gen, SRU, SRC_SWRSR, 0x200, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_SRCIR, 0x204, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_ADINR, 0x214, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_IFSCR, 0x21c, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_IFSVR, 0x220, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_SRCCR, 0x224, 0x40), + RSND_GEN1_M_REG(gen, SRU, SRC_MNFSR, 0x228, 0x40), RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00), RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04), @@ -219,24 +343,7 @@ static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) RSND_GEN1_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), }; - memset(®c, 0, sizeof(regc)); - regc.reg_bits = 32; - regc.val_bits = 32; - - gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, ®c); - if (IS_ERR(gen->regmap)) { - dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap)); - return PTR_ERR(gen->regmap); - } - - for (i = 0; i < RSND_REG_MAX; i++) { - gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]); - if (IS_ERR(gen->regs[i])) - return PTR_ERR(gen->regs[i]); - - } - - return 0; + return rsnd_gen_regmap_init(priv, gen, regf); } static int rsnd_gen1_probe(struct platform_device *pdev, @@ -281,45 +388,16 @@ static int rsnd_gen1_probe(struct platform_device *pdev, } -static void rsnd_gen1_remove(struct platform_device *pdev, - struct rsnd_priv *priv) -{ -} - -static struct rsnd_gen_ops rsnd_gen1_ops = { - .probe = rsnd_gen1_probe, - .remove = rsnd_gen1_remove, - .path_init = rsnd_gen1_path_init, - .path_exit = rsnd_gen1_path_exit, -}; - /* * Gen */ -int rsnd_gen_path_init(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) -{ - struct rsnd_gen *gen = rsnd_priv_to_gen(priv); - - return gen->ops->path_init(priv, rdai, io); -} - -int rsnd_gen_path_exit(struct rsnd_priv *priv, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) -{ - struct rsnd_gen *gen = rsnd_priv_to_gen(priv); - - return gen->ops->path_exit(priv, rdai, io); -} - int rsnd_gen_probe(struct platform_device *pdev, struct rcar_snd_info *info, struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_gen *gen; + int ret; gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); if (!gen) { @@ -327,23 +405,21 @@ int rsnd_gen_probe(struct platform_device *pdev, return -ENOMEM; } - if (rsnd_is_gen1(priv)) - gen->ops = &rsnd_gen1_ops; - - if (!gen->ops) { - dev_err(dev, "unknown generation R-Car sound device\n"); - return -ENODEV; - } - priv->gen = gen; - return gen->ops->probe(pdev, info, priv); + ret = -ENODEV; + if (rsnd_is_gen1(priv)) + ret = rsnd_gen1_probe(pdev, info, priv); + else if (rsnd_is_gen2(priv)) + ret = rsnd_gen2_probe(pdev, info, priv); + + if (ret < 0) + dev_err(dev, "unknown generation R-Car sound device\n"); + + return ret; } void rsnd_gen_remove(struct platform_device *pdev, struct rsnd_priv *priv) { - struct rsnd_gen *gen = rsnd_priv_to_gen(priv); - - gen->ops->remove(pdev, priv); } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 9e463e50e7e6..4ca66cd899c8 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -31,16 +31,24 @@ * see gen1/gen2 for detail */ enum rsnd_reg { - /* SRU/SCU */ - RSND_REG_SRC_ROUTE_SEL, - RSND_REG_SRC_TMG_SEL0, - RSND_REG_SRC_TMG_SEL1, - RSND_REG_SRC_TMG_SEL2, - RSND_REG_SRC_CTRL, + /* SRU/SCU/SSIU */ + RSND_REG_SRC_ROUTE_SEL, /* for Gen1 */ + RSND_REG_SRC_TMG_SEL0, /* for Gen1 */ + RSND_REG_SRC_TMG_SEL1, /* for Gen1 */ + RSND_REG_SRC_TMG_SEL2, /* for Gen1 */ + RSND_REG_SRC_ROUTE_CTRL, /* for Gen1 */ RSND_REG_SSI_MODE0, RSND_REG_SSI_MODE1, RSND_REG_BUSIF_MODE, - RSND_REG_BUSIF_ADINR, + RSND_REG_INT_ENABLE, /* for Gen2 */ + RSND_REG_SRC_ROUTE_MODE0, + RSND_REG_SRC_SWRSR, + RSND_REG_SRC_SRCIR, + RSND_REG_SRC_ADINR, + RSND_REG_SRC_IFSCR, + RSND_REG_SRC_IFSVR, + RSND_REG_SRC_SRCCR, + RSND_REG_SRC_MNFSR, /* ADG */ RSND_REG_BRRA, @@ -49,9 +57,9 @@ enum rsnd_reg { RSND_REG_AUDIO_CLK_SEL0, RSND_REG_AUDIO_CLK_SEL1, RSND_REG_AUDIO_CLK_SEL2, - RSND_REG_AUDIO_CLK_SEL3, - RSND_REG_AUDIO_CLK_SEL4, - RSND_REG_AUDIO_CLK_SEL5, + RSND_REG_AUDIO_CLK_SEL3, /* for Gen1 */ + RSND_REG_AUDIO_CLK_SEL4, /* for Gen1 */ + RSND_REG_AUDIO_CLK_SEL5, /* for Gen1 */ /* SSI */ RSND_REG_SSICR, @@ -174,11 +182,11 @@ struct rsnd_dai { struct rsnd_dai_stream playback; struct rsnd_dai_stream capture; - int clk_master:1; - int bit_clk_inv:1; - int frm_clk_inv:1; - int sys_delay:1; - int data_alignment:1; + unsigned int clk_master:1; + unsigned int bit_clk_inv:1; + unsigned int frm_clk_inv:1; + unsigned int sys_delay:1; + unsigned int data_alignment:1; }; #define rsnd_dai_nr(priv) ((priv)->dai_nr) @@ -229,6 +237,10 @@ int rsnd_adg_probe(struct platform_device *pdev, struct rsnd_priv *priv); void rsnd_adg_remove(struct platform_device *pdev, struct rsnd_priv *priv); +int rsnd_adg_set_convert_clk(struct rsnd_priv *priv, + struct rsnd_mod *mod, + unsigned int src_rate, + unsigned int dst_rate); /* * R-Car sound priv @@ -282,6 +294,10 @@ void rsnd_scu_remove(struct platform_device *pdev, struct rsnd_priv *priv); struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id); bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod); +unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv, + struct rsnd_mod *ssi_mod, + struct snd_pcm_runtime *runtime); + #define rsnd_scu_nr(priv) ((priv)->scu_nr) /* diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c index fa8fa15860b9..9bb08bb1d455 100644 --- a/sound/soc/sh/rcar/scu.c +++ b/sound/soc/sh/rcar/scu.c @@ -13,9 +13,13 @@ struct rsnd_scu { struct rsnd_scu_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; + struct clk *clk; }; #define rsnd_scu_mode_flags(p) ((p)->info->flags) +#define rsnd_scu_convert_rate(p) ((p)->info->convert_rate) + +#define RSND_SCU_NAME_SIZE 16 /* * ADINR @@ -26,6 +30,15 @@ struct rsnd_scu { #define OTBL_18 (6 << 16) #define OTBL_16 (8 << 16) +/* + * image of SRC (Sampling Rate Converter) + * + * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+ + * 48kHz <-> | SRC | <------> | SSI | <-----> | codec | + * 44.1kHz <-> +-----+ +-----+ +-------+ + * ... + * + */ #define rsnd_mod_to_scu(_mod) \ container_of((_mod), struct rsnd_scu, mod) @@ -36,7 +49,8 @@ struct rsnd_scu { ((pos) = (struct rsnd_scu *)(priv)->scu + i); \ i++) -static int rsnd_scu_set_route(struct rsnd_priv *priv, +/* Gen1 only */ +static int rsnd_src_set_route_if_gen1(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) @@ -55,7 +69,7 @@ static int rsnd_scu_set_route(struct rsnd_priv *priv, { 0x3, 28, }, /* 7 */ { 0x3, 30, }, /* 8 */ }; - + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); u32 mask; u32 val; int shift; @@ -85,9 +99,18 @@ static int rsnd_scu_set_route(struct rsnd_priv *priv, */ shift = (id % 4) * 8; mask = 0x1F << shift; - if (8 == id) /* SRU8 is very special */ + + /* + * ADG is used as source clock if SRC was used, + * then, SSI WS is used as destination clock. + * SSI WS is used as source clock if SRC is not used + * (when playback, source/destination become reverse when capture) + */ + if (rsnd_scu_convert_rate(scu)) /* use ADG */ + val = 0; + else if (8 == id) /* use SSI WS, but SRU8 is special */ val = id << shift; - else + else /* use SSI WS */ val = (id + 1) << shift; switch (id / 4) { @@ -105,30 +128,45 @@ static int rsnd_scu_set_route(struct rsnd_priv *priv, return 0; } -static int rsnd_scu_set_mode(struct rsnd_priv *priv, - struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct rsnd_dai_stream *io) +unsigned int rsnd_scu_get_ssi_rate(struct rsnd_priv *priv, + struct rsnd_mod *ssi_mod, + struct snd_pcm_runtime *runtime) { - int id = rsnd_mod_id(mod); - u32 val; + struct rsnd_scu *scu; + unsigned int rate; - if (rsnd_is_gen1(priv)) { - val = (1 << id); - rsnd_mod_bset(mod, SRC_CTRL, val, val); - } + /* this function is assuming SSI id = SCU id here */ + scu = rsnd_mod_to_scu(rsnd_scu_mod_get(priv, rsnd_mod_id(ssi_mod))); - return 0; + /* + * return convert rate if SRC is used, + * otherwise, return runtime->rate as usual + */ + rate = rsnd_scu_convert_rate(scu); + if (!rate) + rate = runtime->rate; + + return rate; } -static int rsnd_scu_set_hpbif(struct rsnd_priv *priv, +static int rsnd_scu_convert_rate_ctrl(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_dai *rdai, struct rsnd_dai_stream *io) { struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + u32 convert_rate = rsnd_scu_convert_rate(scu); u32 adinr = runtime->channels; + /* set/clear soft reset */ + rsnd_mod_write(mod, SRC_SWRSR, 0); + rsnd_mod_write(mod, SRC_SWRSR, 1); + + /* Initialize the operation of the SRC internal circuits */ + rsnd_mod_write(mod, SRC_SRCIR, 1); + + /* Set channel number and output bit length */ switch (runtime->sample_bits) { case 16: adinr |= OTBL_16; @@ -139,9 +177,81 @@ static int rsnd_scu_set_hpbif(struct rsnd_priv *priv, default: return -EIO; } + rsnd_mod_write(mod, SRC_ADINR, adinr); + if (convert_rate) { + u32 fsrate = 0x0400000 / convert_rate * runtime->rate; + int ret; + + /* Enable the initial value of IFS */ + rsnd_mod_write(mod, SRC_IFSCR, 1); + + /* Set initial value of IFS */ + rsnd_mod_write(mod, SRC_IFSVR, fsrate); + + /* Select SRC mode (fixed value) */ + rsnd_mod_write(mod, SRC_SRCCR, 0x00010110); + + /* Set the restriction value of the FS ratio (98%) */ + rsnd_mod_write(mod, SRC_MNFSR, fsrate / 100 * 98); + + if (rsnd_is_gen1(priv)) { + /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ + } + + /* set convert clock */ + ret = rsnd_adg_set_convert_clk(priv, mod, + runtime->rate, + convert_rate); + if (ret < 0) + return ret; + } + + /* Cancel the initialization and operate the SRC function */ + rsnd_mod_write(mod, SRC_SRCIR, 0); + + /* use DMA transfer */ rsnd_mod_write(mod, BUSIF_MODE, 1); - rsnd_mod_write(mod, BUSIF_ADINR, adinr); + + return 0; +} + +static int rsnd_scu_transfer_start(struct rsnd_priv *priv, + struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + int id = rsnd_mod_id(mod); + u32 val; + + if (rsnd_is_gen1(priv)) { + val = (1 << id); + rsnd_mod_bset(mod, SRC_ROUTE_CTRL, val, val); + } + + if (rsnd_scu_convert_rate(scu)) + rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); + + return 0; +} + +static int rsnd_scu_transfer_stop(struct rsnd_priv *priv, + struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + int id = rsnd_mod_id(mod); + u32 mask; + + if (rsnd_is_gen1(priv)) { + mask = (1 << id); + rsnd_mod_bset(mod, SRC_ROUTE_CTRL, mask, 0); + } + + if (rsnd_scu_convert_rate(scu)) + rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0); return 0; } @@ -159,6 +269,7 @@ static int rsnd_scu_start(struct rsnd_mod *mod, struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); struct device *dev = rsnd_priv_to_dev(priv); int ret; @@ -173,16 +284,19 @@ static int rsnd_scu_start(struct rsnd_mod *mod, return 0; } + clk_enable(scu->clk); + /* it use DMA transter */ - ret = rsnd_scu_set_route(priv, mod, rdai, io); + + ret = rsnd_src_set_route_if_gen1(priv, mod, rdai, io); if (ret < 0) return ret; - ret = rsnd_scu_set_mode(priv, mod, rdai, io); + ret = rsnd_scu_convert_rate_ctrl(priv, mod, rdai, io); if (ret < 0) return ret; - ret = rsnd_scu_set_hpbif(priv, mod, rdai, io); + ret = rsnd_scu_transfer_start(priv, mod, rdai, io); if (ret < 0) return ret; @@ -191,9 +305,27 @@ static int rsnd_scu_start(struct rsnd_mod *mod, return 0; } +static int rsnd_scu_stop(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +{ + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + + if (!rsnd_scu_hpbif_is_enable(mod)) + return 0; + + rsnd_scu_transfer_stop(priv, mod, rdai, io); + + clk_disable(scu->clk); + + return 0; +} + static struct rsnd_mod_ops rsnd_scu_ops = { .name = "scu", .start = rsnd_scu_start, + .stop = rsnd_scu_stop, }; struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) @@ -210,6 +342,8 @@ int rsnd_scu_probe(struct platform_device *pdev, { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_scu *scu; + struct clk *clk; + char name[RSND_SCU_NAME_SIZE]; int i, nr; /* @@ -226,9 +360,16 @@ int rsnd_scu_probe(struct platform_device *pdev, priv->scu = scu; for_each_rsnd_scu(scu, priv, i) { + snprintf(name, RSND_SCU_NAME_SIZE, "scu.%d", i); + + clk = devm_clk_get(dev, name); + if (IS_ERR(clk)) + return PTR_ERR(clk); + rsnd_mod_init(priv, &scu->mod, &rsnd_scu_ops, i); scu->info = &info->scu_info[i]; + scu->clk = clk; dev_dbg(dev, "SCU%d probed\n", i); } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 5ac20cd5e006..4b8cf7ca9d19 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -187,9 +187,10 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod, } static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, - unsigned int rate) + struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct device *dev = rsnd_priv_to_dev(priv); int i, j, ret; int adg_clk_div_table[] = { @@ -199,6 +200,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, 1, 2, 4, 8, 16, 6, 12, }; unsigned int main_rate; + unsigned int rate = rsnd_scu_get_ssi_rate(priv, &ssi->mod, runtime); /* * Find best clock, and try to start ADG @@ -209,7 +211,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, /* * this driver is assuming that * system word is 64fs (= 2 x 32bit) - * see rsnd_ssi_start() + * see rsnd_ssi_init() */ main_rate = rate / adg_clk_div_table[i] * 32 * 2 * ssi_clk_mul_table[j]; @@ -251,14 +253,10 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, clk_enable(ssi->clk); if (rsnd_rdai_is_clk_master(rdai)) { - struct snd_pcm_runtime *runtime; - - runtime = rsnd_io_to_runtime(io); - if (rsnd_ssi_clk_from_parent(ssi)) rsnd_ssi_hw_start(ssi->parent, rdai, io); else - rsnd_ssi_master_clk_start(ssi, runtime->rate); + rsnd_ssi_master_clk_start(ssi, io); } } @@ -457,6 +455,10 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, /* enable PIO IRQ */ ssi->cr_etc = UIEN | OIEN | DIEN; + /* enable PIO interrupt if gen2 */ + if (rsnd_is_gen2(priv)) + rsnd_mod_write(&ssi->mod, INT_ENABLE, 0x0f000000); + rsnd_ssi_hw_start(ssi, rdai, io); dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); @@ -650,7 +652,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, snprintf(name, RSND_SSI_NAME_SIZE, "ssi.%d", i); - clk = clk_get(dev, name); + clk = devm_clk_get(dev, name); if (IS_ERR(clk)) return PTR_ERR(clk); @@ -711,7 +713,6 @@ void rsnd_ssi_remove(struct platform_device *pdev, int i; for_each_rsnd_ssi(ssi, priv, i) { - clk_put(ssi->clk); if (rsnd_ssi_dma_available(ssi)) rsnd_dma_quit(priv, rsnd_mod_to_dma(&ssi->mod)); } diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 53c9ecdd119f..5e9690c85d8f 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -24,6 +24,7 @@ #include #include #include +#include static int soc_compr_open(struct snd_compr_stream *cstream) { @@ -75,6 +76,98 @@ out: return ret; } +static int soc_compr_open_fe(struct snd_compr_stream *cstream) +{ + struct snd_soc_pcm_runtime *fe = cstream->private_data; + struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; + struct snd_soc_platform *platform = fe->platform; + struct snd_soc_dai *cpu_dai = fe->cpu_dai; + struct snd_soc_dai *codec_dai = fe->codec_dai; + struct snd_soc_dpcm *dpcm; + struct snd_soc_dapm_widget_list *list; + int stream; + int ret = 0; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + stream = SNDRV_PCM_STREAM_PLAYBACK; + else + stream = SNDRV_PCM_STREAM_CAPTURE; + + mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + + if (platform->driver->compr_ops && platform->driver->compr_ops->open) { + ret = platform->driver->compr_ops->open(cstream); + if (ret < 0) { + pr_err("compress asoc: can't open platform %s\n", platform->name); + goto out; + } + } + + if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) { + ret = fe->dai_link->compr_ops->startup(cstream); + if (ret < 0) { + pr_err("compress asoc: %s startup failed\n", fe->dai_link->name); + goto machine_err; + } + } + + fe->dpcm[stream].runtime = fe_substream->runtime; + + if (dpcm_path_get(fe, stream, &list) <= 0) { + dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", + fe->dai_link->name, stream ? "capture" : "playback"); + } + + /* calculate valid and active FE <-> BE dpcms */ + dpcm_process_paths(fe, stream, &list, 1); + + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; + + ret = dpcm_be_dai_startup(fe, stream); + if (ret < 0) { + /* clean up all links */ + list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) + dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; + + dpcm_be_disconnect(fe, stream); + fe->dpcm[stream].runtime = NULL; + goto fe_err; + } + + dpcm_clear_pending_state(fe, stream); + dpcm_path_put(&list); + + fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) { + cpu_dai->playback_active++; + codec_dai->playback_active++; + } else { + cpu_dai->capture_active++; + codec_dai->capture_active++; + } + + cpu_dai->active++; + codec_dai->active++; + fe->codec->active++; + + mutex_unlock(&fe->card->mutex); + + return 0; + +fe_err: + if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown) + fe->dai_link->compr_ops->shutdown(cstream); +machine_err: + if (platform->driver->compr_ops && platform->driver->compr_ops->free) + platform->driver->compr_ops->free(cstream); +out: + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; + mutex_unlock(&fe->card->mutex); + return ret; +} + /* * Power down the audio subsystem pmdown_time msecs after close is called. * This is to ensure there are no pops or clicks in between any music tracks @@ -164,6 +257,65 @@ static int soc_compr_free(struct snd_compr_stream *cstream) return 0; } +static int soc_compr_free_fe(struct snd_compr_stream *cstream) +{ + struct snd_soc_pcm_runtime *fe = cstream->private_data; + struct snd_soc_platform *platform = fe->platform; + struct snd_soc_dai *cpu_dai = fe->cpu_dai; + struct snd_soc_dai *codec_dai = fe->codec_dai; + struct snd_soc_dpcm *dpcm; + int stream, ret; + + mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + + if (cstream->direction == SND_COMPRESS_PLAYBACK) { + stream = SNDRV_PCM_STREAM_PLAYBACK; + cpu_dai->playback_active--; + codec_dai->playback_active--; + } else { + stream = SNDRV_PCM_STREAM_CAPTURE; + cpu_dai->capture_active--; + codec_dai->capture_active--; + } + + cpu_dai->active--; + codec_dai->active--; + fe->codec->active--; + + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; + + ret = dpcm_be_dai_hw_free(fe, stream); + if (ret < 0) + dev_err(fe->dev, "compressed hw_free failed %d\n", ret); + + ret = dpcm_be_dai_shutdown(fe, stream); + + /* mark FE's links ready to prune */ + list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) + dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); + else + dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP); + + fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; + + dpcm_be_disconnect(fe, stream); + + fe->dpcm[stream].runtime = NULL; + + if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown) + fe->dai_link->compr_ops->shutdown(cstream); + + if (platform->driver->compr_ops && platform->driver->compr_ops->free) + platform->driver->compr_ops->free(cstream); + + mutex_unlock(&fe->card->mutex); + return 0; +} + static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd) { @@ -194,6 +346,59 @@ out: return ret; } +static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) +{ + struct snd_soc_pcm_runtime *fe = cstream->private_data; + struct snd_soc_platform *platform = fe->platform; + int ret = 0, stream; + + if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN || + cmd == SND_COMPR_TRIGGER_DRAIN) { + + if (platform->driver->compr_ops && + platform->driver->compr_ops->trigger) + return platform->driver->compr_ops->trigger(cstream, cmd); + } + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + stream = SNDRV_PCM_STREAM_PLAYBACK; + else + stream = SNDRV_PCM_STREAM_CAPTURE; + + + mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + + if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) { + ret = platform->driver->compr_ops->trigger(cstream, cmd); + if (ret < 0) + goto out; + } + + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; + + ret = dpcm_be_dai_trigger(fe, stream, cmd); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; + break; + } + +out: + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; + mutex_unlock(&fe->card->mutex); + return ret; +} + static int soc_compr_set_params(struct snd_compr_stream *cstream, struct snd_compr_params *params) { @@ -241,6 +446,64 @@ err: return ret; } +static int soc_compr_set_params_fe(struct snd_compr_stream *cstream, + struct snd_compr_params *params) +{ + struct snd_soc_pcm_runtime *fe = cstream->private_data; + struct snd_pcm_substream *fe_substream = fe->pcm->streams[0].substream; + struct snd_soc_platform *platform = fe->platform; + int ret = 0, stream; + + if (cstream->direction == SND_COMPRESS_PLAYBACK) + stream = SNDRV_PCM_STREAM_PLAYBACK; + else + stream = SNDRV_PCM_STREAM_CAPTURE; + + mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); + + if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) { + ret = platform->driver->compr_ops->set_params(cstream, params); + if (ret < 0) + goto out; + } + + if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) { + ret = fe->dai_link->compr_ops->set_params(cstream); + if (ret < 0) + goto out; + } + + /* + * Create an empty hw_params for the BE as the machine driver must + * fix this up to match DSP decoder and ASRC configuration. + * I.e. machine driver fixup for compressed BE is mandatory. + */ + memset(&fe->dpcm[fe_substream->stream].hw_params, 0, + sizeof(struct snd_pcm_hw_params)); + + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; + + ret = dpcm_be_dai_hw_params(fe, stream); + if (ret < 0) + goto out; + + ret = dpcm_be_dai_prepare(fe, stream); + if (ret < 0) + goto out; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); + else + dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START); + + fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; + +out: + fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; + mutex_unlock(&fe->card->mutex); + return ret; +} + static int soc_compr_get_params(struct snd_compr_stream *cstream, struct snd_codec *params) { @@ -360,6 +623,7 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream, return ret; } + /* ASoC Compress operations */ static struct snd_compr_ops soc_compr_ops = { .open = soc_compr_open, @@ -375,6 +639,21 @@ static struct snd_compr_ops soc_compr_ops = { .get_codec_caps = soc_compr_get_codec_caps }; +/* ASoC Dynamic Compress operations */ +static struct snd_compr_ops soc_compr_dyn_ops = { + .open = soc_compr_open_fe, + .free = soc_compr_free_fe, + .set_params = soc_compr_set_params_fe, + .get_params = soc_compr_get_params, + .set_metadata = soc_compr_set_metadata, + .get_metadata = soc_compr_get_metadata, + .trigger = soc_compr_trigger_fe, + .pointer = soc_compr_pointer, + .ack = soc_compr_ack, + .get_caps = soc_compr_get_caps, + .get_codec_caps = soc_compr_get_codec_caps +}; + /* create a new compress */ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) { @@ -383,6 +662,7 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_compr *compr; + struct snd_pcm *be_pcm; char new_name[64]; int ret = 0, direction = 0; @@ -410,7 +690,26 @@ int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) ret = -ENOMEM; goto compr_err; } - memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); + + if (rtd->dai_link->dynamic) { + snprintf(new_name, sizeof(new_name), "(%s)", + rtd->dai_link->stream_name); + + ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, + 1, 0, &be_pcm); + if (ret < 0) { + dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n", + rtd->dai_link->name); + goto compr_err; + } + + rtd->pcm = be_pcm; + rtd->fe_compr = 1; + be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; + be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; + memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); + } else + memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); /* Add copy callback for not memory mapped DSPs */ if (platform->driver->compr_ops && platform->driver->compr_ops->copy) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a66783e13a9c..fe1df50805a3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1728,6 +1728,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) } snd_soc_dapm_link_dai_widgets(card); + snd_soc_dapm_connect_dai_link_widgets(card); if (card->controls) snd_soc_add_card_controls(card, card->controls, card->num_controls); @@ -3484,7 +3485,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0, freq, dir); else - return -EINVAL; + return -ENOTSUPP; } EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); @@ -3505,7 +3506,7 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, return codec->driver->set_sysclk(codec, clk_id, source, freq, dir); else - return -EINVAL; + return -ENOTSUPP; } EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk); @@ -4617,10 +4618,14 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, if (id < 0 || id >= pos->num_dai) { ret = -EINVAL; - } else { - *dai_name = pos->dai_drv[id].name; - ret = 0; + break; } + + ret = 0; + + *dai_name = pos->dai_drv[id].name; + if (!*dai_name) + *dai_name = pos->name; } break; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index dcade130157f..dc8ff13187f7 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -371,12 +371,16 @@ static void dapm_reset(struct snd_soc_card *card) } } -static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) +static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, + unsigned int *value) { - if (w->codec) - return snd_soc_read(w->codec, reg); - else if (w->platform) - return snd_soc_platform_read(w->platform, reg); + if (w->codec) { + *value = snd_soc_read(w->codec, reg); + return 0; + } else if (w->platform) { + *value = snd_soc_platform_read(w->platform, reg); + return 0; + } dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); return -1; @@ -430,13 +434,12 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, return ret; } else { soc_widget_lock(w); - ret = soc_widget_read(w, reg); + ret = soc_widget_read(w, reg, &old); if (ret < 0) { soc_widget_unlock(w); return ret; } - old = ret; new = (old & ~mask) | (value & mask); change = old != new; if (change) { @@ -513,7 +516,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, unsigned int invert = mc->invert; if (reg != SND_SOC_NOPM) { - val = soc_widget_read(w, reg); + soc_widget_read(w, reg, &val); val = (val >> shift) & mask; if (invert) val = max - val; @@ -529,7 +532,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, w->kcontrol_news[i].private_value; int val, item; - val = soc_widget_read(w, e->reg); + soc_widget_read(w, e->reg, &val); item = (val >> e->shift_l) & e->mask; if (item < e->max && !strcmp(p->name, e->texts[item])) @@ -558,7 +561,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, w->kcontrol_news[i].private_value; int val, item; - val = soc_widget_read(w, e->reg); + soc_widget_read(w, e->reg, &val); val = (val >> e->shift_l) & e->mask; for (item = 0; item < e->max; item++) { if (val == e->values[item]) @@ -2473,7 +2476,8 @@ err: } static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, - const struct snd_soc_dapm_route *route) + const struct snd_soc_dapm_route *route, + unsigned int is_prefixed) { struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; @@ -2483,7 +2487,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, char prefixed_source[80]; int ret; - if (dapm->codec && dapm->codec->name_prefix) { + if (dapm->codec && dapm->codec->name_prefix && !is_prefixed) { snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", dapm->codec->name_prefix, route->sink); sink = prefixed_sink; @@ -2611,7 +2615,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); for (i = 0; i < num; i++) { - r = snd_soc_dapm_add_route(dapm, route); + r = snd_soc_dapm_add_route(dapm, route, false); if (r < 0) { dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", route->source, @@ -2782,7 +2786,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) /* Read the initial power state from the device */ if (w->reg >= 0) { - val = soc_widget_read(w, w->reg) >> w->shift; + soc_widget_read(w, w->reg, &val); + val = val >> w->shift; val &= w->mask; if (val == w->on_val) w->power = 1; @@ -2868,6 +2873,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, unsigned int val; int connect, change; struct snd_soc_dapm_update update; + int ret = 0; if (snd_soc_volsw_is_stereo(mc)) dev_warn(codec->dapm.dev, @@ -2901,12 +2907,16 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, card->update = &update; } - soc_dapm_mixer_update_power(card, kcontrol, connect); + ret = soc_dapm_mixer_update_power(card, kcontrol, connect); card->update = NULL; } mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); @@ -2955,6 +2965,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, unsigned int val, mux, change; unsigned int mask; struct snd_soc_dapm_update update; + int ret = 0; if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; @@ -2978,12 +2989,16 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, update.val = val; card->update = &update; - soc_dapm_mux_update_power(card, kcontrol, mux, e); + ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); card->update = NULL; } mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); @@ -3019,6 +3034,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int change; + int ret = 0; if (ucontrol->value.enumerated.item[0] >= e->max) return -EINVAL; @@ -3028,9 +3044,13 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, value = ucontrol->value.enumerated.item[0]; change = dapm_kcontrol_set_value(kcontrol, value); if (change) - soc_dapm_mux_update_power(card, kcontrol, value, e); + ret = soc_dapm_mux_update_power(card, kcontrol, value, e); mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); @@ -3097,6 +3117,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, unsigned int val, mux, change; unsigned int mask; struct snd_soc_dapm_update update; + int ret = 0; if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; @@ -3120,12 +3141,16 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, update.val = val; card->update = &update; - soc_dapm_mux_update_power(card, kcontrol, mux, e); + ret = soc_dapm_mux_update_power(card, kcontrol, mux, e); card->update = NULL; } mutex_unlock(&card->dapm_mutex); + + if (ret > 0) + soc_dpcm_runtime_update(card); + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); @@ -3614,6 +3639,55 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) return 0; } +void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) +{ + struct snd_soc_pcm_runtime *rtd = card->rtd; + struct snd_soc_dai *cpu_dai, *codec_dai; + struct snd_soc_dapm_route r; + int i; + + memset(&r, 0, sizeof(r)); + + /* for each BE DAI link... */ + for (i = 0; i < card->num_rtd; i++) { + rtd = &card->rtd[i]; + cpu_dai = rtd->cpu_dai; + codec_dai = rtd->codec_dai; + + /* dynamic FE links have no fixed DAI mapping */ + if (rtd->dai_link->dynamic) + continue; + + /* there is no point in connecting BE DAI links with dummies */ + if (snd_soc_dai_is_dummy(codec_dai) || + snd_soc_dai_is_dummy(cpu_dai)) + continue; + + /* connect BE DAI playback if widgets are valid */ + if (codec_dai->playback_widget && cpu_dai->playback_widget) { + r.source = cpu_dai->playback_widget->name; + r.sink = codec_dai->playback_widget->name; + dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", + cpu_dai->codec->name, r.source, + codec_dai->platform->name, r.sink); + + snd_soc_dapm_add_route(&card->dapm, &r, true); + } + + /* connect BE DAI capture if widgets are valid */ + if (codec_dai->capture_widget && cpu_dai->capture_widget) { + r.source = codec_dai->capture_widget->name; + r.sink = cpu_dai->capture_widget->name; + dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", + codec_dai->codec->name, r.source, + cpu_dai->platform->name, r.sink); + + snd_soc_dapm_add_route(&card->dapm, &r, true); + } + + } +} + static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, int event) { diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 3449c1e909ae..7ac745df1412 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -12,6 +12,7 @@ #include #include #include +#include static void devm_component_release(struct device *dev, void *res) { @@ -84,3 +85,43 @@ int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card) return ret; } EXPORT_SYMBOL_GPL(devm_snd_soc_register_card); + +#ifdef CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM + +static void devm_dmaengine_pcm_release(struct device *dev, void *res) +{ + snd_dmaengine_pcm_unregister(*(struct device **)res); +} + +/** + * devm_snd_dmaengine_pcm_register - resource managed dmaengine PCM registration + * @dev: The parent device for the PCM device + * @config: Platform specific PCM configuration + * @flags: Platform specific quirks + * + * Register a dmaengine based PCM device with automatic unregistration when the + * device is unregistered. + */ +int devm_snd_dmaengine_pcm_register(struct device *dev, + const struct snd_dmaengine_pcm_config *config, unsigned int flags) +{ + struct device **ptr; + int ret; + + ptr = devres_alloc(devm_dmaengine_pcm_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = snd_dmaengine_pcm_register(dev, config, flags); + if (ret == 0) { + *ptr = dev; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_snd_dmaengine_pcm_register); + +#endif diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 41949af3baae..5bace124ef43 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -137,10 +137,15 @@ static int dmaengine_pcm_set_runtime_hwparams(struct snd_pcm_substream *substrea hw.buffer_bytes_max = SIZE_MAX; hw.fifo_size = dma_data->fifo_size; + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) + hw.info |= SNDRV_PCM_INFO_BATCH; + ret = dma_get_slave_caps(chan, &dma_caps); if (ret == 0) { if (dma_caps.cmd_pause) hw.info |= SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME; + if (dma_caps.residue_granularity <= DMA_RESIDUE_GRANULARITY_SEGMENT) + hw.info |= SNDRV_PCM_INFO_BATCH; } return snd_soc_set_runtime_hwparams(substream, &hw); @@ -171,17 +176,35 @@ static struct dma_chan *dmaengine_pcm_compat_request_channel( { struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); struct snd_dmaengine_dai_dma_data *dma_data; + dma_filter_fn fn = NULL; dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0]) return pcm->chan[0]; - if (pcm->config->compat_request_channel) + if (pcm->config && pcm->config->compat_request_channel) return pcm->config->compat_request_channel(rtd, substream); - return snd_dmaengine_pcm_request_channel(pcm->config->compat_filter_fn, - dma_data->filter_data); + if (pcm->config) + fn = pcm->config->compat_filter_fn; + + return snd_dmaengine_pcm_request_channel(fn, dma_data->filter_data); +} + +static bool dmaengine_pcm_can_report_residue(struct dma_chan *chan) +{ + struct dma_slave_caps dma_caps; + int ret; + + ret = dma_get_slave_caps(chan, &dma_caps); + if (ret != 0) + return true; + + if (dma_caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) + return false; + + return true; } static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) @@ -236,6 +259,16 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd) max_buffer_size); if (ret) goto err_free; + + /* + * This will only return false if we know for sure that at least + * one channel does not support residue reporting. If the DMA + * driver does not implement the slave_caps API we rely having + * the NO_RESIDUE flag set manually in case residue reporting is + * not supported. + */ + if (!dmaengine_pcm_can_report_residue(pcm->chan[i])) + pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE; } return 0; @@ -245,6 +278,18 @@ err_free: return ret; } +static snd_pcm_uframes_t dmaengine_pcm_pointer( + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform); + + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) + return snd_dmaengine_pcm_pointer_no_residue(substream); + else + return snd_dmaengine_pcm_pointer(substream); +} + static const struct snd_pcm_ops dmaengine_pcm_ops = { .open = dmaengine_pcm_open, .close = snd_dmaengine_pcm_close, @@ -252,7 +297,7 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = { .hw_params = dmaengine_pcm_hw_params, .hw_free = snd_pcm_lib_free_pages, .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer, + .pointer = dmaengine_pcm_pointer, }; static const struct snd_soc_platform_driver dmaengine_pcm_platform = { @@ -262,47 +307,59 @@ static const struct snd_soc_platform_driver dmaengine_pcm_platform = { .probe_order = SND_SOC_COMP_ORDER_LATE, }; -static const struct snd_pcm_ops dmaengine_no_residue_pcm_ops = { - .open = dmaengine_pcm_open, - .close = snd_dmaengine_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = dmaengine_pcm_hw_params, - .hw_free = snd_pcm_lib_free_pages, - .trigger = snd_dmaengine_pcm_trigger, - .pointer = snd_dmaengine_pcm_pointer_no_residue, -}; - -static const struct snd_soc_platform_driver dmaengine_no_residue_pcm_platform = { - .ops = &dmaengine_no_residue_pcm_ops, - .pcm_new = dmaengine_pcm_new, - .pcm_free = dmaengine_pcm_free, - .probe_order = SND_SOC_COMP_ORDER_LATE, -}; - static const char * const dmaengine_pcm_dma_channel_names[] = { [SNDRV_PCM_STREAM_PLAYBACK] = "tx", [SNDRV_PCM_STREAM_CAPTURE] = "rx", }; -static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, - struct device *dev) +static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, + struct device *dev, const struct snd_dmaengine_pcm_config *config) { unsigned int i; + const char *name; + struct dma_chan *chan; if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || !dev->of_node) - return; + return 0; - if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) { - pcm->chan[0] = dma_request_slave_channel(dev, "rx-tx"); - pcm->chan[1] = pcm->chan[0]; - } else { - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { - pcm->chan[i] = dma_request_slave_channel(dev, - dmaengine_pcm_dma_channel_names[i]); - } + if (config && config->dma_dev) { + /* + * If this warning is seen, it probably means that your Linux + * device structure does not match your HW device structure. + * It would be best to refactor the Linux device structure to + * correctly match the HW structure. + */ + dev_warn(dev, "DMA channels sourced from device %s", + dev_name(config->dma_dev)); + dev = config->dma_dev; } + + for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; + i++) { + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + name = "rx-tx"; + else + name = dmaengine_pcm_dma_channel_names[i]; + if (config && config->chan_names[i]) + name = config->chan_names[i]; + chan = dma_request_slave_channel_reason(dev, name); + if (IS_ERR(chan)) { + if (PTR_ERR(chan) == -EPROBE_DEFER) + return -EPROBE_DEFER; + pcm->chan[i] = NULL; + } else { + pcm->chan[i] = chan; + } + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + break; + } + + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) + pcm->chan[1] = pcm->chan[0]; + + return 0; } static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm) @@ -338,14 +395,12 @@ int snd_dmaengine_pcm_register(struct device *dev, pcm->config = config; pcm->flags = flags; - dmaengine_pcm_request_chan_of(pcm, dev); + ret = dmaengine_pcm_request_chan_of(pcm, dev, config); + if (ret) + goto err_free_dma; - if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) - ret = snd_soc_add_platform(dev, &pcm->platform, - &dmaengine_no_residue_pcm_platform); - else - ret = snd_soc_add_platform(dev, &pcm->platform, - &dmaengine_pcm_platform); + ret = snd_soc_add_platform(dev, &pcm->platform, + &dmaengine_pcm_platform); if (ret) goto err_free_dma; diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 4f11d23f2062..aa886cca3ecf 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -99,14 +99,14 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, config.val_bits = data_bits; switch (control) { -#if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE) +#if IS_ENABLED(CONFIG_REGMAP_I2C) case SND_SOC_I2C: codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev), &config); break; #endif -#if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE) +#if IS_ENABLED(CONFIG_REGMAP_SPI) case SND_SOC_SPI: codec->control_data = regmap_init_spi(to_spi_device(codec->dev), &config); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 891b9a9bcbf8..47e1ce771e65 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -58,7 +58,7 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams); /* DPCM stream event, send event to FE and all active BEs. */ -static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, +int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, int event) { struct snd_soc_dpcm *dpcm; @@ -84,35 +84,117 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; int ret; - if (!soc_dai->driver->symmetric_rates && - !rtd->dai_link->symmetric_rates) - return 0; + if (soc_dai->rate && (soc_dai->driver->symmetric_rates || + rtd->dai_link->symmetric_rates)) { + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", + soc_dai->rate); - /* This can happen if multiple streams are starting simultaneously - - * the second can need to get its constraints before the first has - * picked a rate. Complain and allow the application to carry on. - */ - if (!soc_dai->rate) { - dev_warn(soc_dai->dev, - "ASoC: Not enforcing symmetric_rates due to race\n"); - return 0; + ret = snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + soc_dai->rate, soc_dai->rate); + if (ret < 0) { + dev_err(soc_dai->dev, + "ASoC: Unable to apply rate constraint: %d\n", + ret); + return ret; + } } - dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", soc_dai->rate); + if (soc_dai->channels && (soc_dai->driver->symmetric_channels || + rtd->dai_link->symmetric_channels)) { + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", + soc_dai->channels); - ret = snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - soc_dai->rate, soc_dai->rate); - if (ret < 0) { - dev_err(soc_dai->dev, - "ASoC: Unable to apply rate symmetry constraint: %d\n", - ret); - return ret; + ret = snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, + soc_dai->channels, + soc_dai->channels); + if (ret < 0) { + dev_err(soc_dai->dev, + "ASoC: Unable to apply channel symmetry constraint: %d\n", + ret); + return ret; + } + } + + if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits || + rtd->dai_link->symmetric_samplebits)) { + dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", + soc_dai->sample_bits); + + ret = snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + soc_dai->sample_bits, + soc_dai->sample_bits); + if (ret < 0) { + dev_err(soc_dai->dev, + "ASoC: Unable to apply sample bits symmetry constraint: %d\n", + ret); + return ret; + } } return 0; } +static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int rate, channels, sample_bits, symmetry; + + rate = params_rate(params); + channels = params_channels(params); + sample_bits = snd_pcm_format_physical_width(params_format(params)); + + /* reject unmatched parameters when applying symmetry */ + symmetry = cpu_dai->driver->symmetric_rates || + codec_dai->driver->symmetric_rates || + rtd->dai_link->symmetric_rates; + if (symmetry && cpu_dai->rate && cpu_dai->rate != rate) { + dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", + cpu_dai->rate, rate); + return -EINVAL; + } + + symmetry = cpu_dai->driver->symmetric_channels || + codec_dai->driver->symmetric_channels || + rtd->dai_link->symmetric_channels; + if (symmetry && cpu_dai->channels && cpu_dai->channels != channels) { + dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", + cpu_dai->channels, channels); + return -EINVAL; + } + + symmetry = cpu_dai->driver->symmetric_samplebits || + codec_dai->driver->symmetric_samplebits || + rtd->dai_link->symmetric_samplebits; + if (symmetry && cpu_dai->sample_bits && cpu_dai->sample_bits != sample_bits) { + dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", + cpu_dai->sample_bits, sample_bits); + return -EINVAL; + } + + return 0; +} + +static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_driver *cpu_driver = rtd->cpu_dai->driver; + struct snd_soc_dai_driver *codec_driver = rtd->codec_dai->driver; + struct snd_soc_dai_link *link = rtd->dai_link; + + return cpu_driver->symmetric_rates || codec_driver->symmetric_rates || + link->symmetric_rates || cpu_driver->symmetric_channels || + codec_driver->symmetric_channels || link->symmetric_channels || + cpu_driver->symmetric_samplebits || + codec_driver->symmetric_samplebits || + link->symmetric_samplebits; +} + /* * List of sample sizes that might go over the bus for parameter * application. There ought to be a wildcard sample size for things @@ -158,14 +240,15 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_runtime *runtime, cpu_stream->channels_min); hw->channels_max = min(codec_stream->channels_max, cpu_stream->channels_max); - hw->formats = codec_stream->formats & cpu_stream->formats; - hw->rates = codec_stream->rates & cpu_stream->rates; - if (codec_stream->rates - & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) - hw->rates |= cpu_stream->rates; - if (cpu_stream->rates - & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS)) - hw->rates |= codec_stream->rates; + if (hw->formats) + hw->formats &= codec_stream->formats & cpu_stream->formats; + else + hw->formats = codec_stream->formats & cpu_stream->formats; + hw->rates = snd_pcm_rate_mask_intersect(codec_stream->rates, + cpu_stream->rates); + + hw->rate_min = 0; + hw->rate_max = UINT_MAX; snd_pcm_limit_hw_rates(runtime); @@ -249,6 +332,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) &cpu_dai_drv->capture); } + if (soc_pcm_has_symmetry(substream)) + runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; + ret = -EINVAL; if (!runtime->hw.rates) { printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", @@ -396,11 +482,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) if (!codec_dai->active) codec_dai->rate = 0; - /* Muting the DAC suppresses artifacts caused during digital - * shutdown, for example from stopping clocks. - */ - snd_soc_dai_digital_mute(codec_dai, 1, substream->stream); - if (cpu_dai->driver->ops->shutdown) cpu_dai->driver->ops->shutdown(substream, cpu_dai); @@ -531,6 +612,10 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); + ret = soc_pcm_params_symmetry(substream, params); + if (ret) + goto out; + if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { ret = rtd->dai_link->ops->hw_params(substream, params); if (ret < 0) { @@ -567,9 +652,16 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } - /* store the rate for each DAIs */ + /* store the parameters for each DAIs */ cpu_dai->rate = params_rate(params); + cpu_dai->channels = params_channels(params); + cpu_dai->sample_bits = + snd_pcm_format_physical_width(params_format(params)); + codec_dai->rate = params_rate(params); + codec_dai->channels = params_channels(params); + codec_dai->sample_bits = + snd_pcm_format_physical_width(params_format(params)); out: mutex_unlock(&rtd->pcm_mutex); @@ -604,6 +696,19 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); + /* clear the corresponding DAIs parameters when going to be inactive */ + if (cpu_dai->active == 1) { + cpu_dai->rate = 0; + cpu_dai->channels = 0; + cpu_dai->sample_bits = 0; + } + + if (codec_dai->active == 1) { + codec_dai->rate = 0; + codec_dai->channels = 0; + codec_dai->sample_bits = 0; + } + /* apply codec digital mute */ if ((playback && codec_dai->playback_active == 1) || (!playback && codec_dai->capture_active == 1)) @@ -672,7 +777,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream, return ret; } - if (platform->driver->ops && platform->driver->bespoke_trigger) { + if (platform->driver->bespoke_trigger) { ret = platform->driver->bespoke_trigger(substream, cmd); if (ret < 0) return ret; @@ -780,7 +885,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe, } /* disconnect a BE and FE */ -static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) +void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm, *d; @@ -876,7 +981,7 @@ static int widget_in_list(struct snd_soc_dapm_widget_list *list, return 0; } -static int dpcm_path_get(struct snd_soc_pcm_runtime *fe, +int dpcm_path_get(struct snd_soc_pcm_runtime *fe, int stream, struct snd_soc_dapm_widget_list **list_) { struct snd_soc_dai *cpu_dai = fe->cpu_dai; @@ -898,11 +1003,6 @@ static int dpcm_path_get(struct snd_soc_pcm_runtime *fe, return paths; } -static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list) -{ - kfree(*list); -} - static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, struct snd_soc_dapm_widget_list **list_) { @@ -972,7 +1072,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, continue; /* don't connect if FE is not running */ - if (!fe->dpcm[stream].runtime) + if (!fe->dpcm[stream].runtime && !fe->fe_compr) continue; /* newly connected FE and BE */ @@ -997,7 +1097,7 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream, * Find the corresponding BE DAIs that source or sink audio to this * FE substream. */ -static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, +int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, int stream, struct snd_soc_dapm_widget_list **list, int new) { if (new) @@ -1006,7 +1106,7 @@ static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe, return dpcm_prune_paths(fe, stream, list); } -static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) +void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; @@ -1044,7 +1144,7 @@ static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe, } } -static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) +int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; int err, count = 0; @@ -1131,6 +1231,20 @@ unwind: return err; } +static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, + struct snd_soc_pcm_stream *stream) +{ + runtime->hw.rate_min = stream->rate_min; + runtime->hw.rate_max = stream->rate_max; + runtime->hw.channels_min = stream->channels_min; + runtime->hw.channels_max = stream->channels_max; + if (runtime->hw.formats) + runtime->hw.formats &= stream->formats; + else + runtime->hw.formats = stream->formats; + runtime->hw.rates = stream->rates; +} + static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -1138,21 +1252,10 @@ static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - runtime->hw.rate_min = cpu_dai_drv->playback.rate_min; - runtime->hw.rate_max = cpu_dai_drv->playback.rate_max; - runtime->hw.channels_min = cpu_dai_drv->playback.channels_min; - runtime->hw.channels_max = cpu_dai_drv->playback.channels_max; - runtime->hw.formats &= cpu_dai_drv->playback.formats; - runtime->hw.rates = cpu_dai_drv->playback.rates; - } else { - runtime->hw.rate_min = cpu_dai_drv->capture.rate_min; - runtime->hw.rate_max = cpu_dai_drv->capture.rate_max; - runtime->hw.channels_min = cpu_dai_drv->capture.channels_min; - runtime->hw.channels_max = cpu_dai_drv->capture.channels_max; - runtime->hw.formats &= cpu_dai_drv->capture.formats; - runtime->hw.rates = cpu_dai_drv->capture.rates; - } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback); + else + dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture); } static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream) @@ -1193,7 +1296,7 @@ be_err: return ret; } -static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) +int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; @@ -1254,7 +1357,7 @@ static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream) return 0; } -static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) +int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; @@ -1319,7 +1422,7 @@ static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream) return 0; } -static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) +int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; int ret; @@ -1449,7 +1552,7 @@ static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm, return ret; } -static int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, +int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd) { struct snd_soc_dpcm *dpcm; @@ -1617,7 +1720,7 @@ out: return ret; } -static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) +int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; int ret = 0; @@ -2033,10 +2136,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) int ret = 0, playback = 0, capture = 0; if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { - if (cpu_dai->driver->playback.channels_min) - playback = 1; - if (cpu_dai->driver->capture.channels_min) - capture = 1; + playback = rtd->dai_link->dpcm_playback; + capture = rtd->dai_link->dpcm_capture; } else { if (codec_dai->driver->playback.channels_min && cpu_dai->driver->playback.channels_min) diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 5e633659c1b3..7f22ca35a413 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -59,10 +59,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); static const struct snd_pcm_hardware dummy_dma_hardware = { - .formats = 0xffffffff, - .channels_min = 1, - .channels_max = UINT_MAX, - /* Random values to keep userspace happy when checking constraints */ .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER, @@ -123,6 +119,13 @@ static struct snd_soc_dai_driver dummy_dai = { }, }; +int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) +{ + if (dai->driver == &dummy_dai) + return 1; + return 0; +} + static int snd_soc_dummy_probe(struct platform_device *pdev) { int ret; diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index 21a8c954af1c..4ab442a63d7e 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -18,12 +18,14 @@ #include #include #include +#include #include #include #include #include #include #include "spdif_in_regs.h" +#include "spear_pcm.h" struct spdif_in_params { u32 format; @@ -37,6 +39,8 @@ struct spdif_in_dev { struct device *dev; void (*reset_perip)(void); int irq; + struct snd_dmaengine_dai_dma_data dma_params_rx; + struct snd_dmaengine_pcm_config config; }; static void spdif_in_configure(struct spdif_in_dev *host) @@ -53,7 +57,8 @@ static int spdif_in_dai_probe(struct snd_soc_dai *dai) { struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai); - dai->capture_dma_data = &host->dma_params; + host->dma_params_rx.filter_data = &host->dma_params; + dai->capture_dma_data = &host->dma_params_rx; return 0; } @@ -244,7 +249,6 @@ static int spdif_in_probe(struct platform_device *pdev) host->dma_params.addr = res_fifo->start; host->dma_params.max_burst = 16; host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - host->dma_params.filter = pdata->filter; host->reset_perip = pdata->reset_perip; host->dev = &pdev->dev; @@ -257,8 +261,13 @@ static int spdif_in_probe(struct platform_device *pdev) return ret; } - return devm_snd_soc_register_component(&pdev->dev, &spdif_in_component, - &spdif_in_dai, 1); + ret = devm_snd_soc_register_component(&pdev->dev, &spdif_in_component, + &spdif_in_dai, 1); + if (ret) + return ret; + + return devm_spear_pcm_platform_register(&pdev->dev, &host->config, + pdata->filter); } static struct platform_driver spdif_in_driver = { diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index b6ef6f78dc78..fe99f461aff0 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c @@ -18,10 +18,12 @@ #include #include #include +#include #include #include #include #include "spdif_out_regs.h" +#include "spear_pcm.h" struct spdif_out_params { u32 rate; @@ -35,6 +37,8 @@ struct spdif_out_dev { struct spdif_out_params saved_params; u32 running; void __iomem *io_base; + struct snd_dmaengine_dai_dma_data dma_params_tx; + struct snd_dmaengine_pcm_config config; }; static void spdif_out_configure(struct spdif_out_dev *host) @@ -244,7 +248,8 @@ static int spdif_soc_dai_probe(struct snd_soc_dai *dai) { struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai); - dai->playback_dma_data = &host->dma_params; + host->dma_params_tx.filter_data = &host->dma_params; + dai->playback_dma_data = &host->dma_params_tx; return snd_soc_add_dai_controls(dai, spdif_out_controls, ARRAY_SIZE(spdif_out_controls)); @@ -280,6 +285,7 @@ static int spdif_out_probe(struct platform_device *pdev) struct spdif_out_dev *host; struct spear_spdif_platform_data *pdata; struct resource *res; + int ret; host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); if (!host) { @@ -302,12 +308,16 @@ static int spdif_out_probe(struct platform_device *pdev) host->dma_params.addr = res->start + SPDIF_OUT_FIFO_DATA; host->dma_params.max_burst = 16; host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - host->dma_params.filter = pdata->filter; dev_set_drvdata(&pdev->dev, host); - return devm_snd_soc_register_component(&pdev->dev, &spdif_out_component, - &spdif_out_dai, 1); + ret = devm_snd_soc_register_component(&pdev->dev, &spdif_out_component, + &spdif_out_dai, 1); + if (ret) + return ret; + + return devm_spear_pcm_platform_register(&pdev->dev, &host->config, + pdata->filter); } #ifdef CONFIG_PM diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 4707f2b862c3..0e5a8f35d0ad 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -18,6 +18,7 @@ #include #include #include +#include "spear_pcm.h" static const struct snd_pcm_hardware spear_pcm_hardware = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -31,49 +32,24 @@ static const struct snd_pcm_hardware spear_pcm_hardware = { .fifo_size = 0, /* fifo size in bytes */ }; -static struct dma_chan *spear_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_substream *substream) -{ - struct spear_dma_data *dma_data; - - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - return snd_dmaengine_pcm_request_channel(dma_data->filter, dma_data); -} - static const struct snd_dmaengine_pcm_config spear_dmaengine_pcm_config = { .pcm_hardware = &spear_pcm_hardware, - .compat_request_channel = spear_pcm_request_chan, .prealloc_buffer_size = 16 * 1024, }; -static int spear_soc_platform_probe(struct platform_device *pdev) +int devm_spear_pcm_platform_register(struct device *dev, + struct snd_dmaengine_pcm_config *config, + bool (*filter)(struct dma_chan *chan, void *slave)) { - return snd_dmaengine_pcm_register(&pdev->dev, - &spear_dmaengine_pcm_config, + *config = spear_dmaengine_pcm_config; + config->compat_filter_fn = filter; + + return snd_dmaengine_pcm_register(dev, config, SND_DMAENGINE_PCM_FLAG_NO_DT | SND_DMAENGINE_PCM_FLAG_COMPAT); } - -static int spear_soc_platform_remove(struct platform_device *pdev) -{ - snd_dmaengine_pcm_unregister(&pdev->dev); - return 0; -} - -static struct platform_driver spear_pcm_driver = { - .driver = { - .name = "spear-pcm-audio", - .owner = THIS_MODULE, - }, - - .probe = spear_soc_platform_probe, - .remove = spear_soc_platform_remove, -}; - -module_platform_driver(spear_pcm_driver); +EXPORT_SYMBOL_GPL(devm_spear_pcm_platform_register); MODULE_AUTHOR("Rajeev Kumar "); MODULE_DESCRIPTION("SPEAr PCM DMA module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:spear-pcm-audio"); diff --git a/sound/soc/spear/spear_pcm.h b/sound/soc/spear/spear_pcm.h new file mode 100644 index 000000000000..9b0ca62d6f02 --- /dev/null +++ b/sound/soc/spear/spear_pcm.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SPEAR_PCM_H__ +#define __SPEAR_PCM_H__ + +int devm_spear_pcm_platform_register(struct device *dev, + struct snd_dmaengine_pcm_config *config, + bool (*filter)(struct dma_chan *chan, void *slave)); + +#endif diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index 8fc653ca3ab4..9f9c1856f822 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -1,6 +1,8 @@ config SND_SOC_TEGRA tristate "SoC Audio for the Tegra System-on-Chip" depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST + depends on COMMON_CLK + depends on RESET_CONTROLLER select REGMAP_MMIO select SND_SOC_GENERIC_DMAENGINE_PCM help @@ -116,3 +118,13 @@ config SND_SOC_TEGRA_ALC5632 help Say Y or M here if you want to add support for SoC audio on the Toshiba AC100 netbook. + +config SND_SOC_TEGRA_MAX98090 + tristate "SoC Audio support for Tegra boards using a MAX98090 codec" + depends on SND_SOC_TEGRA && I2C && GPIOLIB + select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC + select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC + select SND_SOC_MAX98090 + help + Say Y or M here if you want to add support for SoC audio on Tegra + boards using the MAX98090 codec, such as Venice2. diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 21d2550a08a4..5ae588cd96c4 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -24,6 +24,7 @@ snd-soc-tegra-wm8903-objs := tegra_wm8903.o snd-soc-tegra-wm9712-objs := tegra_wm9712.o snd-soc-tegra-trimslice-objs := trimslice.o snd-soc-tegra-alc5632-objs := tegra_alc5632.o +snd-soc-tegra-max98090-objs := tegra_max98090.o obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o @@ -31,3 +32,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o obj-$(CONFIG_SND_SOC_TEGRA_WM9712) += snd-soc-tegra-wm9712.o obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o +obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index ae27bcd586d2..cf5e1cfe818d 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -313,7 +313,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) { struct tegra20_ac97 *ac97; struct resource *mem; - u32 of_dma[2]; void __iomem *regs; int ret = 0; @@ -348,14 +347,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) goto err_clk_put; } - if (of_property_read_u32_array(pdev->dev.of_node, - "nvidia,dma-request-selector", - of_dma, 2) < 0) { - dev_err(&pdev->dev, "No DMA resource\n"); - ret = -ENODEV; - goto err_clk_put; - } - ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node, "nvidia,codec-reset-gpio", 0); if (gpio_is_valid(ac97->reset_gpio)) { @@ -380,12 +371,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ac97->capture_dma_data.maxburst = 4; - ac97->capture_dma_data.slave_id = of_dma[1]; ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ac97->playback_dma_data.maxburst = 4; - ac97->playback_dma_data.slave_id = of_dma[1]; ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); if (ret) @@ -404,7 +393,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops); if (ret) { dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret); - goto err_asoc_utils_fini; + goto err_clk_disable_unprepare; } ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component, @@ -412,7 +401,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; - goto err_asoc_utils_fini; + goto err_clk_disable_unprepare; } ret = tegra_pcm_platform_register(&pdev->dev); @@ -428,6 +417,8 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) err_unregister_component: snd_soc_unregister_component(&pdev->dev); +err_clk_disable_unprepare: + clk_disable_unprepare(ac97->clk_ac97); err_asoc_utils_fini: tegra_asoc_utils_fini(&ac97->util_data); err_clk_put: diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index 8c819f811470..42c1f6bfaf2e 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -339,9 +339,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = { static int tegra20_i2s_platform_probe(struct platform_device *pdev) { struct tegra20_i2s *i2s; - struct resource *mem, *memregion, *dmareq; - u32 of_dma[2]; - u32 dma_ch; + struct resource *mem, *memregion; void __iomem *regs; int ret; @@ -370,20 +368,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) goto err_clk_put; } - dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmareq) { - if (of_property_read_u32_array(pdev->dev.of_node, - "nvidia,dma-request-selector", - of_dma, 2) < 0) { - dev_err(&pdev->dev, "No DMA resource\n"); - ret = -ENODEV; - goto err_clk_put; - } - dma_ch = of_dma[1]; - } else { - dma_ch = dmareq->start; - } - memregion = devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), DRV_NAME); if (!memregion) { @@ -410,12 +394,10 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->capture_dma_data.maxburst = 4; - i2s->capture_dma_data.slave_id = dma_ch; i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->playback_dma_data.maxburst = 4; - i2s->playback_dma_data.slave_id = dma_ch; pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 31154338c1eb..d6f4c9940e0c 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include #include #include "tegra30_ahub.h" @@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev) } int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, - dma_addr_t *fiforeg, - unsigned int *reqsel) + char *dmachan, int dmachan_len, + dma_addr_t *fiforeg) { int channel; u32 reg, val; @@ -110,9 +110,11 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, __set_bit(channel, ahub->rx_usage); *rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel; + snprintf(dmachan, dmachan_len, "rx%d", channel); *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO + (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE); - *reqsel = ahub->dma_sel + channel; + + pm_runtime_get_sync(ahub->dev); reg = TEGRA30_AHUB_CHANNEL_CTRL + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); @@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo); @@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif) int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int reg, val; + pm_runtime_get_sync(ahub->dev); + reg = TEGRA30_AHUB_CHANNEL_CTRL + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); val = tegra30_apbif_read(reg); val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; tegra30_apbif_write(reg, val); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo); @@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif) int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int reg, val; + pm_runtime_get_sync(ahub->dev); + reg = TEGRA30_AHUB_CHANNEL_CTRL + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); val = tegra30_apbif_read(reg); val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; tegra30_apbif_write(reg, val); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo); @@ -185,8 +197,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif) EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, - dma_addr_t *fiforeg, - unsigned int *reqsel) + char *dmachan, int dmachan_len, + dma_addr_t *fiforeg) { int channel; u32 reg, val; @@ -200,9 +212,11 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, __set_bit(channel, ahub->tx_usage); *txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel; + snprintf(dmachan, dmachan_len, "tx%d", channel); *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO + (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE); - *reqsel = ahub->dma_sel + channel; + + pm_runtime_get_sync(ahub->dev); reg = TEGRA30_AHUB_CHANNEL_CTRL + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); @@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE); ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo); @@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif) int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; int reg, val; + pm_runtime_get_sync(ahub->dev); + reg = TEGRA30_AHUB_CHANNEL_CTRL + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); val = tegra30_apbif_read(reg); val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; tegra30_apbif_write(reg, val); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo); @@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif) int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; int reg, val; + pm_runtime_get_sync(ahub->dev); + reg = TEGRA30_AHUB_CHANNEL_CTRL + (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); val = tegra30_apbif_read(reg); val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; tegra30_apbif_write(reg, val); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo); @@ -280,10 +304,14 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int reg; + pm_runtime_get_sync(ahub->dev); + reg = TEGRA30_AHUB_AUDIO_RX + (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE); tegra30_audio_write(reg, 1 << txcif); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source); @@ -293,35 +321,51 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; int reg; + pm_runtime_get_sync(ahub->dev); + reg = TEGRA30_AHUB_AUDIO_RX + (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE); tegra30_audio_write(reg, 0); + pm_runtime_put(ahub->dev); + return 0; } EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); -#define CLK_LIST_MASK_TEGRA30 BIT(0) -#define CLK_LIST_MASK_TEGRA114 BIT(1) +#define MOD_LIST_MASK_TEGRA30 BIT(0) +#define MOD_LIST_MASK_TEGRA114 BIT(1) +#define MOD_LIST_MASK_TEGRA124 BIT(2) -#define CLK_LIST_MASK_TEGRA30_OR_LATER \ - (CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114) +#define MOD_LIST_MASK_TEGRA30_OR_LATER \ + (MOD_LIST_MASK_TEGRA30 | MOD_LIST_MASK_TEGRA114 | \ + MOD_LIST_MASK_TEGRA124) +#define MOD_LIST_MASK_TEGRA114_OR_LATER \ + (MOD_LIST_MASK_TEGRA114 | MOD_LIST_MASK_TEGRA124) static const struct { - const char *clk_name; - u32 clk_list_mask; -} configlink_clocks[] = { - { "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER }, - { "amx", CLK_LIST_MASK_TEGRA114 }, - { "adx", CLK_LIST_MASK_TEGRA114 }, + const char *rst_name; + u32 mod_list_mask; +} configlink_mods[] = { + { "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s3", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s4", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "dam0", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "dam1", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "dam2", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "spdif", MOD_LIST_MASK_TEGRA30_OR_LATER }, + { "amx", MOD_LIST_MASK_TEGRA114_OR_LATER }, + { "adx", MOD_LIST_MASK_TEGRA114_OR_LATER }, + { "amx1", MOD_LIST_MASK_TEGRA124 }, + { "adx1", MOD_LIST_MASK_TEGRA124 }, + { "afc0", MOD_LIST_MASK_TEGRA124 }, + { "afc1", MOD_LIST_MASK_TEGRA124 }, + { "afc2", MOD_LIST_MASK_TEGRA124 }, + { "afc3", MOD_LIST_MASK_TEGRA124 }, + { "afc4", MOD_LIST_MASK_TEGRA124 }, + { "afc5", MOD_LIST_MASK_TEGRA124 }, }; #define LAST_REG(name) \ @@ -450,17 +494,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { }; static struct tegra30_ahub_soc_data soc_data_tegra30 = { - .clk_list_mask = CLK_LIST_MASK_TEGRA30, + .mod_list_mask = MOD_LIST_MASK_TEGRA30, .set_audio_cif = tegra30_ahub_set_cif, }; static struct tegra30_ahub_soc_data soc_data_tegra114 = { - .clk_list_mask = CLK_LIST_MASK_TEGRA114, + .mod_list_mask = MOD_LIST_MASK_TEGRA114, .set_audio_cif = tegra30_ahub_set_cif, }; static struct tegra30_ahub_soc_data soc_data_tegra124 = { - .clk_list_mask = CLK_LIST_MASK_TEGRA114, + .mod_list_mask = MOD_LIST_MASK_TEGRA124, .set_audio_cif = tegra124_ahub_set_cif, }; @@ -475,10 +519,9 @@ static int tegra30_ahub_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct tegra30_ahub_soc_data *soc_data; - struct clk *clk; + struct reset_control *rst; int i; struct resource *res0, *res1, *region; - u32 of_dma[2]; void __iomem *regs_apbif, *regs_ahub; int ret = 0; @@ -495,19 +538,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev) * operate correctly, all devices on this bus must be out of reset. * Ensure that here. */ - for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { - if (!(configlink_clocks[i].clk_list_mask & - soc_data->clk_list_mask)) + for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) { + if (!(configlink_mods[i].mod_list_mask & + soc_data->mod_list_mask)) continue; - clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "Can't get clock %s\n", - configlink_clocks[i].clk_name); - ret = PTR_ERR(clk); + + rst = reset_control_get(&pdev->dev, + configlink_mods[i].rst_name); + if (IS_ERR(rst)) { + dev_err(&pdev->dev, "Can't get reset %s\n", + configlink_mods[i].rst_name); + ret = PTR_ERR(rst); goto err; } - tegra_periph_reset_deassert(clk); - clk_put(clk); + + ret = reset_control_deassert(rst); + reset_control_put(rst); + if (ret) + goto err; } ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), @@ -536,16 +584,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev) goto err_clk_put_d_audio; } - if (of_property_read_u32_array(pdev->dev.of_node, - "nvidia,dma-request-selector", - of_dma, 2) < 0) { - dev_err(&pdev->dev, - "Missing property nvidia,dma-request-selector\n"); - ret = -ENODEV; - goto err_clk_put_d_audio; - } - ahub->dma_sel = of_dma[1]; - res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res0) { dev_err(&pdev->dev, "No apbif memory resource\n"); diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index d67321d90faa..fd7ba75ed814 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -465,15 +465,15 @@ enum tegra30_ahub_rxcif { }; extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, - dma_addr_t *fiforeg, - unsigned int *reqsel); + char *dmachan, int dmachan_len, + dma_addr_t *fiforeg); extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, - dma_addr_t *fiforeg, - unsigned int *reqsel); + char *dmachan, int dmachan_len, + dma_addr_t *fiforeg); extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); @@ -502,7 +502,7 @@ void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg, struct tegra30_ahub_cif_conf *conf); struct tegra30_ahub_soc_data { - u32 clk_list_mask; + u32 mod_list_mask; void (*set_audio_cif)(struct regmap *regmap, unsigned int reg, struct tegra30_ahub_cif_conf *conf); @@ -524,7 +524,6 @@ struct tegra30_ahub { struct device *dev; struct clk *clk_d_audio; struct clk *clk_apbif; - int dma_sel; resource_size_t apbif_addr; struct regmap *regmap_apbif; struct regmap *regmap_ahub; diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 02247fee1cf7..49ad9366add8 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev) return 0; } -static int tegra30_i2s_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); - int ret; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, - &i2s->playback_dma_data.addr, - &i2s->playback_dma_data.slave_id); - i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->playback_dma_data.maxburst = 4; - tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, - i2s->playback_fifo_cif); - } else { - ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, - &i2s->capture_dma_data.addr, - &i2s->capture_dma_data.slave_id); - i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->capture_dma_data.maxburst = 4; - tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, - i2s->capture_i2s_cif); - } - - return ret; -} - -static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); - tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); - } else { - tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); - tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); - } -} - static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { @@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) } static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { - .startup = tegra30_i2s_startup, - .shutdown = tegra30_i2s_shutdown, .set_fmt = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, @@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) goto err_pm_disable; } + i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->playback_dma_data.maxburst = 4; + ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, + i2s->playback_dma_chan, + sizeof(i2s->playback_dma_chan), + &i2s->playback_dma_data.addr); + if (ret) { + dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret); + goto err_suspend; + } + ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, + i2s->playback_fifo_cif); + if (ret) { + dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); + goto err_free_tx_fifo; + } + + i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->capture_dma_data.maxburst = 4; + ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, + i2s->capture_dma_chan, + sizeof(i2s->capture_dma_chan), + &i2s->capture_dma_data.addr); + if (ret) { + dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret); + goto err_unroute_tx_fifo; + } + ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, + i2s->capture_i2s_cif); + if (ret) { + dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); + goto err_free_rx_fifo; + } + ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, &i2s->dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; - goto err_suspend; + goto err_unroute_rx_fifo; } - ret = tegra_pcm_platform_register(&pdev->dev); + ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev, + &i2s->dma_config, i2s->playback_dma_chan, + i2s->capture_dma_chan); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); goto err_unregister_component; @@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) err_unregister_component: snd_soc_unregister_component(&pdev->dev); +err_unroute_rx_fifo: + tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); +err_free_rx_fifo: + tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); +err_unroute_tx_fifo: + tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); +err_free_tx_fifo: + tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra30_i2s_runtime_suspend(&pdev->dev); @@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) tegra_pcm_platform_unregister(&pdev->dev); snd_soc_unregister_component(&pdev->dev); + tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); + tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); + + tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); + tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); + clk_put(i2s->clk_i2s); return 0; diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index 4d0b0a30dbfb..774fc6ad2026 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h @@ -238,11 +238,14 @@ struct tegra30_i2s { struct clk *clk_i2s; enum tegra30_ahub_txcif capture_i2s_cif; enum tegra30_ahub_rxcif capture_fifo_cif; + char capture_dma_chan[8]; struct snd_dmaengine_dai_dma_data capture_dma_data; enum tegra30_ahub_rxcif playback_i2s_cif; enum tegra30_ahub_txcif playback_fifo_cif; + char playback_dma_chan[8]; struct snd_dmaengine_dai_dma_data playback_dma_data; struct regmap *regmap; + struct snd_dmaengine_pcm_config dma_config; }; #endif diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c new file mode 100644 index 000000000000..0283cfb7c031 --- /dev/null +++ b/sound/soc/tegra/tegra_max98090.c @@ -0,0 +1,275 @@ +/* + * Tegra machine ASoC driver for boards using a MAX90809 CODEC. + * + * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Based on code copyright/by: + * + * Copyright (C) 2010-2012 - NVIDIA, Inc. + * Copyright (C) 2011 The AC100 Kernel Team + * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd. + * Copyright 2007 Wolfson Microelectronics PLC. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tegra_asoc_utils.h" + +#define DRV_NAME "tegra-snd-max98090" + +struct tegra_max98090 { + struct tegra_asoc_utils_data util_data; + int gpio_hp_det; +}; + +static int tegra_max98090_asoc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; + struct snd_soc_card *card = codec->card; + struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); + int srate, mclk; + int err; + + srate = params_rate(params); + switch (srate) { + case 8000: + case 16000: + case 24000: + case 32000: + case 48000: + case 64000: + case 96000: + mclk = 12288000; + break; + case 11025: + case 22050: + case 44100: + case 88200: + mclk = 11289600; + break; + default: + mclk = 12000000; + break; + } + + err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); + if (err < 0) { + dev_err(card->dev, "Can't configure clocks\n"); + return err; + } + + err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, + SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "codec_dai clock not set\n"); + return err; + } + + return 0; +} + +static struct snd_soc_ops tegra_max98090_ops = { + .hw_params = tegra_max98090_asoc_hw_params, +}; + +static struct snd_soc_jack tegra_max98090_hp_jack; + +static struct snd_soc_jack_pin tegra_max98090_hp_jack_pins[] = { + { + .pin = "Headphones", + .mask = SND_JACK_HEADPHONE, + }, +}; + +static struct snd_soc_jack_gpio tegra_max98090_hp_jack_gpio = { + .name = "Headphone detection", + .report = SND_JACK_HEADPHONE, + .debounce_time = 150, + .invert = 1, +}; + +static const struct snd_soc_dapm_widget tegra_max98090_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphones", NULL), + SND_SOC_DAPM_SPK("Speakers", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_kcontrol_new tegra_max98090_controls[] = { + SOC_DAPM_PIN_SWITCH("Speakers"), +}; + +static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = codec_dai->codec; + struct tegra_max98090 *machine = snd_soc_card_get_drvdata(codec->card); + + if (gpio_is_valid(machine->gpio_hp_det)) { + snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE, + &tegra_max98090_hp_jack); + snd_soc_jack_add_pins(&tegra_max98090_hp_jack, + ARRAY_SIZE(tegra_max98090_hp_jack_pins), + tegra_max98090_hp_jack_pins); + + tegra_max98090_hp_jack_gpio.gpio = machine->gpio_hp_det; + snd_soc_jack_add_gpios(&tegra_max98090_hp_jack, + 1, + &tegra_max98090_hp_jack_gpio); + } + + return 0; +} + +static struct snd_soc_dai_link tegra_max98090_dai = { + .name = "max98090", + .stream_name = "max98090 PCM", + .codec_dai_name = "HiFi", + .init = tegra_max98090_asoc_init, + .ops = &tegra_max98090_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, +}; + +static struct snd_soc_card snd_soc_tegra_max98090 = { + .name = "tegra-max98090", + .owner = THIS_MODULE, + .dai_link = &tegra_max98090_dai, + .num_links = 1, + .controls = tegra_max98090_controls, + .num_controls = ARRAY_SIZE(tegra_max98090_controls), + .dapm_widgets = tegra_max98090_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra_max98090_dapm_widgets), + .fully_routed = true, +}; + +static int tegra_max98090_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &snd_soc_tegra_max98090; + struct tegra_max98090 *machine; + int ret; + + machine = devm_kzalloc(&pdev->dev, + sizeof(struct tegra_max98090), GFP_KERNEL); + if (!machine) { + dev_err(&pdev->dev, "Can't allocate tegra_max98090\n"); + return -ENOMEM; + } + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, machine); + + machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); + if (machine->gpio_hp_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + + ret = snd_soc_of_parse_card_name(card, "nvidia,model"); + if (ret) + goto err; + + ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); + if (ret) + goto err; + + tegra_max98090_dai.codec_of_node = of_parse_phandle(np, + "nvidia,audio-codec", 0); + if (!tegra_max98090_dai.codec_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,audio-codec' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_max98090_dai.cpu_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); + if (!tegra_max98090_dai.cpu_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_max98090_dai.platform_of_node = tegra_max98090_dai.cpu_of_node; + + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); + if (ret) + goto err; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + goto err_fini_utils; + } + + return 0; + +err_fini_utils: + tegra_asoc_utils_fini(&machine->util_data); +err: + return ret; +} + +static int tegra_max98090_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); + + snd_soc_jack_free_gpios(&tegra_max98090_hp_jack, 1, + &tegra_max98090_hp_jack_gpio); + + snd_soc_unregister_card(card); + + tegra_asoc_utils_fini(&machine->util_data); + + return 0; +} + +static const struct of_device_id tegra_max98090_of_match[] = { + { .compatible = "nvidia,tegra-audio-max98090", }, + {}, +}; + +static struct platform_driver tegra_max98090_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = tegra_max98090_of_match, + }, + .probe = tegra_max98090_probe, + .remove = tegra_max98090_remove, +}; +module_platform_driver(tegra_max98090_driver); + +MODULE_AUTHOR("Stephen Warren "); +MODULE_DESCRIPTION("Tegra max98090 machine ASoC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_max98090_of_match); diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 7b2d23ba69b3..93caed500565 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -42,9 +42,6 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .channels_min = 2, - .channels_max = 2, .period_bytes_min = 1024, .period_bytes_max = PAGE_SIZE, .periods_min = 2, @@ -61,12 +58,23 @@ static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = { int tegra_pcm_platform_register(struct device *dev) { - return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_DT | - SND_DMAENGINE_PCM_FLAG_COMPAT); + return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 0); } EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); +int tegra_pcm_platform_register_with_chan_names(struct device *dev, + struct snd_dmaengine_pcm_config *config, + char *txdmachan, char *rxdmachan) +{ + *config = tegra_dmaengine_pcm_config; + config->dma_dev = dev->parent; + config->chan_names[0] = txdmachan; + config->chan_names[1] = rxdmachan; + + return snd_dmaengine_pcm_register(dev, config, 0); +} +EXPORT_SYMBOL_GPL(tegra_pcm_platform_register_with_chan_names); + void tegra_pcm_platform_unregister(struct device *dev) { return snd_dmaengine_pcm_unregister(dev); diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h index 68ad901714a9..7883dec748a3 100644 --- a/sound/soc/tegra/tegra_pcm.h +++ b/sound/soc/tegra/tegra_pcm.h @@ -31,7 +31,12 @@ #ifndef __TEGRA_PCM_H__ #define __TEGRA_PCM_H__ +struct snd_dmaengine_pcm_config; + int tegra_pcm_platform_register(struct device *dev); +int tegra_pcm_platform_register_with_chan_names(struct device *dev, + struct snd_dmaengine_pcm_config *config, + char *txdmachan, char *rxdmachan); void tegra_pcm_platform_unregister(struct device *dev); #endif diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 5e119630b0e0..45b57892b6a5 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -55,7 +55,6 @@ static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_dai_link tegra_wm9712_dai = { .name = "AC97 HiFi", .stream_name = "AC97 HiFi", - .cpu_dai_name = "tegra20-ac97", .codec_dai_name = "wm9712-hifi", .codec_name = "wm9712-codec", .init = tegra_wm9712_init, diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index fbd077f4de72..f0829de28708 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -40,11 +40,6 @@ static const struct snd_pcm_hardware txx9aclc_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_PAUSE, -#ifdef __BIG_ENDIAN - .formats = SNDRV_PCM_FMTBIT_S16_BE, -#else - .formats = SNDRV_PCM_FMTBIT_S16_LE, -#endif .period_bytes_min = 1024, .period_bytes_max = 8 * 1024, .periods_min = 2, diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 178d1bad6259..b3b66aa98dce 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -91,6 +91,8 @@ static int mop500_of_probe(struct platform_device *pdev, for (i = 0; i < 2; i++) { mop500_dai_links[i].cpu_of_node = msp_np[i]; mop500_dai_links[i].cpu_dai_name = NULL; + mop500_dai_links[i].platform_of_node = msp_np[i]; + mop500_dai_links[i].platform_name = NULL; mop500_dai_links[i].codec_of_node = codec_np; mop500_dai_links[i].codec_name = NULL; } diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index c6fb5cce980e..5f4807b2c007 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -17,12 +17,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include "ux500_msp_i2s.h" #include "ux500_msp_dai.h" @@ -654,16 +656,52 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream, return ret; } +static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai) +{ + struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); + struct snd_dmaengine_dai_dma_data *playback_dma_data; + struct snd_dmaengine_dai_dma_data *capture_dma_data; + + playback_dma_data = devm_kzalloc(dai->dev, + sizeof(*playback_dma_data), + GFP_KERNEL); + if (!playback_dma_data) + return -ENOMEM; + + capture_dma_data = devm_kzalloc(dai->dev, + sizeof(*capture_dma_data), + GFP_KERNEL); + if (!capture_dma_data) + return -ENOMEM; + + playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr; + capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr; + + playback_dma_data->maxburst = 4; + capture_dma_data->maxburst = 4; + + snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data); + + return 0; +} + static int ux500_msp_dai_probe(struct snd_soc_dai *dai) { struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); + struct msp_i2s_platform_data *pdata = dai->dev->platform_data; + int ret; - dai->playback_dma_data = &drvdata->msp->playback_dma_data; - dai->capture_dma_data = &drvdata->msp->capture_dma_data; + if (!pdata) { + ret = ux500_msp_dai_of_probe(dai); + return ret; + } drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; drvdata->msp->capture_dma_data.data_size = drvdata->slot_width; + snd_soc_dai_init_dma_data(dai, + &drvdata->msp->playback_dma_data, + &drvdata->msp->capture_dma_data); return 0; } @@ -680,87 +718,19 @@ static struct snd_soc_dai_ops ux500_msp_dai_ops[] = { } }; -static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { - { - .name = "ux500-msp-i2s.0", - .probe = ux500_msp_dai_probe, - .id = 0, - .suspend = NULL, - .resume = NULL, - .playback = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .capture = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .ops = ux500_msp_dai_ops, - }, - { - .name = "ux500-msp-i2s.1", - .probe = ux500_msp_dai_probe, - .id = 1, - .suspend = NULL, - .resume = NULL, - .playback = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .capture = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .ops = ux500_msp_dai_ops, - }, - { - .name = "ux500-msp-i2s.2", - .id = 2, - .probe = ux500_msp_dai_probe, - .suspend = NULL, - .resume = NULL, - .playback = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .capture = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .ops = ux500_msp_dai_ops, - }, - { - .name = "ux500-msp-i2s.3", - .probe = ux500_msp_dai_probe, - .id = 3, - .suspend = NULL, - .resume = NULL, - .playback = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .capture = { - .channels_min = UX500_MSP_MIN_CHANNELS, - .channels_max = UX500_MSP_MAX_CHANNELS, - .rates = UX500_I2S_RATES, - .formats = UX500_I2S_FORMATS, - }, - .ops = ux500_msp_dai_ops, - }, +static struct snd_soc_dai_driver ux500_msp_dai_drv = { + .probe = ux500_msp_dai_probe, + .suspend = NULL, + .resume = NULL, + .playback.channels_min = UX500_MSP_MIN_CHANNELS, + .playback.channels_max = UX500_MSP_MAX_CHANNELS, + .playback.rates = UX500_I2S_RATES, + .playback.formats = UX500_I2S_FORMATS, + .capture.channels_min = UX500_MSP_MIN_CHANNELS, + .capture.channels_max = UX500_MSP_MAX_CHANNELS, + .capture.rates = UX500_I2S_RATES, + .capture.formats = UX500_I2S_FORMATS, + .ops = ux500_msp_dai_ops, }; static const struct snd_soc_component_driver ux500_msp_component = { @@ -771,10 +741,14 @@ static const struct snd_soc_component_driver ux500_msp_component = { static int ux500_msp_drv_probe(struct platform_device *pdev) { struct ux500_msp_i2s_drvdata *drvdata; + struct msp_i2s_platform_data *pdata = pdev->dev.platform_data; + struct device_node *np = pdev->dev.of_node; int ret = 0; - dev_dbg(&pdev->dev, "%s: Enter (pdev->name = %s).\n", __func__, - pdev->name); + if (!pdata && !np) { + dev_err(&pdev->dev, "No platform data or Device Tree found\n"); + return -ENODEV; + } drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp_i2s_drvdata), @@ -826,7 +800,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, drvdata); ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, - &ux500_msp_dai_drv[drvdata->msp->id], 1); + &ux500_msp_dai_drv, 1); if (ret < 0) { dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", __func__, drvdata->msp->id); diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index 1ca8b08ae993..959d7b4edf56 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c @@ -646,6 +646,34 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) } +static int ux500_msp_i2s_of_init_msp(struct platform_device *pdev, + struct ux500_msp *msp, + struct msp_i2s_platform_data **platform_data) +{ + struct msp_i2s_platform_data *pdata; + + *platform_data = devm_kzalloc(&pdev->dev, + sizeof(struct msp_i2s_platform_data), + GFP_KERNEL); + pdata = *platform_data; + if (!pdata) + return -ENOMEM; + + msp->playback_dma_data.dma_cfg = devm_kzalloc(&pdev->dev, + sizeof(struct stedma40_chan_cfg), + GFP_KERNEL); + if (!msp->playback_dma_data.dma_cfg) + return -ENOMEM; + + msp->capture_dma_data.dma_cfg = devm_kzalloc(&pdev->dev, + sizeof(struct stedma40_chan_cfg), + GFP_KERNEL); + if (!msp->capture_dma_data.dma_cfg) + return -ENOMEM; + + return 0; +} + int ux500_msp_i2s_init_msp(struct platform_device *pdev, struct ux500_msp **msp_p, struct msp_i2s_platform_data *platform_data) @@ -653,30 +681,28 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, struct resource *res = NULL; struct device_node *np = pdev->dev.of_node; struct ux500_msp *msp; + int ret; *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); msp = *msp_p; if (!msp) return -ENOMEM; - if (np) { - if (!platform_data) { - platform_data = devm_kzalloc(&pdev->dev, - sizeof(struct msp_i2s_platform_data), GFP_KERNEL); - if (!platform_data) - return -ENOMEM; - } - } else - if (!platform_data) + if (!platform_data) { + if (np) { + ret = ux500_msp_i2s_of_init_msp(pdev, msp, + &platform_data); + if (ret) + return ret; + } else return -EINVAL; + } else { + msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx; + msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx; + msp->id = platform_data->id; + } - dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__, - pdev->name, platform_data->id); - - msp->id = platform_data->id; msp->dev = &pdev->dev; - msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx; - msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 258d0bcee0bd..875de0f68b85 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h @@ -475,7 +475,7 @@ struct ux500_msp_dma_params { }; struct ux500_msp { - enum msp_i2s_id id; + int id; void __iomem *registers; struct device *dev; struct ux500_msp_dma_params playback_dma_data; diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index ce554de5d9dc..51a66a87305a 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -28,12 +28,6 @@ #include "ux500_msp_i2s.h" #include "ux500_pcm.h" -#define UX500_PLATFORM_MIN_RATE 8000 -#define UX500_PLATFORM_MAX_RATE 48000 - -#define UX500_PLATFORM_MIN_CHANNELS 1 -#define UX500_PLATFORM_MAX_CHANNELS 8 - #define UX500_PLATFORM_PERIODS_BYTES_MIN 128 #define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE) #define UX500_PLATFORM_PERIODS_MIN 2 @@ -45,15 +39,6 @@ static const struct snd_pcm_hardware ux500_pcm_hw = { SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_PAUSE, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_S16_BE | - SNDRV_PCM_FMTBIT_U16_BE, - .rates = SNDRV_PCM_RATE_KNOT, - .rate_min = UX500_PLATFORM_MIN_RATE, - .rate_max = UX500_PLATFORM_MAX_RATE, - .channels_min = UX500_PLATFORM_MIN_CHANNELS, - .channels_max = UX500_PLATFORM_MAX_CHANNELS, .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX, .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN, .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX, @@ -65,14 +50,10 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_substream *substream) { struct snd_soc_dai *dai = rtd->cpu_dai; - struct device *dev = dai->dev; u16 per_data_width, mem_data_width; struct stedma40_chan_cfg *dma_cfg; struct ux500_msp_dma_params *dma_params; - dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id, - snd_pcm_stream_str(substream)); - dma_params = snd_soc_dai_get_dma_data(dai, substream); dma_cfg = dma_params->dma_cfg; @@ -108,26 +89,36 @@ static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream, struct dma_slave_config *slave_config) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct ux500_msp_dma_params *dma_params; - struct stedma40_chan_cfg *dma_cfg; + struct msp_i2s_platform_data *pdata = rtd->cpu_dai->dev->platform_data; + struct snd_dmaengine_dai_dma_data *snd_dma_params; + struct ux500_msp_dma_params *ste_dma_params; + dma_addr_t dma_addr; int ret; - dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - dma_cfg = dma_params->dma_cfg; + if (pdata) { + ste_dma_params = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + dma_addr = ste_dma_params->tx_rx_addr; + } else { + snd_dma_params = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + dma_addr = snd_dma_params->addr; + } ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); if (ret) return ret; slave_config->dst_maxburst = 4; - slave_config->dst_addr_width = dma_cfg->dst_info.data_width; slave_config->src_maxburst = 4; - slave_config->src_addr_width = dma_cfg->src_info.data_width; + + slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - slave_config->dst_addr = dma_params->tx_rx_addr; + slave_config->dst_addr = dma_addr; else - slave_config->src_addr = dma_params->tx_rx_addr; + slave_config->src_addr = dma_addr; return 0; } @@ -139,15 +130,25 @@ static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { .prepare_slave_config = ux500_pcm_prepare_slave_config, }; +static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = { + .compat_request_channel = ux500_pcm_request_chan, + .prepare_slave_config = ux500_pcm_prepare_slave_config, +}; + int ux500_pcm_register_platform(struct platform_device *pdev) { + const struct snd_dmaengine_pcm_config *pcm_config; + struct device_node *np = pdev->dev.of_node; int ret; - ret = snd_dmaengine_pcm_register(&pdev->dev, - &ux500_dmaengine_pcm_config, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | - SND_DMAENGINE_PCM_FLAG_COMPAT | - SND_DMAENGINE_PCM_FLAG_NO_DT); + if (np) + pcm_config = &ux500_dmaengine_of_pcm_config; + else + pcm_config = &ux500_dmaengine_pcm_config; + + ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | + SND_DMAENGINE_PCM_FLAG_COMPAT); if (ret < 0) { dev_err(&pdev->dev, "%s: ERROR: Failed to register platform '%s' (%d)!\n", diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index 8e3d9a6c7a3b..25c38afaee49 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c @@ -174,7 +174,7 @@ static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip) dac_rate_new = 8 * (ssc_rate / ssc_div); status = clk_round_rate(chip->board->dac_clk, dac_rate_new); - if (status < 0) + if (status <= 0) return status; /* Ignore difference smaller than 256 Hz. */ diff --git a/sound/usb/format.c b/sound/usb/format.c index 3525231c6b97..d244fd3703d8 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -189,8 +189,10 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof chip->usb_id == USB_ID(0x0ccd, 0x00b1)) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; - /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */ - if (rate == 16000 && chip->usb_id == USB_ID(0x041e, 0x4068)) + /* Creative VF0420/VF0470 Live Cams report 16 kHz instead of 8kHz */ + if (rate == 16000 && + (chip->usb_id == USB_ID(0x041e, 0x4064) || + chip->usb_id == USB_ID(0x041e, 0x4068))) rate = 8000; fp->rate_table[fp->nr_rates] = rate; diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index c21a3df9a0df..2c44139b4041 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -110,7 +110,7 @@ static const struct snd_pcm_hardware pcm_hw = { #define HIFACE_RATE_96000 0x4a #define HIFACE_RATE_176400 0x40 #define HIFACE_RATE_192000 0x48 -#define HIFACE_RATE_352000 0x58 +#define HIFACE_RATE_352800 0x58 #define HIFACE_RATE_384000 0x68 static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate) @@ -141,8 +141,8 @@ static int hiface_pcm_set_rate(struct pcm_runtime *rt, unsigned int rate) case 192000: rate_value = HIFACE_RATE_192000; break; - case 352000: - rate_value = HIFACE_RATE_352000; + case 352800: + rate_value = HIFACE_RATE_352800; break; case 384000: rate_value = HIFACE_RATE_384000; diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index cc2dd1f0decb..32af6b741ef5 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -322,6 +322,12 @@ static struct usbmix_name_map hercules_usb51_map[] = { { 0 } /* terminator */ }; +/* Plantronics Gamecom 780 has a broken volume control, better to disable it */ +static struct usbmix_name_map gamecom780_map[] = { + { 9, NULL }, /* FU, speaker out */ + {} +}; + /* * Control map entries */ @@ -358,6 +364,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x046d, 0x09a4), .ignore_ctl_error = 1, }, + { /* Plantronics GameCom 780 */ + .id = USB_ID(0x047f, 0xc010), + .map = gamecom780_map, + }, { /* Hercules DJ Console (Windows Edition) */ .id = USB_ID(0x06f8, 0xb000), diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index f5f0595ef9c7..f652b10ce905 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -72,16 +72,6 @@ } }, -/* Creative/Toshiba Multimedia Center SB-0500 */ -{ - USB_DEVICE(0x041e, 0x3048), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Toshiba", - .product_name = "SB-0500", - .ifnum = QUIRK_NO_INTERFACE - } -}, - /* Creative/E-Mu devices */ { USB_DEVICE(0x041e, 0x3010), @@ -91,6 +81,15 @@ .ifnum = QUIRK_NO_INTERFACE } }, +/* Creative/Toshiba Multimedia Center SB-0500 */ +{ + USB_DEVICE(0x041e, 0x3048), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Toshiba", + .product_name = "SB-0500", + .ifnum = QUIRK_NO_INTERFACE + } +}, { /* E-Mu 0202 USB */ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, @@ -2520,6 +2519,46 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_MIDI_RAW_BYTES } }, +{ + USB_DEVICE(0x1235, 0x0010), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Focusrite", + .product_name = "Saffire 6 USB", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S24_3LE, + .channels = 4, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, + .endpoint = 0x01, + .ep_attr = USB_ENDPOINT_XFER_ISOC, + .rates = SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000, + .rate_min = 44100, + .rate_max = 48000, + .nr_rates = 2, + .rate_table = (unsigned int[]) { + 44100, 48000 + } + } + }, + { + .ifnum = 1, + .type = QUIRK_MIDI_RAW_BYTES + }, + { + .ifnum = -1 + } + } + } +}, { USB_DEVICE(0x1235, 0x0018), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { @@ -2569,6 +2608,57 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_MIDI_NOVATION } }, +{ + /* + * Focusrite Scarlett 18i6 + * + * Avoid mixer creation, which otherwise fails because some of + * the interface descriptor subtypes for interface 0 are + * unknown. That should be fixed or worked-around but this at + * least allows the device to be used successfully with a DAW + * and an external mixer. See comments below about other + * ignored interfaces. + */ + USB_DEVICE(0x1235, 0x8004), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Focusrite", + .product_name = "Scarlett 18i6", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = & (const struct snd_usb_audio_quirk[]) { + { + /* InterfaceSubClass 1 (Control Device) */ + .ifnum = 0, + .type = QUIRK_IGNORE_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + /* InterfaceSubClass 1 (Control Device) */ + .ifnum = 3, + .type = QUIRK_IGNORE_INTERFACE + }, + { + .ifnum = 4, + .type = QUIRK_MIDI_STANDARD_INTERFACE + }, + { + /* InterfaceSubClass 1 (Device Firmware Update) */ + .ifnum = 5, + .type = QUIRK_IGNORE_INTERFACE + }, + { + .ifnum = -1 + } + } + } +}, /* Access Music devices */ { @@ -2670,20 +2760,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_AUDIO_ALIGN_TRANSFER, } }, -{ - USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240), - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | - USB_DEVICE_ID_MATCH_INT_CLASS | - USB_DEVICE_ID_MATCH_INT_SUBCLASS, - .bInterfaceClass = USB_CLASS_AUDIO, - .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Hauppauge", - .product_name = "HVR-850", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_AUDIO_ALIGN_TRANSFER, - } -}, { USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210), .match_flags = USB_DEVICE_ID_MATCH_DEVICE | @@ -2754,6 +2830,20 @@ YAMAHA_DEVICE(0x7010, "UB99"), .type = QUIRK_AUDIO_ALIGN_TRANSFER, } }, +{ + USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240), + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Hauppauge", + .product_name = "HVR-850", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_AUDIO_ALIGN_TRANSFER, + } +}, { USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280), .match_flags = USB_DEVICE_ID_MATCH_DEVICE | @@ -3052,58 +3142,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, -{ - /* - * Focusrite Scarlett 18i6 - * - * Avoid mixer creation, which otherwise fails because some of - * the interface descriptor subtypes for interface 0 are - * unknown. That should be fixed or worked-around but this at - * least allows the device to be used successfully with a DAW - * and an external mixer. See comments below about other - * ignored interfaces. - */ - USB_DEVICE(0x1235, 0x8004), - .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { - .vendor_name = "Focusrite", - .product_name = "Scarlett 18i6", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = & (const struct snd_usb_audio_quirk[]) { - { - /* InterfaceSubClass 1 (Control Device) */ - .ifnum = 0, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - /* InterfaceSubClass 1 (Control Device) */ - .ifnum = 3, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = 4, - .type = QUIRK_MIDI_STANDARD_INTERFACE - }, - { - /* InterfaceSubClass 1 (Device Firmware Update) */ - .ifnum = 5, - .type = QUIRK_IGNORE_INTERFACE - }, - { - .ifnum = -1 - } - } - } -}, - { /* * Some USB MIDI devices don't have an audio control interface, diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 0df9ede99dfd..89730707614c 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -660,10 +660,23 @@ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) return err; } +/* quirk for Plantronics GameCom 780 with CM6302 chip */ +static int snd_usb_gamecon780_boot_quirk(struct usb_device *dev) +{ + /* set the initial volume and don't change; other values are either + * too loud or silent due to firmware bug (bko#65251) + */ + u8 buf[2] = { 0x74, 0xdc }; + return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + UAC_FU_VOLUME << 8, 9 << 8, buf, 2); +} + /* * Novation Twitch DJ controller + * Focusrite Novation Saffire 6 USB audio card */ -static int snd_usb_twitch_boot_quirk(struct usb_device *dev) +static int snd_usb_novation_boot_quirk(struct usb_device *dev) { /* preemptively set up the device because otherwise the * raw MIDI endpoints are not active */ @@ -972,9 +985,9 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, /* Digidesign Mbox 2 */ return snd_usb_mbox2_boot_quirk(dev); - case USB_ID(0x1235, 0x0018): - /* Focusrite Novation Twitch */ - return snd_usb_twitch_boot_quirk(dev); + case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */ + case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */ + return snd_usb_novation_boot_quirk(dev); case USB_ID(0x133e, 0x0815): /* Access Music VirusTI Desktop */ @@ -986,6 +999,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, return snd_usb_nativeinstruments_boot_quirk(dev); case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ return snd_usb_fasttrackpro_boot_quirk(dev); + case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */ + return snd_usb_gamecon780_boot_quirk(dev); } return 0; diff --git a/tools/Makefile b/tools/Makefile index a9b02008443c..feec3ad5fd09 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -3,6 +3,7 @@ include scripts/Makefile.include help: @echo 'Possible targets:' @echo '' + @echo ' acpi - ACPI tools' @echo ' cgroup - cgroup tools' @echo ' cpupower - a tool for all things x86 CPU power' @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' @@ -33,16 +34,19 @@ help: @echo ' the respective build directory.' @echo ' clean: a summary clean target to clean _all_ folders' +acpi: FORCE + $(call descend,power/$@) + cpupower: FORCE $(call descend,power/$@) cgroup firewire guest usb virtio vm net: FORCE $(call descend,$@) -liblk: FORCE - $(call descend,lib/lk) +libapikfs: FORCE + $(call descend,lib/api) -perf: liblk FORCE +perf: libapikfs FORCE $(call descend,$@) selftests: FORCE @@ -54,6 +58,9 @@ turbostat x86_energy_perf_policy: FORCE tmon: FORCE $(call descend,thermal/$@) +acpi_install: + $(call descend,power/$(@:_install=),install) + cpupower_install: $(call descend,power/$(@:_install=),install) @@ -69,21 +76,24 @@ turbostat_install x86_energy_perf_policy_install: tmon_install: $(call descend,thermal/$(@:_install=),install) -install: cgroup_install cpupower_install firewire_install lguest_install \ +install: acpi_install cgroup_install cpupower_install firewire_install lguest_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install vm_install net_install x86_energy_perf_policy_install \ tmon +acpi_clean: + $(call descend,power/acpi,clean) + cpupower_clean: $(call descend,power/cpupower,clean) cgroup_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: $(call descend,$(@:_clean=),clean) -liblk_clean: - $(call descend,lib/lk,clean) +libapikfs_clean: + $(call descend,lib/api,clean) -perf_clean: liblk_clean +perf_clean: libapikfs_clean $(call descend,$(@:_clean=),clean) selftests_clean: @@ -95,8 +105,8 @@ turbostat_clean x86_energy_perf_policy_clean: tmon_clean: $(call descend,thermal/tmon,clean) -clean: cgroup_clean cpupower_clean firewire_clean lguest_clean perf_clean \ - selftests_clean turbostat_clean usb_clean virtio_clean \ +clean: acpi_clean cgroup_clean cpupower_clean firewire_clean lguest_clean \ + perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ vm_clean net_clean x86_energy_perf_policy_clean tmon_clean .PHONY: FORCE diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index b8d6d541d854..4088b816a3ee 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 8bcb04096eb2..520de3304571 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/tools/perf/util/include/asm/bug.h b/tools/include/asm/bug.h similarity index 81% rename from tools/perf/util/include/asm/bug.h rename to tools/include/asm/bug.h index 7fcc6810adc2..9e5f4846967f 100644 --- a/tools/perf/util/include/asm/bug.h +++ b/tools/include/asm/bug.h @@ -1,5 +1,7 @@ -#ifndef _PERF_ASM_GENERIC_BUG_H -#define _PERF_ASM_GENERIC_BUG_H +#ifndef _TOOLS_ASM_BUG_H +#define _TOOLS_ASM_BUG_H + +#include #define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0) @@ -19,4 +21,5 @@ __warned = 1; \ unlikely(__ret_warn_once); \ }) -#endif + +#endif /* _TOOLS_ASM_BUG_H */ diff --git a/tools/perf/util/include/linux/compiler.h b/tools/include/linux/compiler.h similarity index 64% rename from tools/perf/util/include/linux/compiler.h rename to tools/include/linux/compiler.h index b003ad7200b2..fbc6665c6d53 100644 --- a/tools/perf/util/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -1,5 +1,5 @@ -#ifndef _PERF_LINUX_COMPILER_H_ -#define _PERF_LINUX_COMPILER_H_ +#ifndef _TOOLS_LINUX_COMPILER_H_ +#define _TOOLS_LINUX_COMPILER_H_ #ifndef __always_inline # define __always_inline inline __attribute__((always_inline)) @@ -27,4 +27,12 @@ # define __weak __attribute__((weak)) #endif +#ifndef likely +# define likely(x) __builtin_expect(!!(x), 1) #endif + +#ifndef unlikely +# define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +#endif /* _TOOLS_LINUX_COMPILER_H */ diff --git a/tools/lib/lk/Makefile b/tools/lib/api/Makefile similarity index 66% rename from tools/lib/lk/Makefile rename to tools/lib/api/Makefile index 3dba0a4aebbf..ed2f51e11b80 100644 --- a/tools/lib/lk/Makefile +++ b/tools/lib/api/Makefile @@ -1,4 +1,5 @@ include ../../scripts/Makefile.include +include ../../perf/config/utilities.mak # QUIET_CLEAN CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar @@ -7,11 +8,11 @@ AR = $(CROSS_COMPILE)ar LIB_H= LIB_OBJS= -LIB_H += debugfs.h +LIB_H += fs/debugfs.h -LIB_OBJS += $(OUTPUT)debugfs.o +LIB_OBJS += $(OUTPUT)fs/debugfs.o -LIBFILE = liblk.a +LIBFILE = libapikfs.a CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC EXTLIBS = -lelf -lpthread -lrt -lm @@ -25,14 +26,17 @@ $(LIBFILE): $(LIB_OBJS) $(LIB_OBJS): $(LIB_H) -$(OUTPUT)%.o: %.c +libapi_dirs: + $(QUIET_MKDIR)mkdir -p $(OUTPUT)fs/ + +$(OUTPUT)%.o: %.c libapi_dirs $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< -$(OUTPUT)%.s: %.c +$(OUTPUT)%.s: %.c libapi_dirs $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< -$(OUTPUT)%.o: %.S +$(OUTPUT)%.o: %.S libapi_dirs $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< clean: - $(RM) $(LIB_OBJS) $(LIBFILE) + $(call QUIET_CLEAN, libapi) $(RM) $(LIB_OBJS) $(LIBFILE) .PHONY: clean diff --git a/tools/lib/lk/debugfs.c b/tools/lib/api/fs/debugfs.c similarity index 100% rename from tools/lib/lk/debugfs.c rename to tools/lib/api/fs/debugfs.c diff --git a/tools/lib/lk/debugfs.h b/tools/lib/api/fs/debugfs.h similarity index 86% rename from tools/lib/lk/debugfs.h rename to tools/lib/api/fs/debugfs.h index 935c59bdb442..f19d3df9609d 100644 --- a/tools/lib/lk/debugfs.h +++ b/tools/lib/api/fs/debugfs.h @@ -1,5 +1,5 @@ -#ifndef __LK_DEBUGFS_H__ -#define __LK_DEBUGFS_H__ +#ifndef __API_DEBUGFS_H__ +#define __API_DEBUGFS_H__ #define _STR(x) #x #define STR(x) _STR(x) @@ -26,4 +26,4 @@ char *debugfs_mount(const char *mountpoint); extern char debugfs_mountpoint[]; -#endif /* __LK_DEBUGFS_H__ */ +#endif /* __API_DEBUGFS_H__ */ diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile new file mode 100644 index 000000000000..da8b7aa3d351 --- /dev/null +++ b/tools/lib/lockdep/Makefile @@ -0,0 +1,251 @@ +# liblockdep version +LL_VERSION = 0 +LL_PATCHLEVEL = 0 +LL_EXTRAVERSION = 1 + +# file format version +FILE_VERSION = 1 + +MAKEFLAGS += --no-print-directory + + +# Makefiles suck: This macro sets a default value of $(2) for the +# variable named by $(1), unless the variable has been set by +# environment or command line. This is necessary for CC and AR +# because make sets default values, so the simpler ?= approach +# won't work as expected. +define allow-override + $(if $(or $(findstring environment,$(origin $(1))),\ + $(findstring command line,$(origin $(1)))),,\ + $(eval $(1) = $(2))) +endef + +# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix. +$(call allow-override,CC,$(CROSS_COMPILE)gcc) +$(call allow-override,AR,$(CROSS_COMPILE)ar) + +INSTALL = install + +# Use DESTDIR for installing into a different root directory. +# This is useful for building a package. The program will be +# installed in this directory as if it was the root directory. +# Then the build tool can move it later. +DESTDIR ?= +DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))' + +prefix ?= /usr/local +libdir_relative = lib +libdir = $(prefix)/$(libdir_relative) +bindir_relative = bin +bindir = $(prefix)/$(bindir_relative) + +export DESTDIR DESTDIR_SQ INSTALL + +# copy a bit from Linux kbuild + +ifeq ("$(origin V)", "command line") + VERBOSE = $(V) +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ("$(origin O)", "command line") + BUILD_OUTPUT := $(O) +endif + +ifeq ($(BUILD_SRC),) +ifneq ($(BUILD_OUTPUT),) + +define build_output + $(if $(VERBOSE:1=),@)$(MAKE) -C $(BUILD_OUTPUT) \ + BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1 +endef + +saved-output := $(BUILD_OUTPUT) +BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd) +$(if $(BUILD_OUTPUT),, \ + $(error output directory "$(saved-output)" does not exist)) + +all: sub-make + +gui: force + $(call build_output, all_cmd) + +$(filter-out gui,$(MAKECMDGOALS)): sub-make + +sub-make: force + $(call build_output, $(MAKECMDGOALS)) + + +# Leave processing to above invocation of make +skip-makefile := 1 + +endif # BUILD_OUTPUT +endif # BUILD_SRC + +# We process the rest of the Makefile if this is the final invocation of make +ifeq ($(skip-makefile),) + +srctree := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR)) +objtree := $(CURDIR) +src := $(srctree) +obj := $(objtree) + +export prefix libdir bindir src obj + +# Shell quotes +libdir_SQ = $(subst ','\'',$(libdir)) +bindir_SQ = $(subst ','\'',$(bindir)) + +LIB_FILE = liblockdep.a liblockdep.so +BIN_FILE = lockdep + +CONFIG_INCLUDES = +CONFIG_LIBS = +CONFIG_FLAGS = + +OBJ = $@ +N = + +export Q VERBOSE + +LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION) + +INCLUDES = -I. -I/usr/local/include -I./uinclude $(CONFIG_INCLUDES) + +# Set compile option CFLAGS if not set elsewhere +CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g + +override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ) + +ifeq ($(VERBOSE),1) + Q = + print_compile = + print_app_build = + print_fpic_compile = + print_shared_lib_compile = + print_install = +else + Q = @ + print_compile = echo ' CC '$(OBJ); + print_app_build = echo ' BUILD '$(OBJ); + print_fpic_compile = echo ' CC FPIC '$(OBJ); + print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ); + print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ); + print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2'; +endif + +do_fpic_compile = \ + ($(print_fpic_compile) \ + $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@) + +do_app_build = \ + ($(print_app_build) \ + $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)) + +do_compile_shared_library = \ + ($(print_shared_lib_compile) \ + $(CC) --shared $^ -o $@ -lpthread -ldl) + +do_build_static_lib = \ + ($(print_static_lib_build) \ + $(RM) $@; $(AR) rcs $@ $^) + + +define do_compile + $(print_compile) \ + $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; +endef + +$(obj)/%.o: $(src)/%.c + $(Q)$(call do_compile) + +%.o: $(src)/%.c + $(Q)$(call do_compile) + +PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o + +ALL_OBJS = $(PEVENT_LIB_OBJS) + +CMD_TARGETS = $(LIB_FILE) + +TARGETS = $(CMD_TARGETS) + + +all: all_cmd + +all_cmd: $(CMD_TARGETS) + +liblockdep.so: $(PEVENT_LIB_OBJS) + $(Q)$(do_compile_shared_library) + +liblockdep.a: $(PEVENT_LIB_OBJS) + $(Q)$(do_build_static_lib) + +$(PEVENT_LIB_OBJS): %.o: $(src)/%.c + $(Q)$(do_fpic_compile) + +## make deps + +all_objs := $(sort $(ALL_OBJS)) +all_deps := $(all_objs:%.o=.%.d) + +# let .d file also depends on the source and header files +define check_deps + @set -e; $(RM) $@; \ + $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + $(RM) $@.$$$$ +endef + +$(all_deps): .%.d: $(src)/%.c + $(Q)$(call check_deps) + +$(all_objs) : %.o : .%.d + +dep_includes := $(wildcard $(all_deps)) + +ifneq ($(dep_includes),) + include $(dep_includes) +endif + +### Detect environment changes +TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE) + +tags: force + $(RM) tags + find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \ + --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' + +TAGS: force + $(RM) TAGS + find . -name '*.[ch]' | xargs etags \ + --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' + +define do_install + $(print_install) \ + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ + fi; \ + $(INSTALL) $1 '$(DESTDIR_SQ)$2' +endef + +install_lib: all_cmd + $(Q)$(call do_install,$(LIB_FILE),$(libdir_SQ)) + $(Q)$(call do_install,$(BIN_FILE),$(bindir_SQ)) + +install: install_lib + +clean: + $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d + $(RM) tags TAGS + +endif # skip-makefile + +PHONY += force +force: + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable so we can use it in if_changed and friends. +.PHONY: $(PHONY) diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c new file mode 100644 index 000000000000..8ef602f18a32 --- /dev/null +++ b/tools/lib/lockdep/common.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include + +static __thread struct task_struct current_obj; + +/* lockdep wants these */ +bool debug_locks = true; +bool debug_locks_silent; + +__attribute__((constructor)) static void liblockdep_init(void) +{ + lockdep_init(); +} + +__attribute__((destructor)) static void liblockdep_exit(void) +{ + debug_check_no_locks_held(¤t_obj); +} + +struct task_struct *__curr(void) +{ + if (current_obj.pid == 0) { + /* Makes lockdep output pretty */ + prctl(PR_GET_NAME, current_obj.comm); + current_obj.pid = syscall(__NR_gettid); + } + + return ¤t_obj; +} diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h new file mode 100644 index 000000000000..0bda630027c3 --- /dev/null +++ b/tools/lib/lockdep/include/liblockdep/common.h @@ -0,0 +1,50 @@ +#ifndef _LIBLOCKDEP_COMMON_H +#define _LIBLOCKDEP_COMMON_H + +#include + +#define NR_LOCKDEP_CACHING_CLASSES 2 +#define MAX_LOCKDEP_SUBCLASSES 8UL + +#ifndef CALLER_ADDR0 +#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +#endif + +#ifndef _RET_IP_ +#define _RET_IP_ CALLER_ADDR0 +#endif + +#ifndef _THIS_IP_ +#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) +#endif + +struct lockdep_subclass_key { + char __one_byte; +}; + +struct lock_class_key { + struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES]; +}; + +struct lockdep_map { + struct lock_class_key *key; + struct lock_class *class_cache[NR_LOCKDEP_CACHING_CLASSES]; + const char *name; +#ifdef CONFIG_LOCK_STAT + int cpu; + unsigned long ip; +#endif +}; + +void lockdep_init_map(struct lockdep_map *lock, const char *name, + struct lock_class_key *key, int subclass); +void lock_acquire(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, + struct lockdep_map *nest_lock, unsigned long ip); +void lock_release(struct lockdep_map *lock, int nested, + unsigned long ip); + +#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ + { .name = (_name), .key = (void *)(_key), } + +#endif diff --git a/tools/lib/lockdep/include/liblockdep/mutex.h b/tools/lib/lockdep/include/liblockdep/mutex.h new file mode 100644 index 000000000000..c342f7087147 --- /dev/null +++ b/tools/lib/lockdep/include/liblockdep/mutex.h @@ -0,0 +1,70 @@ +#ifndef _LIBLOCKDEP_MUTEX_H +#define _LIBLOCKDEP_MUTEX_H + +#include +#include "common.h" + +struct liblockdep_pthread_mutex { + pthread_mutex_t mutex; + struct lockdep_map dep_map; +}; + +typedef struct liblockdep_pthread_mutex liblockdep_pthread_mutex_t; + +#define LIBLOCKDEP_PTHREAD_MUTEX_INITIALIZER(mtx) \ + (const struct liblockdep_pthread_mutex) { \ + .mutex = PTHREAD_MUTEX_INITIALIZER, \ + .dep_map = STATIC_LOCKDEP_MAP_INIT(#mtx, &((&(mtx))->dep_map)), \ +} + +static inline int __mutex_init(liblockdep_pthread_mutex_t *lock, + const char *name, + struct lock_class_key *key, + const pthread_mutexattr_t *__mutexattr) +{ + lockdep_init_map(&lock->dep_map, name, key, 0); + return pthread_mutex_init(&lock->mutex, __mutexattr); +} + +#define liblockdep_pthread_mutex_init(mutex, mutexattr) \ +({ \ + static struct lock_class_key __key; \ + \ + __mutex_init((mutex), #mutex, &__key, (mutexattr)); \ +}) + +static inline int liblockdep_pthread_mutex_lock(liblockdep_pthread_mutex_t *lock) +{ + lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); + return pthread_mutex_lock(&lock->mutex); +} + +static inline int liblockdep_pthread_mutex_unlock(liblockdep_pthread_mutex_t *lock) +{ + lock_release(&lock->dep_map, 0, (unsigned long)_RET_IP_); + return pthread_mutex_unlock(&lock->mutex); +} + +static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *lock) +{ + lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); + return pthread_mutex_trylock(&lock->mutex) == 0 ? 1 : 0; +} + +static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *lock) +{ + return pthread_mutex_destroy(&lock->mutex); +} + +#ifdef __USE_LIBLOCKDEP + +#define pthread_mutex_t liblockdep_pthread_mutex_t +#define pthread_mutex_init liblockdep_pthread_mutex_init +#define pthread_mutex_lock liblockdep_pthread_mutex_lock +#define pthread_mutex_unlock liblockdep_pthread_mutex_unlock +#define pthread_mutex_trylock liblockdep_pthread_mutex_trylock +#define pthread_mutex_destroy liblockdep_pthread_mutex_destroy + +#endif + +#endif diff --git a/tools/lib/lockdep/include/liblockdep/rwlock.h b/tools/lib/lockdep/include/liblockdep/rwlock.h new file mode 100644 index 000000000000..a680ab8c2e36 --- /dev/null +++ b/tools/lib/lockdep/include/liblockdep/rwlock.h @@ -0,0 +1,86 @@ +#ifndef _LIBLOCKDEP_RWLOCK_H +#define _LIBLOCKDEP_RWLOCK_H + +#include +#include "common.h" + +struct liblockdep_pthread_rwlock { + pthread_rwlock_t rwlock; + struct lockdep_map dep_map; +}; + +typedef struct liblockdep_pthread_rwlock liblockdep_pthread_rwlock_t; + +#define LIBLOCKDEP_PTHREAD_RWLOCK_INITIALIZER(rwl) \ + (struct liblockdep_pthread_rwlock) { \ + .rwlock = PTHREAD_RWLOCK_INITIALIZER, \ + .dep_map = STATIC_LOCKDEP_MAP_INIT(#rwl, &((&(rwl))->dep_map)), \ +} + +static inline int __rwlock_init(liblockdep_pthread_rwlock_t *lock, + const char *name, + struct lock_class_key *key, + const pthread_rwlockattr_t *attr) +{ + lockdep_init_map(&lock->dep_map, name, key, 0); + + return pthread_rwlock_init(&lock->rwlock, attr); +} + +#define liblockdep_pthread_rwlock_init(lock, attr) \ +({ \ + static struct lock_class_key __key; \ + \ + __rwlock_init((lock), #lock, &__key, (attr)); \ +}) + +static inline int liblockdep_pthread_rwlock_rdlock(liblockdep_pthread_rwlock_t *lock) +{ + lock_acquire(&lock->dep_map, 0, 0, 2, 2, NULL, (unsigned long)_RET_IP_); + return pthread_rwlock_rdlock(&lock->rwlock); + +} + +static inline int liblockdep_pthread_rwlock_unlock(liblockdep_pthread_rwlock_t *lock) +{ + lock_release(&lock->dep_map, 0, (unsigned long)_RET_IP_); + return pthread_rwlock_unlock(&lock->rwlock); +} + +static inline int liblockdep_pthread_rwlock_wrlock(liblockdep_pthread_rwlock_t *lock) +{ + lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); + return pthread_rwlock_wrlock(&lock->rwlock); +} + +static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_t *lock) +{ + lock_acquire(&lock->dep_map, 0, 1, 2, 2, NULL, (unsigned long)_RET_IP_); + return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; +} + +static inline int liblockdep_pthread_rwlock_trywlock(liblockdep_pthread_rwlock_t *lock) +{ + lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); + return pthread_rwlock_trywlock(&lock->rwlock) == 0 ? 1 : 0; +} + +static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock) +{ + return pthread_rwlock_destroy(&lock->rwlock); +} + +#ifdef __USE_LIBLOCKDEP + +#define pthread_rwlock_t liblockdep_pthread_rwlock_t +#define pthread_rwlock_init liblockdep_pthread_rwlock_init +#define pthread_rwlock_rdlock liblockdep_pthread_rwlock_rdlock +#define pthread_rwlock_unlock liblockdep_pthread_rwlock_unlock +#define pthread_rwlock_wrlock liblockdep_pthread_rwlock_wrlock +#define pthread_rwlock_tryrdlock liblockdep_pthread_rwlock_tryrdlock +#define pthread_rwlock_trywlock liblockdep_pthread_rwlock_trywlock +#define pthread_rwlock_destroy liblockdep_rwlock_destroy + +#endif + +#endif diff --git a/tools/lib/lockdep/lockdep b/tools/lib/lockdep/lockdep new file mode 100755 index 000000000000..49af9fe19f5b --- /dev/null +++ b/tools/lib/lockdep/lockdep @@ -0,0 +1,3 @@ +#!/bin/bash + +LD_PRELOAD="./liblockdep.so $LD_PRELOAD" "$@" diff --git a/tools/lib/lockdep/lockdep.c b/tools/lib/lockdep/lockdep.c new file mode 100644 index 000000000000..f42b7e9aa48f --- /dev/null +++ b/tools/lib/lockdep/lockdep.c @@ -0,0 +1,2 @@ +#include +#include "../../../kernel/locking/lockdep.c" diff --git a/tools/lib/lockdep/lockdep_internals.h b/tools/lib/lockdep/lockdep_internals.h new file mode 100644 index 000000000000..29d0c954cc24 --- /dev/null +++ b/tools/lib/lockdep/lockdep_internals.h @@ -0,0 +1 @@ +#include "../../../kernel/locking/lockdep_internals.h" diff --git a/tools/lib/lockdep/lockdep_states.h b/tools/lib/lockdep/lockdep_states.h new file mode 100644 index 000000000000..248d235efda9 --- /dev/null +++ b/tools/lib/lockdep/lockdep_states.h @@ -0,0 +1 @@ +#include "../../../kernel/locking/lockdep_states.h" diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c new file mode 100644 index 000000000000..f8465a811aa5 --- /dev/null +++ b/tools/lib/lockdep/preload.c @@ -0,0 +1,447 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include "include/liblockdep/mutex.h" +#include "../../../include/linux/rbtree.h" + +/** + * struct lock_lookup - liblockdep's view of a single unique lock + * @orig: pointer to the original pthread lock, used for lookups + * @dep_map: lockdep's dep_map structure + * @key: lockdep's key structure + * @node: rb-tree node used to store the lock in a global tree + * @name: a unique name for the lock + */ +struct lock_lookup { + void *orig; /* Original pthread lock, used for lookups */ + struct lockdep_map dep_map; /* Since all locks are dynamic, we need + * a dep_map and a key for each lock */ + /* + * Wait, there's no support for key classes? Yup :( + * Most big projects wrap the pthread api with their own calls to + * be compatible with different locking methods. This means that + * "classes" will be brokes since the function that creates all + * locks will point to a generic locking function instead of the + * actual code that wants to do the locking. + */ + struct lock_class_key key; + struct rb_node node; +#define LIBLOCKDEP_MAX_LOCK_NAME 22 + char name[LIBLOCKDEP_MAX_LOCK_NAME]; +}; + +/* This is where we store our locks */ +static struct rb_root locks = RB_ROOT; +static pthread_rwlock_t locks_rwlock = PTHREAD_RWLOCK_INITIALIZER; + +/* pthread mutex API */ + +#ifdef __GLIBC__ +extern int __pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); +extern int __pthread_mutex_lock(pthread_mutex_t *mutex); +extern int __pthread_mutex_trylock(pthread_mutex_t *mutex); +extern int __pthread_mutex_unlock(pthread_mutex_t *mutex); +extern int __pthread_mutex_destroy(pthread_mutex_t *mutex); +#else +#define __pthread_mutex_init NULL +#define __pthread_mutex_lock NULL +#define __pthread_mutex_trylock NULL +#define __pthread_mutex_unlock NULL +#define __pthread_mutex_destroy NULL +#endif +static int (*ll_pthread_mutex_init)(pthread_mutex_t *mutex, + const pthread_mutexattr_t *attr) = __pthread_mutex_init; +static int (*ll_pthread_mutex_lock)(pthread_mutex_t *mutex) = __pthread_mutex_lock; +static int (*ll_pthread_mutex_trylock)(pthread_mutex_t *mutex) = __pthread_mutex_trylock; +static int (*ll_pthread_mutex_unlock)(pthread_mutex_t *mutex) = __pthread_mutex_unlock; +static int (*ll_pthread_mutex_destroy)(pthread_mutex_t *mutex) = __pthread_mutex_destroy; + +/* pthread rwlock API */ + +#ifdef __GLIBC__ +extern int __pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr); +extern int __pthread_rwlock_destroy(pthread_rwlock_t *rwlock); +extern int __pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); +extern int __pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); +extern int __pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); +extern int __pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); +extern int __pthread_rwlock_unlock(pthread_rwlock_t *rwlock); +#else +#define __pthread_rwlock_init NULL +#define __pthread_rwlock_destroy NULL +#define __pthread_rwlock_wrlock NULL +#define __pthread_rwlock_trywrlock NULL +#define __pthread_rwlock_rdlock NULL +#define __pthread_rwlock_tryrdlock NULL +#define __pthread_rwlock_unlock NULL +#endif + +static int (*ll_pthread_rwlock_init)(pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr) = __pthread_rwlock_init; +static int (*ll_pthread_rwlock_destroy)(pthread_rwlock_t *rwlock) = __pthread_rwlock_destroy; +static int (*ll_pthread_rwlock_rdlock)(pthread_rwlock_t *rwlock) = __pthread_rwlock_rdlock; +static int (*ll_pthread_rwlock_tryrdlock)(pthread_rwlock_t *rwlock) = __pthread_rwlock_tryrdlock; +static int (*ll_pthread_rwlock_trywrlock)(pthread_rwlock_t *rwlock) = __pthread_rwlock_trywrlock; +static int (*ll_pthread_rwlock_wrlock)(pthread_rwlock_t *rwlock) = __pthread_rwlock_wrlock; +static int (*ll_pthread_rwlock_unlock)(pthread_rwlock_t *rwlock) = __pthread_rwlock_unlock; + +enum { none, prepare, done, } __init_state; +static void init_preload(void); +static void try_init_preload(void) +{ + if (!__init_state != done) + init_preload(); +} + +static struct rb_node **__get_lock_node(void *lock, struct rb_node **parent) +{ + struct rb_node **node = &locks.rb_node; + struct lock_lookup *l; + + *parent = NULL; + + while (*node) { + l = rb_entry(*node, struct lock_lookup, node); + + *parent = *node; + if (lock < l->orig) + node = &l->node.rb_left; + else if (lock > l->orig) + node = &l->node.rb_right; + else + return node; + } + + return node; +} + +#ifndef LIBLOCKDEP_STATIC_ENTRIES +#define LIBLOCKDEP_STATIC_ENTRIES 1024 +#endif + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +static struct lock_lookup __locks[LIBLOCKDEP_STATIC_ENTRIES]; +static int __locks_nr; + +static inline bool is_static_lock(struct lock_lookup *lock) +{ + return lock >= __locks && lock < __locks + ARRAY_SIZE(__locks); +} + +static struct lock_lookup *alloc_lock(void) +{ + if (__init_state != done) { + /* + * Some programs attempt to initialize and use locks in their + * allocation path. This means that a call to malloc() would + * result in locks being initialized and locked. + * + * Why is it an issue for us? dlsym() below will try allocating + * to give us the original function. Since this allocation will + * result in a locking operations, we have to let pthread deal + * with it, but we can't! we don't have the pointer to the + * original API since we're inside dlsym() trying to get it + */ + + int idx = __locks_nr++; + if (idx >= ARRAY_SIZE(__locks)) { + fprintf(stderr, + "LOCKDEP error: insufficient LIBLOCKDEP_STATIC_ENTRIES\n"); + exit(EX_UNAVAILABLE); + } + return __locks + idx; + } + + return malloc(sizeof(struct lock_lookup)); +} + +static inline void free_lock(struct lock_lookup *lock) +{ + if (likely(!is_static_lock(lock))) + free(lock); +} + +/** + * __get_lock - find or create a lock instance + * @lock: pointer to a pthread lock function + * + * Try to find an existing lock in the rbtree using the provided pointer. If + * one wasn't found - create it. + */ +static struct lock_lookup *__get_lock(void *lock) +{ + struct rb_node **node, *parent; + struct lock_lookup *l; + + ll_pthread_rwlock_rdlock(&locks_rwlock); + node = __get_lock_node(lock, &parent); + ll_pthread_rwlock_unlock(&locks_rwlock); + if (*node) { + return rb_entry(*node, struct lock_lookup, node); + } + + /* We didn't find the lock, let's create it */ + l = alloc_lock(); + if (l == NULL) + return NULL; + + l->orig = lock; + /* + * Currently the name of the lock is the ptr value of the pthread lock, + * while not optimal, it makes debugging a bit easier. + * + * TODO: Get the real name of the lock using libdwarf + */ + sprintf(l->name, "%p", lock); + lockdep_init_map(&l->dep_map, l->name, &l->key, 0); + + ll_pthread_rwlock_wrlock(&locks_rwlock); + /* This might have changed since the last time we fetched it */ + node = __get_lock_node(lock, &parent); + rb_link_node(&l->node, parent, node); + rb_insert_color(&l->node, &locks); + ll_pthread_rwlock_unlock(&locks_rwlock); + + return l; +} + +static void __del_lock(struct lock_lookup *lock) +{ + ll_pthread_rwlock_wrlock(&locks_rwlock); + rb_erase(&lock->node, &locks); + ll_pthread_rwlock_unlock(&locks_rwlock); + free_lock(lock); +} + +int pthread_mutex_init(pthread_mutex_t *mutex, + const pthread_mutexattr_t *attr) +{ + int r; + + /* + * We keep trying to init our preload module because there might be + * code in init sections that tries to touch locks before we are + * initialized, in that case we'll need to manually call preload + * to get us going. + * + * Funny enough, kernel's lockdep had the same issue, and used + * (almost) the same solution. See look_up_lock_class() in + * kernel/locking/lockdep.c for details. + */ + try_init_preload(); + + r = ll_pthread_mutex_init(mutex, attr); + if (r == 0) + /* + * We do a dummy initialization here so that lockdep could + * warn us if something fishy is going on - such as + * initializing a held lock. + */ + __get_lock(mutex); + + return r; +} + +int pthread_mutex_lock(pthread_mutex_t *mutex) +{ + int r; + + try_init_preload(); + + lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, + (unsigned long)_RET_IP_); + /* + * Here's the thing with pthread mutexes: unlike the kernel variant, + * they can fail. + * + * This means that the behaviour here is a bit different from what's + * going on in the kernel: there we just tell lockdep that we took the + * lock before actually taking it, but here we must deal with the case + * that locking failed. + * + * To do that we'll "release" the lock if locking failed - this way + * we'll get lockdep doing the correct checks when we try to take + * the lock, and if that fails - we'll be back to the correct + * state by releasing it. + */ + r = ll_pthread_mutex_lock(mutex); + if (r) + lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + int r; + + try_init_preload(); + + lock_acquire(&__get_lock(mutex)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); + r = ll_pthread_mutex_trylock(mutex); + if (r) + lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + int r; + + try_init_preload(); + + lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_); + /* + * Just like taking a lock, only in reverse! + * + * If we fail releasing the lock, tell lockdep we're holding it again. + */ + r = ll_pthread_mutex_unlock(mutex); + if (r) + lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + try_init_preload(); + + /* + * Let's see if we're releasing a lock that's held. + * + * TODO: Hook into free() and add that check there as well. + */ + debug_check_no_locks_freed(mutex, mutex + sizeof(*mutex)); + __del_lock(__get_lock(mutex)); + return ll_pthread_mutex_destroy(mutex); +} + +/* This is the rwlock part, very similar to what happened with mutex above */ +int pthread_rwlock_init(pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr) +{ + int r; + + try_init_preload(); + + r = ll_pthread_rwlock_init(rwlock, attr); + if (r == 0) + __get_lock(rwlock); + + return r; +} + +int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) +{ + try_init_preload(); + + debug_check_no_locks_freed(rwlock, rwlock + sizeof(*rwlock)); + __del_lock(__get_lock(rwlock)); + return ll_pthread_rwlock_destroy(rwlock); +} + +int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) +{ + int r; + + init_preload(); + + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 2, 2, NULL, (unsigned long)_RET_IP_); + r = ll_pthread_rwlock_rdlock(rwlock); + if (r) + lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) +{ + int r; + + init_preload(); + + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 2, 2, NULL, (unsigned long)_RET_IP_); + r = ll_pthread_rwlock_tryrdlock(rwlock); + if (r) + lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) +{ + int r; + + init_preload(); + + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); + r = ll_pthread_rwlock_trywrlock(rwlock); + if (r) + lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) +{ + int r; + + init_preload(); + + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); + r = ll_pthread_rwlock_wrlock(rwlock); + if (r) + lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); + + return r; +} + +int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) +{ + int r; + + init_preload(); + + lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); + r = ll_pthread_rwlock_unlock(rwlock); + if (r) + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); + + return r; +} + +__attribute__((constructor)) static void init_preload(void) +{ + if (__init_state != done) + return; + +#ifndef __GLIBC__ + __init_state = prepare; + + ll_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init"); + ll_pthread_mutex_lock = dlsym(RTLD_NEXT, "pthread_mutex_lock"); + ll_pthread_mutex_trylock = dlsym(RTLD_NEXT, "pthread_mutex_trylock"); + ll_pthread_mutex_unlock = dlsym(RTLD_NEXT, "pthread_mutex_unlock"); + ll_pthread_mutex_destroy = dlsym(RTLD_NEXT, "pthread_mutex_destroy"); + + ll_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init"); + ll_pthread_rwlock_destroy = dlsym(RTLD_NEXT, "pthread_rwlock_destroy"); + ll_pthread_rwlock_rdlock = dlsym(RTLD_NEXT, "pthread_rwlock_rdlock"); + ll_pthread_rwlock_tryrdlock = dlsym(RTLD_NEXT, "pthread_rwlock_tryrdlock"); + ll_pthread_rwlock_wrlock = dlsym(RTLD_NEXT, "pthread_rwlock_wrlock"); + ll_pthread_rwlock_trywrlock = dlsym(RTLD_NEXT, "pthread_rwlock_trywrlock"); + ll_pthread_rwlock_unlock = dlsym(RTLD_NEXT, "pthread_rwlock_unlock"); +#endif + + printf("%p\n", ll_pthread_mutex_trylock);fflush(stdout); + + lockdep_init(); + + __init_state = done; +} diff --git a/tools/lib/lockdep/rbtree.c b/tools/lib/lockdep/rbtree.c new file mode 100644 index 000000000000..f7f43033c8b7 --- /dev/null +++ b/tools/lib/lockdep/rbtree.c @@ -0,0 +1 @@ +#include "../../../lib/rbtree.c" diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh new file mode 100644 index 000000000000..5334ad9d39b7 --- /dev/null +++ b/tools/lib/lockdep/run_tests.sh @@ -0,0 +1,27 @@ +#! /bin/bash + +make &> /dev/null + +for i in `ls tests/*.c`; do + testname=$(basename -s .c "$i") + gcc -o tests/$testname -pthread -lpthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null + echo -ne "$testname... " + if [ $(timeout 1 ./tests/$testname | wc -l) -gt 0 ]; then + echo "PASSED!" + else + echo "FAILED!" + fi + rm tests/$testname +done + +for i in `ls tests/*.c`; do + testname=$(basename -s .c "$i") + gcc -o tests/$testname -pthread -lpthread -Iinclude $i &> /dev/null + echo -ne "(PRELOAD) $testname... " + if [ $(timeout 1 ./lockdep ./tests/$testname | wc -l) -gt 0 ]; then + echo "PASSED!" + else + echo "FAILED!" + fi + rm tests/$testname +done diff --git a/tools/lib/lockdep/tests/AA.c b/tools/lib/lockdep/tests/AA.c new file mode 100644 index 000000000000..0f782ff404ac --- /dev/null +++ b/tools/lib/lockdep/tests/AA.c @@ -0,0 +1,13 @@ +#include + +void main(void) +{ + pthread_mutex_t a, b; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + + pthread_mutex_lock(&a); + pthread_mutex_lock(&b); + pthread_mutex_lock(&a); +} diff --git a/tools/lib/lockdep/tests/ABBA.c b/tools/lib/lockdep/tests/ABBA.c new file mode 100644 index 000000000000..07f0e29d5485 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBA.c @@ -0,0 +1,13 @@ +#include +#include "common.h" + +void main(void) +{ + pthread_mutex_t a, b; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + + LOCK_UNLOCK_2(a, b); + LOCK_UNLOCK_2(b, a); +} diff --git a/tools/lib/lockdep/tests/ABBCCA.c b/tools/lib/lockdep/tests/ABBCCA.c new file mode 100644 index 000000000000..843db09ac666 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBCCA.c @@ -0,0 +1,15 @@ +#include +#include "common.h" + +void main(void) +{ + pthread_mutex_t a, b, c; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + pthread_mutex_init(&c, NULL); + + LOCK_UNLOCK_2(a, b); + LOCK_UNLOCK_2(b, c); + LOCK_UNLOCK_2(c, a); +} diff --git a/tools/lib/lockdep/tests/ABBCCDDA.c b/tools/lib/lockdep/tests/ABBCCDDA.c new file mode 100644 index 000000000000..33620e268f85 --- /dev/null +++ b/tools/lib/lockdep/tests/ABBCCDDA.c @@ -0,0 +1,17 @@ +#include +#include "common.h" + +void main(void) +{ + pthread_mutex_t a, b, c, d; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + pthread_mutex_init(&c, NULL); + pthread_mutex_init(&d, NULL); + + LOCK_UNLOCK_2(a, b); + LOCK_UNLOCK_2(b, c); + LOCK_UNLOCK_2(c, d); + LOCK_UNLOCK_2(d, a); +} diff --git a/tools/lib/lockdep/tests/ABCABC.c b/tools/lib/lockdep/tests/ABCABC.c new file mode 100644 index 000000000000..3fee51e3a68a --- /dev/null +++ b/tools/lib/lockdep/tests/ABCABC.c @@ -0,0 +1,15 @@ +#include +#include "common.h" + +void main(void) +{ + pthread_mutex_t a, b, c; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + pthread_mutex_init(&c, NULL); + + LOCK_UNLOCK_2(a, b); + LOCK_UNLOCK_2(c, a); + LOCK_UNLOCK_2(b, c); +} diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c new file mode 100644 index 000000000000..427ba562c75b --- /dev/null +++ b/tools/lib/lockdep/tests/ABCDBCDA.c @@ -0,0 +1,17 @@ +#include +#include "common.h" + +void main(void) +{ + pthread_mutex_t a, b, c, d; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + pthread_mutex_init(&c, NULL); + pthread_mutex_init(&d, NULL); + + LOCK_UNLOCK_2(a, b); + LOCK_UNLOCK_2(c, d); + LOCK_UNLOCK_2(b, c); + LOCK_UNLOCK_2(d, a); +} diff --git a/tools/lib/lockdep/tests/ABCDBDDA.c b/tools/lib/lockdep/tests/ABCDBDDA.c new file mode 100644 index 000000000000..680c6cf3e919 --- /dev/null +++ b/tools/lib/lockdep/tests/ABCDBDDA.c @@ -0,0 +1,17 @@ +#include +#include "common.h" + +void main(void) +{ + pthread_mutex_t a, b, c, d; + + pthread_mutex_init(&a, NULL); + pthread_mutex_init(&b, NULL); + pthread_mutex_init(&c, NULL); + pthread_mutex_init(&d, NULL); + + LOCK_UNLOCK_2(a, b); + LOCK_UNLOCK_2(c, d); + LOCK_UNLOCK_2(b, d); + LOCK_UNLOCK_2(d, a); +} diff --git a/tools/lib/lockdep/tests/WW.c b/tools/lib/lockdep/tests/WW.c new file mode 100644 index 000000000000..d44f77d71029 --- /dev/null +++ b/tools/lib/lockdep/tests/WW.c @@ -0,0 +1,13 @@ +#include + +void main(void) +{ + pthread_rwlock_t a, b; + + pthread_rwlock_init(&a, NULL); + pthread_rwlock_init(&b, NULL); + + pthread_rwlock_wrlock(&a); + pthread_rwlock_rdlock(&b); + pthread_rwlock_wrlock(&a); +} diff --git a/tools/lib/lockdep/tests/common.h b/tools/lib/lockdep/tests/common.h new file mode 100644 index 000000000000..d89e94d47d86 --- /dev/null +++ b/tools/lib/lockdep/tests/common.h @@ -0,0 +1,12 @@ +#ifndef _LIBLOCKDEP_TEST_COMMON_H +#define _LIBLOCKDEP_TEST_COMMON_H + +#define LOCK_UNLOCK_2(a, b) \ + do { \ + pthread_mutex_lock(&(a)); \ + pthread_mutex_lock(&(b)); \ + pthread_mutex_unlock(&(b)); \ + pthread_mutex_unlock(&(a)); \ + } while(0) + +#endif diff --git a/tools/lib/lockdep/tests/unlock_balance.c b/tools/lib/lockdep/tests/unlock_balance.c new file mode 100644 index 000000000000..0bc62de686f7 --- /dev/null +++ b/tools/lib/lockdep/tests/unlock_balance.c @@ -0,0 +1,12 @@ +#include + +void main(void) +{ + pthread_mutex_t a; + + pthread_mutex_init(&a, NULL); + + pthread_mutex_lock(&a); + pthread_mutex_unlock(&a); + pthread_mutex_unlock(&a); +} diff --git a/tools/lib/lockdep/uinclude/asm/hweight.h b/tools/lib/lockdep/uinclude/asm/hweight.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/asm/hweight.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/asm/sections.h b/tools/lib/lockdep/uinclude/asm/sections.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/asm/sections.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/bitops.h b/tools/lib/lockdep/uinclude/linux/bitops.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/bitops.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/compiler.h b/tools/lib/lockdep/uinclude/linux/compiler.h new file mode 100644 index 000000000000..7ac838a1f196 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/compiler.h @@ -0,0 +1,7 @@ +#ifndef _LIBLOCKDEP_LINUX_COMPILER_H_ +#define _LIBLOCKDEP_LINUX_COMPILER_H_ + +#define __used __attribute__((__unused__)) +#define unlikely + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/debug_locks.h b/tools/lib/lockdep/uinclude/linux/debug_locks.h new file mode 100644 index 000000000000..f38eb64df794 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/debug_locks.h @@ -0,0 +1,12 @@ +#ifndef _LIBLOCKDEP_DEBUG_LOCKS_H_ +#define _LIBLOCKDEP_DEBUG_LOCKS_H_ + +#include +#include + +#define DEBUG_LOCKS_WARN_ON(x) (x) + +extern bool debug_locks; +extern bool debug_locks_silent; + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/delay.h b/tools/lib/lockdep/uinclude/linux/delay.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/delay.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/export.h b/tools/lib/lockdep/uinclude/linux/export.h new file mode 100644 index 000000000000..6bdf3492c535 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/export.h @@ -0,0 +1,7 @@ +#ifndef _LIBLOCKDEP_LINUX_EXPORT_H_ +#define _LIBLOCKDEP_LINUX_EXPORT_H_ + +#define EXPORT_SYMBOL(sym) +#define EXPORT_SYMBOL_GPL(sym) + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/ftrace.h b/tools/lib/lockdep/uinclude/linux/ftrace.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/ftrace.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/gfp.h b/tools/lib/lockdep/uinclude/linux/gfp.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/gfp.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/hardirq.h b/tools/lib/lockdep/uinclude/linux/hardirq.h new file mode 100644 index 000000000000..c8f3f8f58729 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/hardirq.h @@ -0,0 +1,11 @@ +#ifndef _LIBLOCKDEP_LINUX_HARDIRQ_H_ +#define _LIBLOCKDEP_LINUX_HARDIRQ_H_ + +#define SOFTIRQ_BITS 0UL +#define HARDIRQ_BITS 0UL +#define SOFTIRQ_SHIFT 0UL +#define HARDIRQ_SHIFT 0UL +#define hardirq_count() 0UL +#define softirq_count() 0UL + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/hash.h b/tools/lib/lockdep/uinclude/linux/hash.h new file mode 100644 index 000000000000..0f8479858dc0 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/hash.h @@ -0,0 +1 @@ +#include "../../../include/linux/hash.h" diff --git a/tools/lib/lockdep/uinclude/linux/interrupt.h b/tools/lib/lockdep/uinclude/linux/interrupt.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/interrupt.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/irqflags.h b/tools/lib/lockdep/uinclude/linux/irqflags.h new file mode 100644 index 000000000000..6cc296f0fad0 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/irqflags.h @@ -0,0 +1,38 @@ +#ifndef _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_ +#define _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_ + +# define trace_hardirq_context(p) 0 +# define trace_softirq_context(p) 0 +# define trace_hardirqs_enabled(p) 0 +# define trace_softirqs_enabled(p) 0 +# define trace_hardirq_enter() do { } while (0) +# define trace_hardirq_exit() do { } while (0) +# define lockdep_softirq_enter() do { } while (0) +# define lockdep_softirq_exit() do { } while (0) +# define INIT_TRACE_IRQFLAGS + +# define stop_critical_timings() do { } while (0) +# define start_critical_timings() do { } while (0) + +#define raw_local_irq_disable() do { } while (0) +#define raw_local_irq_enable() do { } while (0) +#define raw_local_irq_save(flags) ((flags) = 0) +#define raw_local_irq_restore(flags) do { } while (0) +#define raw_local_save_flags(flags) ((flags) = 0) +#define raw_irqs_disabled_flags(flags) do { } while (0) +#define raw_irqs_disabled() 0 +#define raw_safe_halt() + +#define local_irq_enable() do { } while (0) +#define local_irq_disable() do { } while (0) +#define local_irq_save(flags) ((flags) = 0) +#define local_irq_restore(flags) do { } while (0) +#define local_save_flags(flags) ((flags) = 0) +#define irqs_disabled() (1) +#define irqs_disabled_flags(flags) (0) +#define safe_halt() do { } while (0) + +#define trace_lock_release(x, y) +#define trace_lock_acquire(a, b, c, d, e, f, g) + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/kallsyms.h b/tools/lib/lockdep/uinclude/linux/kallsyms.h new file mode 100644 index 000000000000..b0f2dbdf1a15 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/kallsyms.h @@ -0,0 +1,32 @@ +#ifndef _LIBLOCKDEP_LINUX_KALLSYMS_H_ +#define _LIBLOCKDEP_LINUX_KALLSYMS_H_ + +#include +#include + +#define KSYM_NAME_LEN 128 + +struct module; + +static inline const char *kallsyms_lookup(unsigned long addr, + unsigned long *symbolsize, + unsigned long *offset, + char **modname, char *namebuf) +{ + return NULL; +} + +#include +#include +static inline void print_ip_sym(unsigned long ip) +{ + char **name; + + name = backtrace_symbols((void **)&ip, 1); + + printf("%s\n", *name); + + free(name); +} + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/kern_levels.h b/tools/lib/lockdep/uinclude/linux/kern_levels.h new file mode 100644 index 000000000000..3b9bade28698 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/kern_levels.h @@ -0,0 +1,25 @@ +#ifndef __KERN_LEVELS_H__ +#define __KERN_LEVELS_H__ + +#define KERN_SOH "" /* ASCII Start Of Header */ +#define KERN_SOH_ASCII '' + +#define KERN_EMERG KERN_SOH "" /* system is unusable */ +#define KERN_ALERT KERN_SOH "" /* action must be taken immediately */ +#define KERN_CRIT KERN_SOH "" /* critical conditions */ +#define KERN_ERR KERN_SOH "" /* error conditions */ +#define KERN_WARNING KERN_SOH "" /* warning conditions */ +#define KERN_NOTICE KERN_SOH "" /* normal but significant condition */ +#define KERN_INFO KERN_SOH "" /* informational */ +#define KERN_DEBUG KERN_SOH "" /* debug-level messages */ + +#define KERN_DEFAULT KERN_SOH "" /* the default kernel loglevel */ + +/* + * Annotation for a "continued" line of log printout (only done after a + * line that had no enclosing \n). Only to be used by core/arch code + * during early bootup (a continued line is not SMP-safe otherwise). + */ +#define KERN_CONT "" + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/kernel.h b/tools/lib/lockdep/uinclude/linux/kernel.h new file mode 100644 index 000000000000..a11e3c357be7 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/kernel.h @@ -0,0 +1,44 @@ +#ifndef _LIBLOCKDEP_LINUX_KERNEL_H_ +#define _LIBLOCKDEP_LINUX_KERNEL_H_ + +#include +#include +#include +#include +#include + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member) * __mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) +#endif + +#define max(x, y) ({ \ + typeof(x) _max1 = (x); \ + typeof(y) _max2 = (y); \ + (void) (&_max1 == &_max2); \ + _max1 > _max2 ? _max1 : _max2; }) + +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) +#define WARN_ON(x) (x) +#define WARN_ON_ONCE(x) (x) +#define likely(x) (x) +#define WARN(x, y, z) (x) +#define uninitialized_var(x) x +#define __init +#define noinline +#define list_add_tail_rcu list_add_tail + +#ifndef CALLER_ADDR0 +#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +#endif + +#ifndef _RET_IP_ +#define _RET_IP_ CALLER_ADDR0 +#endif + +#ifndef _THIS_IP_ +#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) +#endif + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/kmemcheck.h b/tools/lib/lockdep/uinclude/linux/kmemcheck.h new file mode 100644 index 000000000000..94d598bc6abe --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/kmemcheck.h @@ -0,0 +1,8 @@ +#ifndef _LIBLOCKDEP_LINUX_KMEMCHECK_H_ +#define _LIBLOCKDEP_LINUX_KMEMCHECK_H_ + +static inline void kmemcheck_mark_initialized(void *address, unsigned int n) +{ +} + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/linkage.h b/tools/lib/lockdep/uinclude/linux/linkage.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/linkage.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/list.h b/tools/lib/lockdep/uinclude/linux/list.h new file mode 100644 index 000000000000..6e9ef31ed82e --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/list.h @@ -0,0 +1 @@ +#include "../../../include/linux/list.h" diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h new file mode 100644 index 000000000000..d0f5d6e50214 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/lockdep.h @@ -0,0 +1,55 @@ +#ifndef _LIBLOCKDEP_LOCKDEP_H_ +#define _LIBLOCKDEP_LOCKDEP_H_ + +#include +#include +#include +#include +#include + + +#define MAX_LOCK_DEPTH 2000UL + +#include "../../../include/linux/lockdep.h" + +struct task_struct { + u64 curr_chain_key; + int lockdep_depth; + unsigned int lockdep_recursion; + struct held_lock held_locks[MAX_LOCK_DEPTH]; + gfp_t lockdep_reclaim_gfp; + int pid; + char comm[17]; +}; + +extern struct task_struct *__curr(void); + +#define current (__curr()) + +#define debug_locks_off() 1 +#define task_pid_nr(tsk) ((tsk)->pid) + +#define KSYM_NAME_LEN 128 +#define printk printf + +#define list_del_rcu list_del + +#define atomic_t unsigned long +#define atomic_inc(x) ((*(x))++) + +static struct new_utsname *init_utsname(void) +{ + static struct new_utsname n = (struct new_utsname) { + .release = "liblockdep", + .version = LIBLOCKDEP_VERSION, + }; + + return &n; +} + +#define print_tainted() "" +#define static_obj(x) 1 + +#define debug_show_all_locks() + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/module.h b/tools/lib/lockdep/uinclude/linux/module.h new file mode 100644 index 000000000000..09c7a7be8ccc --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/module.h @@ -0,0 +1,6 @@ +#ifndef _LIBLOCKDEP_LINUX_MODULE_H_ +#define _LIBLOCKDEP_LINUX_MODULE_H_ + +#define module_param(name, type, perm) + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/mutex.h b/tools/lib/lockdep/uinclude/linux/mutex.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/mutex.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/poison.h b/tools/lib/lockdep/uinclude/linux/poison.h new file mode 100644 index 000000000000..0c27bdf14233 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/poison.h @@ -0,0 +1 @@ +#include "../../../include/linux/poison.h" diff --git a/tools/lib/lockdep/uinclude/linux/prefetch.h b/tools/lib/lockdep/uinclude/linux/prefetch.h new file mode 100644 index 000000000000..d73fe6f850ac --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/prefetch.h @@ -0,0 +1,6 @@ +#ifndef _LIBLOCKDEP_LINUX_PREFETCH_H_ +#define _LIBLOCKDEP_LINUX_PREFETCH_H + +static inline void prefetch(void *a __attribute__((unused))) { } + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/proc_fs.h b/tools/lib/lockdep/uinclude/linux/proc_fs.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/proc_fs.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/rbtree.h b/tools/lib/lockdep/uinclude/linux/rbtree.h new file mode 100644 index 000000000000..965901db4862 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/rbtree.h @@ -0,0 +1 @@ +#include "../../../include/linux/rbtree.h" diff --git a/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h b/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h new file mode 100644 index 000000000000..c3759477379c --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h @@ -0,0 +1,2 @@ +#define __always_inline +#include "../../../include/linux/rbtree_augmented.h" diff --git a/tools/lib/lockdep/uinclude/linux/rcu.h b/tools/lib/lockdep/uinclude/linux/rcu.h new file mode 100644 index 000000000000..4c99fcb5da27 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/rcu.h @@ -0,0 +1,16 @@ +#ifndef _LIBLOCKDEP_RCU_H_ +#define _LIBLOCKDEP_RCU_H_ + +int rcu_scheduler_active; + +static inline int rcu_lockdep_current_cpu_online(void) +{ + return 1; +} + +static inline int rcu_is_cpu_idle(void) +{ + return 1; +} + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/seq_file.h b/tools/lib/lockdep/uinclude/linux/seq_file.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/seq_file.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/lockdep/uinclude/linux/spinlock.h b/tools/lib/lockdep/uinclude/linux/spinlock.h new file mode 100644 index 000000000000..68c1aa2bcba5 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/spinlock.h @@ -0,0 +1,25 @@ +#ifndef _LIBLOCKDEP_SPINLOCK_H_ +#define _LIBLOCKDEP_SPINLOCK_H_ + +#include +#include + +#define arch_spinlock_t pthread_mutex_t +#define __ARCH_SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER + +static inline void arch_spin_lock(arch_spinlock_t *mutex) +{ + pthread_mutex_lock(mutex); +} + +static inline void arch_spin_unlock(arch_spinlock_t *mutex) +{ + pthread_mutex_unlock(mutex); +} + +static inline bool arch_spin_is_locked(arch_spinlock_t *mutex) +{ + return true; +} + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/stacktrace.h b/tools/lib/lockdep/uinclude/linux/stacktrace.h new file mode 100644 index 000000000000..39aecc6b19d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/stacktrace.h @@ -0,0 +1,32 @@ +#ifndef _LIBLOCKDEP_LINUX_STACKTRACE_H_ +#define _LIBLOCKDEP_LINUX_STACKTRACE_H_ + +#include + +struct stack_trace { + unsigned int nr_entries, max_entries; + unsigned long *entries; + int skip; +}; + +static inline void print_stack_trace(struct stack_trace *trace, int spaces) +{ + backtrace_symbols_fd((void **)trace->entries, trace->nr_entries, 1); +} + +#define save_stack_trace(trace) \ + ((trace)->nr_entries = \ + backtrace((void **)(trace)->entries, (trace)->max_entries)) + +static inline int dump_stack(void) +{ + void *array[64]; + size_t size; + + size = backtrace(array, 64); + backtrace_symbols_fd(array, size, 1); + + return 0; +} + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/stringify.h b/tools/lib/lockdep/uinclude/linux/stringify.h new file mode 100644 index 000000000000..05dfcd1ac118 --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/stringify.h @@ -0,0 +1,7 @@ +#ifndef _LIBLOCKDEP_LINUX_STRINGIFY_H_ +#define _LIBLOCKDEP_LINUX_STRINGIFY_H_ + +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + +#endif diff --git a/tools/lib/lockdep/uinclude/linux/types.h b/tools/lib/lockdep/uinclude/linux/types.h new file mode 100644 index 000000000000..929938f426de --- /dev/null +++ b/tools/lib/lockdep/uinclude/linux/types.h @@ -0,0 +1,58 @@ +#ifndef _LIBLOCKDEP_LINUX_TYPES_H_ +#define _LIBLOCKDEP_LINUX_TYPES_H_ + +#include +#include + +#define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */ +#include + +struct page; +struct kmem_cache; + +typedef unsigned gfp_t; + +typedef __u64 u64; +typedef __s64 s64; + +typedef __u32 u32; +typedef __s32 s32; + +typedef __u16 u16; +typedef __s16 s16; + +typedef __u8 u8; +typedef __s8 s8; + +#ifdef __CHECKER__ +#define __bitwise__ __attribute__((bitwise)) +#else +#define __bitwise__ +#endif +#ifdef __CHECK_ENDIAN__ +#define __bitwise __bitwise__ +#else +#define __bitwise +#endif + + +typedef __u16 __bitwise __le16; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __le32; +typedef __u32 __bitwise __be32; +typedef __u64 __bitwise __le64; +typedef __u64 __bitwise __be64; + +struct list_head { + struct list_head *next, *prev; +}; + +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +#endif diff --git a/tools/lib/lockdep/uinclude/trace/events/lock.h b/tools/lib/lockdep/uinclude/trace/events/lock.h new file mode 100644 index 000000000000..fab00ff936d1 --- /dev/null +++ b/tools/lib/lockdep/uinclude/trace/events/lock.h @@ -0,0 +1,3 @@ + +/* empty file */ + diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c new file mode 100644 index 000000000000..18bc271a4bbc --- /dev/null +++ b/tools/lib/symbol/kallsyms.c @@ -0,0 +1,58 @@ +#include "symbol/kallsyms.h" +#include +#include + +int kallsyms__parse(const char *filename, void *arg, + int (*process_symbol)(void *arg, const char *name, + char type, u64 start)) +{ + char *line = NULL; + size_t n; + int err = -1; + FILE *file = fopen(filename, "r"); + + if (file == NULL) + goto out_failure; + + err = 0; + + while (!feof(file)) { + u64 start; + int line_len, len; + char symbol_type; + char *symbol_name; + + line_len = getline(&line, &n, file); + if (line_len < 0 || !line) + break; + + line[--line_len] = '\0'; /* \n */ + + len = hex2u64(line, &start); + + len++; + if (len + 2 >= line_len) + continue; + + symbol_type = line[len]; + len += 2; + symbol_name = line + len; + len = line_len - len; + + if (len >= KSYM_NAME_LEN) { + err = -1; + break; + } + + err = process_symbol(arg, symbol_name, symbol_type, start); + if (err) + break; + } + + free(line); + fclose(file); + return err; + +out_failure: + return -1; +} diff --git a/tools/lib/symbol/kallsyms.h b/tools/lib/symbol/kallsyms.h new file mode 100644 index 000000000000..6084f5e18b3c --- /dev/null +++ b/tools/lib/symbol/kallsyms.h @@ -0,0 +1,24 @@ +#ifndef __TOOLS_KALLSYMS_H_ +#define __TOOLS_KALLSYMS_H_ 1 + +#include +#include +#include + +#ifndef KSYM_NAME_LEN +#define KSYM_NAME_LEN 256 +#endif + +static inline u8 kallsyms2elf_type(char type) +{ + if (type == 'W') + return STB_WEAK; + + return isupper(type) ? STB_GLOBAL : STB_LOCAL; +} + +int kallsyms__parse(const char *filename, void *arg, + int (*process_symbol)(void *arg, const char *name, + char type, u64 start)); + +#endif /* __TOOLS_KALLSYMS_H_ */ diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index fc1502098595..005c9cc06935 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -43,6 +43,32 @@ man_dir_SQ = '$(subst ','\'',$(man_dir))' export man_dir man_dir_SQ INSTALL export DESTDIR DESTDIR_SQ +set_plugin_dir := 1 + +# Set plugin_dir to preffered global plugin location +# If we install under $HOME directory we go under +# $(HOME)/.traceevent/plugins +# +# We dont set PLUGIN_DIR in case we install under $HOME +# directory, because by default the code looks under: +# $(HOME)/.traceevent/plugins by default. +# +ifeq ($(plugin_dir),) +ifeq ($(prefix),$(HOME)) +override plugin_dir = $(HOME)/.traceevent/plugins +set_plugin_dir := 0 +else +override plugin_dir = $(prefix)/lib/traceevent/plugins +endif +endif + +ifeq ($(set_plugin_dir),1) +PLUGIN_DIR = -DPLUGIN_DIR="$(plugin_dir)" +PLUGIN_DIR_SQ = '$(subst ','\'',$(PLUGIN_DIR))' +endif + +include $(if $(BUILD_SRC),$(BUILD_SRC)/)../../scripts/Makefile.include + # copy a bit from Linux kbuild ifeq ("$(origin V)", "command line") @@ -57,18 +83,13 @@ ifeq ("$(origin O)", "command line") endif ifeq ($(BUILD_SRC),) -ifneq ($(BUILD_OUTPUT),) +ifneq ($(OUTPUT),) define build_output - $(if $(VERBOSE:1=),@)+$(MAKE) -C $(BUILD_OUTPUT) \ - BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1 + $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \ + BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1 endef -saved-output := $(BUILD_OUTPUT) -BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd) -$(if $(BUILD_OUTPUT),, \ - $(error output directory "$(saved-output)" does not exist)) - all: sub-make $(MAKECMDGOALS): sub-make @@ -80,7 +101,7 @@ sub-make: force # Leave processing to above invocation of make skip-makefile := 1 -endif # BUILD_OUTPUT +endif # OUTPUT endif # BUILD_SRC # We process the rest of the Makefile if this is the final invocation of make @@ -96,6 +117,7 @@ export prefix bindir src obj # Shell quotes bindir_SQ = $(subst ','\'',$(bindir)) bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) +plugin_dir_SQ = $(subst ','\'',$(plugin_dir)) LIB_FILE = libtraceevent.a libtraceevent.so @@ -114,7 +136,7 @@ export Q VERBOSE EVENT_PARSE_VERSION = $(EP_VERSION).$(EP_PATCHLEVEL).$(EP_EXTRAVERSION) -INCLUDES = -I. $(CONFIG_INCLUDES) +INCLUDES = -I. -I $(srctree)/../../include $(CONFIG_INCLUDES) # Set compile option CFLAGS if not set elsewhere CFLAGS ?= -g -Wall @@ -125,41 +147,14 @@ override CFLAGS += $(udis86-flags) -D_GNU_SOURCE ifeq ($(VERBOSE),1) Q = - print_compile = - print_app_build = - print_fpic_compile = - print_shared_lib_compile = - print_plugin_obj_compile = - print_plugin_build = - print_install = else Q = @ - print_compile = echo ' CC '$(OBJ); - print_app_build = echo ' BUILD '$(OBJ); - print_fpic_compile = echo ' CC FPIC '$(OBJ); - print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ); - print_plugin_obj_compile = echo ' BUILD PLUGIN OBJ '$(OBJ); - print_plugin_build = echo ' BUILD PLUGIN '$(OBJ); - print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ); - print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2'; endif -do_fpic_compile = \ - ($(print_fpic_compile) \ - $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@) - -do_app_build = \ - ($(print_app_build) \ - $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)) - do_compile_shared_library = \ ($(print_shared_lib_compile) \ $(CC) --shared $^ -o $@) -do_compile_plugin_obj = \ - ($(print_plugin_obj_compile) \ - $(CC) -c $(CFLAGS) -fPIC -o $@ $<) - do_plugin_build = \ ($(print_plugin_build) \ $(CC) $(CFLAGS) -shared -nostartfiles -o $@ $<) @@ -169,23 +164,37 @@ do_build_static_lib = \ $(RM) $@; $(AR) rcs $@ $^) -define do_compile - $(print_compile) \ - $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; -endef +do_compile = $(QUIET_CC)$(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@; $(obj)/%.o: $(src)/%.c - $(Q)$(call do_compile) + $(call do_compile) %.o: $(src)/%.c - $(Q)$(call do_compile) + $(call do_compile) -PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o +PEVENT_LIB_OBJS = event-parse.o +PEVENT_LIB_OBJS += event-plugin.o +PEVENT_LIB_OBJS += trace-seq.o +PEVENT_LIB_OBJS += parse-filter.o +PEVENT_LIB_OBJS += parse-utils.o PEVENT_LIB_OBJS += kbuffer-parse.o -ALL_OBJS = $(PEVENT_LIB_OBJS) +PLUGIN_OBJS = plugin_jbd2.o +PLUGIN_OBJS += plugin_hrtimer.o +PLUGIN_OBJS += plugin_kmem.o +PLUGIN_OBJS += plugin_kvm.o +PLUGIN_OBJS += plugin_mac80211.o +PLUGIN_OBJS += plugin_sched_switch.o +PLUGIN_OBJS += plugin_function.o +PLUGIN_OBJS += plugin_xen.o +PLUGIN_OBJS += plugin_scsi.o +PLUGIN_OBJS += plugin_cfg80211.o -CMD_TARGETS = $(LIB_FILE) +PLUGINS := $(PLUGIN_OBJS:.o=.so) + +ALL_OBJS = $(PEVENT_LIB_OBJS) $(PLUGIN_OBJS) + +CMD_TARGETS = $(LIB_FILE) $(PLUGINS) TARGETS = $(CMD_TARGETS) @@ -195,32 +204,40 @@ all: all_cmd all_cmd: $(CMD_TARGETS) libtraceevent.so: $(PEVENT_LIB_OBJS) - $(Q)$(do_compile_shared_library) + $(QUIET_LINK)$(CC) --shared $^ -o $@ libtraceevent.a: $(PEVENT_LIB_OBJS) - $(Q)$(do_build_static_lib) + $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ + +plugins: $(PLUGINS) $(PEVENT_LIB_OBJS): %.o: $(src)/%.c TRACEEVENT-CFLAGS - $(Q)$(do_fpic_compile) + $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@ + +$(PLUGIN_OBJS): %.o : $(src)/%.c + $(QUIET_CC_FPIC)$(CC) -c $(CFLAGS) -fPIC -o $@ $< + +$(PLUGINS): %.so: %.o + $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $< define make_version.h - (echo '/* This file is automatically generated. Do not modify. */'; \ - echo \#define VERSION_CODE $(shell \ - expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ - echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ - echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ - echo '#define FILE_VERSION '$(FILE_VERSION); \ - ) > $1 + (echo '/* This file is automatically generated. Do not modify. */'; \ + echo \#define VERSION_CODE $(shell \ + expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ + echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ + echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ + echo '#define FILE_VERSION '$(FILE_VERSION); \ + ) > $1 endef define update_version.h - ($(call make_version.h, $@.tmp); \ - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ - rm -f $@.tmp; \ - else \ - echo ' UPDATE $@'; \ - mv -f $@.tmp $@; \ - fi); + ($(call make_version.h, $@.tmp); \ + if [ -r $@ ] && cmp -s $@ $@.tmp; then \ + rm -f $@.tmp; \ + else \ + echo ' UPDATE $@'; \ + mv -f $@.tmp $@; \ + fi); endef ep_version.h: force @@ -229,13 +246,13 @@ ep_version.h: force VERSION_FILES = ep_version.h define update_dir - (echo $1 > $@.tmp; \ - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ - rm -f $@.tmp; \ - else \ - echo ' UPDATE $@'; \ - mv -f $@.tmp $@; \ - fi); + (echo $1 > $@.tmp; \ + if [ -r $@ ] && cmp -s $@ $@.tmp; then \ + rm -f $@.tmp; \ + else \ + echo ' UPDATE $@'; \ + mv -f $@.tmp $@; \ + fi); endef ## make deps @@ -245,10 +262,10 @@ all_deps := $(all_objs:%.o=.%.d) # let .d file also depends on the source and header files define check_deps - @set -e; $(RM) $@; \ - $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - $(RM) $@.$$$$ + @set -e; $(RM) $@; \ + $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + $(RM) $@.$$$$ endef $(all_deps): .%.d: $(src)/%.c @@ -283,27 +300,41 @@ TAGS: force --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' define do_install - $(print_install) \ if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ fi; \ $(INSTALL) $1 '$(DESTDIR_SQ)$2' endef -install_lib: all_cmd - $(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ)) +define do_install_plugins + for plugin in $1; do \ + $(call do_install,$$plugin,$(plugin_dir_SQ)); \ + done +endef + +install_lib: all_cmd install_plugins + $(call QUIET_INSTALL, $(LIB_FILE)) \ + $(call do_install,$(LIB_FILE),$(bindir_SQ)) + +install_plugins: $(PLUGINS) + $(call QUIET_INSTALL, trace_plugins) \ + $(call do_install_plugins, $(PLUGINS)) install: install_lib clean: - $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d - $(RM) TRACEEVENT-CFLAGS tags TAGS + $(call QUIET_CLEAN, libtraceevent) \ + $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d \ + $(RM) TRACEEVENT-CFLAGS tags TAGS endif # skip-makefile -PHONY += force +PHONY += force plugins force: +plugins: + @echo > /dev/null + # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable so we can use it in if_changed and friends. .PHONY: $(PHONY) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 217c82ee3665..1587ea392ad6 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -2710,7 +2710,6 @@ process_func_handler(struct event_format *event, struct pevent_function_handler struct print_arg *farg; enum event_type type; char *token; - const char *test; int i; arg->type = PRINT_FUNC; @@ -2727,15 +2726,19 @@ process_func_handler(struct event_format *event, struct pevent_function_handler } type = process_arg(event, farg, &token); - if (i < (func->nr_args - 1)) - test = ","; - else - test = ")"; - - if (test_type_token(type, token, EVENT_DELIM, test)) { - free_arg(farg); - free_token(token); - return EVENT_ERROR; + if (i < (func->nr_args - 1)) { + if (type != EVENT_DELIM || strcmp(token, ",") != 0) { + warning("Error: function '%s()' expects %d arguments but event %s only uses %d", + func->name, func->nr_args, + event->name, i + 1); + goto err; + } + } else { + if (type != EVENT_DELIM || strcmp(token, ")") != 0) { + warning("Error: function '%s()' only expects %d arguments but event %s has more", + func->name, func->nr_args, event->name); + goto err; + } } *next_arg = farg; @@ -2747,6 +2750,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler *tok = token; return type; + +err: + free_arg(farg); + free_token(token); + return EVENT_ERROR; } static enum event_type @@ -4099,6 +4107,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event unsigned long long val; struct func_map *func; const char *saveptr; + struct trace_seq p; char *bprint_fmt = NULL; char format[32]; int show_func; @@ -4306,8 +4315,12 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event format[len] = 0; if (!len_as_arg) len_arg = -1; - print_str_arg(s, data, size, event, + /* Use helper trace_seq */ + trace_seq_init(&p); + print_str_arg(&p, data, size, event, format, len_arg, arg); + trace_seq_terminate(&p); + trace_seq_puts(s, p.buffer); arg = arg->next; break; default: @@ -5116,8 +5129,38 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp, return ret; } +static enum pevent_errno +__pevent_parse_event(struct pevent *pevent, + struct event_format **eventp, + const char *buf, unsigned long size, + const char *sys) +{ + int ret = __pevent_parse_format(eventp, pevent, buf, size, sys); + struct event_format *event = *eventp; + + if (event == NULL) + return ret; + + if (pevent && add_event(pevent, event)) { + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto event_add_failed; + } + +#define PRINT_ARGS 0 + if (PRINT_ARGS && event->print_fmt.args) + print_args(event->print_fmt.args); + + return 0; + +event_add_failed: + pevent_free_format(event); + return ret; +} + /** * pevent_parse_format - parse the event format + * @pevent: the handle to the pevent + * @eventp: returned format * @buf: the buffer storing the event format string * @size: the size of @buf * @sys: the system the event belongs to @@ -5129,10 +5172,12 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp, * * /sys/kernel/debug/tracing/events/.../.../format */ -enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf, +enum pevent_errno pevent_parse_format(struct pevent *pevent, + struct event_format **eventp, + const char *buf, unsigned long size, const char *sys) { - return __pevent_parse_format(eventp, NULL, buf, size, sys); + return __pevent_parse_event(pevent, eventp, buf, size, sys); } /** @@ -5153,25 +5198,7 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, unsigned long size, const char *sys) { struct event_format *event = NULL; - int ret = __pevent_parse_format(&event, pevent, buf, size, sys); - - if (event == NULL) - return ret; - - if (add_event(pevent, event)) { - ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; - goto event_add_failed; - } - -#define PRINT_ARGS 0 - if (PRINT_ARGS && event->print_fmt.args) - print_args(event->print_fmt.args); - - return 0; - -event_add_failed: - pevent_free_format(event); - return ret; + return __pevent_parse_event(pevent, &event, buf, size, sys); } #undef _PE @@ -5203,22 +5230,7 @@ int pevent_strerror(struct pevent *pevent __maybe_unused, idx = errnum - __PEVENT_ERRNO__START - 1; msg = pevent_error_str[idx]; - - switch (errnum) { - case PEVENT_ERRNO__MEM_ALLOC_FAILED: - case PEVENT_ERRNO__PARSE_EVENT_FAILED: - case PEVENT_ERRNO__READ_ID_FAILED: - case PEVENT_ERRNO__READ_FORMAT_FAILED: - case PEVENT_ERRNO__READ_PRINT_FAILED: - case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: - case PEVENT_ERRNO__INVALID_ARG_TYPE: - snprintf(buf, buflen, "%s", msg); - break; - - default: - /* cannot reach here */ - break; - } + snprintf(buf, buflen, "%s", msg); return 0; } @@ -5548,6 +5560,52 @@ int pevent_register_print_function(struct pevent *pevent, return ret; } +/** + * pevent_unregister_print_function - unregister a helper function + * @pevent: the handle to the pevent + * @func: the function to process the helper function + * @name: the name of the helper function + * + * This function removes existing print handler for function @name. + * + * Returns 0 if the handler was removed successully, -1 otherwise. + */ +int pevent_unregister_print_function(struct pevent *pevent, + pevent_func_handler func, char *name) +{ + struct pevent_function_handler *func_handle; + + func_handle = find_func_handler(pevent, name); + if (func_handle && func_handle->func == func) { + remove_func_handler(pevent, name); + return 0; + } + return -1; +} + +static struct event_format *pevent_search_event(struct pevent *pevent, int id, + const char *sys_name, + const char *event_name) +{ + struct event_format *event; + + if (id >= 0) { + /* search by id */ + event = pevent_find_event(pevent, id); + if (!event) + return NULL; + if (event_name && (strcmp(event_name, event->name) != 0)) + return NULL; + if (sys_name && (strcmp(sys_name, event->system) != 0)) + return NULL; + } else { + event = pevent_find_event_by_name(pevent, sys_name, event_name); + if (!event) + return NULL; + } + return event; +} + /** * pevent_register_event_handler - register a way to parse an event * @pevent: the handle to the pevent @@ -5572,20 +5630,9 @@ int pevent_register_event_handler(struct pevent *pevent, int id, struct event_format *event; struct event_handler *handle; - if (id >= 0) { - /* search by id */ - event = pevent_find_event(pevent, id); - if (!event) - goto not_found; - if (event_name && (strcmp(event_name, event->name) != 0)) - goto not_found; - if (sys_name && (strcmp(sys_name, event->system) != 0)) - goto not_found; - } else { - event = pevent_find_event_by_name(pevent, sys_name, event_name); - if (!event) - goto not_found; - } + event = pevent_search_event(pevent, id, sys_name, event_name); + if (event == NULL) + goto not_found; pr_stat("overriding event (%d) %s:%s with new print handler", event->id, event->system, event->name); @@ -5625,6 +5672,79 @@ int pevent_register_event_handler(struct pevent *pevent, int id, return -1; } +static int handle_matches(struct event_handler *handler, int id, + const char *sys_name, const char *event_name, + pevent_event_handler_func func, void *context) +{ + if (id >= 0 && id != handler->id) + return 0; + + if (event_name && (strcmp(event_name, handler->event_name) != 0)) + return 0; + + if (sys_name && (strcmp(sys_name, handler->sys_name) != 0)) + return 0; + + if (func != handler->func || context != handler->context) + return 0; + + return 1; +} + +/** + * pevent_unregister_event_handler - unregister an existing event handler + * @pevent: the handle to the pevent + * @id: the id of the event to unregister + * @sys_name: the system name the handler belongs to + * @event_name: the name of the event handler + * @func: the function to call to parse the event information + * @context: the data to be passed to @func + * + * This function removes existing event handler (parser). + * + * If @id is >= 0, then it is used to find the event. + * else @sys_name and @event_name are used. + * + * Returns 0 if handler was removed successfully, -1 if event was not found. + */ +int pevent_unregister_event_handler(struct pevent *pevent, int id, + const char *sys_name, const char *event_name, + pevent_event_handler_func func, void *context) +{ + struct event_format *event; + struct event_handler *handle; + struct event_handler **next; + + event = pevent_search_event(pevent, id, sys_name, event_name); + if (event == NULL) + goto not_found; + + if (event->handler == func && event->context == context) { + pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.", + event->id, event->system, event->name); + + event->handler = NULL; + event->context = NULL; + return 0; + } + +not_found: + for (next = &pevent->handlers; *next; next = &(*next)->next) { + handle = *next; + if (handle_matches(handle, id, sys_name, event_name, + func, context)) + break; + } + + if (!(*next)) + return -1; + + *next = handle->next; + free_handler(handle); + + return 0; +} + /** * pevent_alloc - create a pevent handle */ diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 8d73d2594f65..791c539374c7 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -23,6 +23,7 @@ #include #include #include +#include #ifndef __maybe_unused #define __maybe_unused __attribute__((unused)) @@ -57,6 +58,12 @@ struct pevent_record { #endif }; +enum trace_seq_fail { + TRACE_SEQ__GOOD, + TRACE_SEQ__BUFFER_POISONED, + TRACE_SEQ__MEM_ALLOC_FAILED, +}; + /* * Trace sequences are used to allow a function to call several other functions * to create a string of data to use (up to a max of PAGE_SIZE). @@ -67,6 +74,7 @@ struct trace_seq { unsigned int buffer_size; unsigned int len; unsigned int readpos; + enum trace_seq_fail state; }; void trace_seq_init(struct trace_seq *s); @@ -97,7 +105,7 @@ typedef int (*pevent_event_handler_func)(struct trace_seq *s, void *context); typedef int (*pevent_plugin_load_func)(struct pevent *pevent); -typedef int (*pevent_plugin_unload_func)(void); +typedef int (*pevent_plugin_unload_func)(struct pevent *pevent); struct plugin_option { struct plugin_option *next; @@ -122,7 +130,7 @@ struct plugin_option { * PEVENT_PLUGIN_UNLOADER: (optional) * The function called just before unloading * - * int PEVENT_PLUGIN_UNLOADER(void) + * int PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) * * PEVENT_PLUGIN_OPTIONS: (optional) * Plugin options that can be set before loading @@ -355,12 +363,35 @@ enum pevent_flag { _PE(READ_FORMAT_FAILED, "failed to read event format"), \ _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ - _PE(INVALID_ARG_TYPE, "invalid argument type") + _PE(INVALID_ARG_TYPE, "invalid argument type"), \ + _PE(INVALID_EXP_TYPE, "invalid expression type"), \ + _PE(INVALID_OP_TYPE, "invalid operator type"), \ + _PE(INVALID_EVENT_NAME, "invalid event name"), \ + _PE(EVENT_NOT_FOUND, "no event found"), \ + _PE(SYNTAX_ERROR, "syntax error"), \ + _PE(ILLEGAL_RVALUE, "illegal rvalue"), \ + _PE(ILLEGAL_LVALUE, "illegal lvalue for string comparison"), \ + _PE(INVALID_REGEX, "regex did not compute"), \ + _PE(ILLEGAL_STRING_CMP, "illegal comparison for string"), \ + _PE(ILLEGAL_INTEGER_CMP,"illegal comparison for integer"), \ + _PE(REPARENT_NOT_OP, "cannot reparent other than OP"), \ + _PE(REPARENT_FAILED, "failed to reparent filter OP"), \ + _PE(BAD_FILTER_ARG, "bad arg in filter tree"), \ + _PE(UNEXPECTED_TYPE, "unexpected type (not a value)"), \ + _PE(ILLEGAL_TOKEN, "illegal token"), \ + _PE(INVALID_PAREN, "open parenthesis cannot come here"), \ + _PE(UNBALANCED_PAREN, "unbalanced number of parenthesis"), \ + _PE(UNKNOWN_TOKEN, "unknown token"), \ + _PE(FILTER_NOT_FOUND, "no filter found"), \ + _PE(NOT_A_NUMBER, "must have number field"), \ + _PE(NO_FILTER, "no filters exists"), \ + _PE(FILTER_MISS, "record does not match to filter") #undef _PE #define _PE(__code, __str) PEVENT_ERRNO__ ## __code enum pevent_errno { PEVENT_ERRNO__SUCCESS = 0, + PEVENT_ERRNO__FILTER_MATCH = PEVENT_ERRNO__SUCCESS, /* * Choose an arbitrary negative big number not to clash with standard @@ -377,6 +408,12 @@ enum pevent_errno { }; #undef _PE +struct plugin_list; + +struct plugin_list *traceevent_load_plugins(struct pevent *pevent); +void traceevent_unload_plugins(struct plugin_list *plugin_list, + struct pevent *pevent); + struct cmdline; struct cmdline_list; struct func_map; @@ -522,6 +559,15 @@ __data2host8(struct pevent *pevent, unsigned long long data) __data2host8(pevent, __val); \ }) +static inline int traceevent_host_bigendian(void) +{ + unsigned char str[] = { 0x1, 0x2, 0x3, 0x4 }; + unsigned int val; + + memcpy(&val, str, 4); + return val == 0x01020304; +} + /* taken from kernel/trace/trace.h */ enum trace_flag_type { TRACE_FLAG_IRQS_OFF = 0x01, @@ -547,7 +593,9 @@ int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long siz enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, unsigned long size, const char *sys); -enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf, +enum pevent_errno pevent_parse_format(struct pevent *pevent, + struct event_format **eventp, + const char *buf, unsigned long size, const char *sys); void pevent_free_format(struct event_format *event); @@ -576,10 +624,15 @@ int pevent_print_func_field(struct trace_seq *s, const char *fmt, int pevent_register_event_handler(struct pevent *pevent, int id, const char *sys_name, const char *event_name, pevent_event_handler_func func, void *context); +int pevent_unregister_event_handler(struct pevent *pevent, int id, + const char *sys_name, const char *event_name, + pevent_event_handler_func func, void *context); int pevent_register_print_function(struct pevent *pevent, pevent_func_handler func, enum pevent_func_arg_type ret_type, char *name, ...); +int pevent_unregister_print_function(struct pevent *pevent, + pevent_func_handler func, char *name); struct format_field *pevent_find_common_field(struct event_format *event, const char *name); struct format_field *pevent_find_field(struct event_format *event, const char *name); @@ -811,18 +864,22 @@ struct filter_type { struct filter_arg *filter; }; +#define PEVENT_FILTER_ERROR_BUFSZ 1024 + struct event_filter { struct pevent *pevent; int filters; struct filter_type *event_filters; + char error_buffer[PEVENT_FILTER_ERROR_BUFSZ]; }; struct event_filter *pevent_filter_alloc(struct pevent *pevent); -#define FILTER_NONE -2 -#define FILTER_NOEXIST -1 -#define FILTER_MISS 0 -#define FILTER_MATCH 1 +/* for backward compatibility */ +#define FILTER_NONE PEVENT_ERRNO__FILTER_NOT_FOUND +#define FILTER_NOEXIST PEVENT_ERRNO__NO_FILTER +#define FILTER_MISS PEVENT_ERRNO__FILTER_MISS +#define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH enum filter_trivial_type { FILTER_TRIVIAL_FALSE, @@ -830,20 +887,21 @@ enum filter_trivial_type { FILTER_TRIVIAL_BOTH, }; -int pevent_filter_add_filter_str(struct event_filter *filter, - const char *filter_str, - char **error_str); +enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, + const char *filter_str); +enum pevent_errno pevent_filter_match(struct event_filter *filter, + struct pevent_record *record); -int pevent_filter_match(struct event_filter *filter, - struct pevent_record *record); +int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, + char *buf, size_t buflen); int pevent_event_filtered(struct event_filter *filter, int event_id); void pevent_filter_reset(struct event_filter *filter); -void pevent_filter_clear_trivial(struct event_filter *filter, +int pevent_filter_clear_trivial(struct event_filter *filter, enum filter_trivial_type type); void pevent_filter_free(struct event_filter *filter); diff --git a/tools/lib/traceevent/event-plugin.c b/tools/lib/traceevent/event-plugin.c new file mode 100644 index 000000000000..0c8bf6780e4d --- /dev/null +++ b/tools/lib/traceevent/event-plugin.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include "event-parse.h" +#include "event-utils.h" + +#define LOCAL_PLUGIN_DIR ".traceevent/plugins" + +struct plugin_list { + struct plugin_list *next; + char *name; + void *handle; +}; + +static void +load_plugin(struct pevent *pevent, const char *path, + const char *file, void *data) +{ + struct plugin_list **plugin_list = data; + pevent_plugin_load_func func; + struct plugin_list *list; + const char *alias; + char *plugin; + void *handle; + + plugin = malloc(strlen(path) + strlen(file) + 2); + if (!plugin) { + warning("could not allocate plugin memory\n"); + return; + } + + strcpy(plugin, path); + strcat(plugin, "/"); + strcat(plugin, file); + + handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL); + if (!handle) { + warning("could not load plugin '%s'\n%s\n", + plugin, dlerror()); + goto out_free; + } + + alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME); + if (!alias) + alias = file; + + func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME); + if (!func) { + warning("could not find func '%s' in plugin '%s'\n%s\n", + PEVENT_PLUGIN_LOADER_NAME, plugin, dlerror()); + goto out_free; + } + + list = malloc(sizeof(*list)); + if (!list) { + warning("could not allocate plugin memory\n"); + goto out_free; + } + + list->next = *plugin_list; + list->handle = handle; + list->name = plugin; + *plugin_list = list; + + pr_stat("registering plugin: %s", plugin); + func(pevent); + return; + + out_free: + free(plugin); +} + +static void +load_plugins_dir(struct pevent *pevent, const char *suffix, + const char *path, + void (*load_plugin)(struct pevent *pevent, + const char *path, + const char *name, + void *data), + void *data) +{ + struct dirent *dent; + struct stat st; + DIR *dir; + int ret; + + ret = stat(path, &st); + if (ret < 0) + return; + + if (!S_ISDIR(st.st_mode)) + return; + + dir = opendir(path); + if (!dir) + return; + + while ((dent = readdir(dir))) { + const char *name = dent->d_name; + + if (strcmp(name, ".") == 0 || + strcmp(name, "..") == 0) + continue; + + /* Only load plugins that end in suffix */ + if (strcmp(name + (strlen(name) - strlen(suffix)), suffix) != 0) + continue; + + load_plugin(pevent, path, name, data); + } + + closedir(dir); +} + +static void +load_plugins(struct pevent *pevent, const char *suffix, + void (*load_plugin)(struct pevent *pevent, + const char *path, + const char *name, + void *data), + void *data) +{ + char *home; + char *path; + char *envdir; + + /* + * If a system plugin directory was defined, + * check that first. + */ +#ifdef PLUGIN_DIR + load_plugins_dir(pevent, suffix, PLUGIN_DIR, load_plugin, data); +#endif + + /* + * Next let the environment-set plugin directory + * override the system defaults. + */ + envdir = getenv("TRACEEVENT_PLUGIN_DIR"); + if (envdir) + load_plugins_dir(pevent, suffix, envdir, load_plugin, data); + + /* + * Now let the home directory override the environment + * or system defaults. + */ + home = getenv("HOME"); + if (!home) + return; + + path = malloc(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2); + if (!path) { + warning("could not allocate plugin memory\n"); + return; + } + + strcpy(path, home); + strcat(path, "/"); + strcat(path, LOCAL_PLUGIN_DIR); + + load_plugins_dir(pevent, suffix, path, load_plugin, data); + + free(path); +} + +struct plugin_list* +traceevent_load_plugins(struct pevent *pevent) +{ + struct plugin_list *list = NULL; + + load_plugins(pevent, ".so", load_plugin, &list); + return list; +} + +void +traceevent_unload_plugins(struct plugin_list *plugin_list, struct pevent *pevent) +{ + pevent_plugin_unload_func func; + struct plugin_list *list; + + while (plugin_list) { + list = plugin_list; + plugin_list = list->next; + func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME); + if (func) + func(pevent); + dlclose(list->handle); + free(list->name); + free(list); + } +} diff --git a/tools/lib/traceevent/event-utils.h b/tools/lib/traceevent/event-utils.h index e76c9acb92cd..d1dc2170e402 100644 --- a/tools/lib/traceevent/event-utils.h +++ b/tools/lib/traceevent/event-utils.h @@ -23,18 +23,14 @@ #include /* Can be overridden */ -void die(const char *fmt, ...); -void *malloc_or_die(unsigned int size); void warning(const char *fmt, ...); void pr_stat(const char *fmt, ...); void vpr_stat(const char *fmt, va_list ap); /* Always available */ -void __die(const char *fmt, ...); void __warning(const char *fmt, ...); void __pr_stat(const char *fmt, ...); -void __vdie(const char *fmt, ...); void __vwarning(const char *fmt, ...); void __vpr_stat(const char *fmt, ...); diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index 2500e75583fc..b50234402fc2 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c @@ -38,41 +38,31 @@ struct event_list { struct event_format *event; }; -#define MAX_ERR_STR_SIZE 256 - -static void show_error(char **error_str, const char *fmt, ...) +static void show_error(char *error_buf, const char *fmt, ...) { unsigned long long index; const char *input; - char *error; va_list ap; int len; int i; - if (!error_str) - return; - input = pevent_get_input_buf(); index = pevent_get_input_buf_ptr(); len = input ? strlen(input) : 0; - error = malloc_or_die(MAX_ERR_STR_SIZE + (len*2) + 3); - if (len) { - strcpy(error, input); - error[len] = '\n'; + strcpy(error_buf, input); + error_buf[len] = '\n'; for (i = 1; i < len && i < index; i++) - error[len+i] = ' '; - error[len + i] = '^'; - error[len + i + 1] = '\n'; + error_buf[len+i] = ' '; + error_buf[len + i] = '^'; + error_buf[len + i + 1] = '\n'; len += i+2; } va_start(ap, fmt); - vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap); + vsnprintf(error_buf + len, PEVENT_FILTER_ERROR_BUFSZ - len, fmt, ap); va_end(ap); - - *error_str = error; } static void free_token(char *token) @@ -95,7 +85,11 @@ static enum event_type read_token(char **tok) (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && pevent_peek_char() == '~') { /* append it */ - *tok = malloc_or_die(3); + *tok = malloc(3); + if (*tok == NULL) { + free_token(token); + return EVENT_ERROR; + } sprintf(*tok, "%c%c", *token, '~'); free_token(token); /* Now remove the '~' from the buffer */ @@ -147,11 +141,13 @@ add_filter_type(struct event_filter *filter, int id) if (filter_type) return filter_type; - filter->event_filters = realloc(filter->event_filters, - sizeof(*filter->event_filters) * - (filter->filters + 1)); - if (!filter->event_filters) - die("Could not allocate filter"); + filter_type = realloc(filter->event_filters, + sizeof(*filter->event_filters) * + (filter->filters + 1)); + if (!filter_type) + return NULL; + + filter->event_filters = filter_type; for (i = 0; i < filter->filters; i++) { if (filter->event_filters[i].event_id > id) @@ -182,7 +178,10 @@ struct event_filter *pevent_filter_alloc(struct pevent *pevent) { struct event_filter *filter; - filter = malloc_or_die(sizeof(*filter)); + filter = malloc(sizeof(*filter)); + if (filter == NULL) + return NULL; + memset(filter, 0, sizeof(*filter)); filter->pevent = pevent; pevent_ref(pevent); @@ -192,12 +191,7 @@ struct event_filter *pevent_filter_alloc(struct pevent *pevent) static struct filter_arg *allocate_arg(void) { - struct filter_arg *arg; - - arg = malloc_or_die(sizeof(*arg)); - memset(arg, 0, sizeof(*arg)); - - return arg; + return calloc(1, sizeof(struct filter_arg)); } static void free_arg(struct filter_arg *arg) @@ -242,15 +236,19 @@ static void free_arg(struct filter_arg *arg) free(arg); } -static void add_event(struct event_list **events, +static int add_event(struct event_list **events, struct event_format *event) { struct event_list *list; - list = malloc_or_die(sizeof(*list)); + list = malloc(sizeof(*list)); + if (list == NULL) + return -1; + list->next = *events; *events = list; list->event = event; + return 0; } static int event_match(struct event_format *event, @@ -265,7 +263,7 @@ static int event_match(struct event_format *event, !regexec(ereg, event->name, 0, NULL, 0); } -static int +static enum pevent_errno find_event(struct pevent *pevent, struct event_list **events, char *sys_name, char *event_name) { @@ -273,6 +271,7 @@ find_event(struct pevent *pevent, struct event_list **events, regex_t ereg; regex_t sreg; int match = 0; + int fail = 0; char *reg; int ret; int i; @@ -283,23 +282,31 @@ find_event(struct pevent *pevent, struct event_list **events, sys_name = NULL; } - reg = malloc_or_die(strlen(event_name) + 3); + reg = malloc(strlen(event_name) + 3); + if (reg == NULL) + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + sprintf(reg, "^%s$", event_name); ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB); free(reg); if (ret) - return -1; + return PEVENT_ERRNO__INVALID_EVENT_NAME; if (sys_name) { - reg = malloc_or_die(strlen(sys_name) + 3); + reg = malloc(strlen(sys_name) + 3); + if (reg == NULL) { + regfree(&ereg); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + sprintf(reg, "^%s$", sys_name); ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB); free(reg); if (ret) { regfree(&ereg); - return -1; + return PEVENT_ERRNO__INVALID_EVENT_NAME; } } @@ -307,7 +314,10 @@ find_event(struct pevent *pevent, struct event_list **events, event = pevent->events[i]; if (event_match(event, sys_name ? &sreg : NULL, &ereg)) { match = 1; - add_event(events, event); + if (add_event(events, event) < 0) { + fail = 1; + break; + } } } @@ -316,7 +326,9 @@ find_event(struct pevent *pevent, struct event_list **events, regfree(&sreg); if (!match) - return -1; + return PEVENT_ERRNO__EVENT_NOT_FOUND; + if (fail) + return PEVENT_ERRNO__MEM_ALLOC_FAILED; return 0; } @@ -332,14 +344,18 @@ static void free_events(struct event_list *events) } } -static struct filter_arg * +static enum pevent_errno create_arg_item(struct event_format *event, const char *token, - enum event_type type, char **error_str) + enum event_type type, struct filter_arg **parg, char *error_str) { struct format_field *field; struct filter_arg *arg; arg = allocate_arg(); + if (arg == NULL) { + show_error(error_str, "failed to allocate filter arg"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } switch (type) { @@ -349,8 +365,11 @@ create_arg_item(struct event_format *event, const char *token, arg->value.type = type == EVENT_DQUOTE ? FILTER_STRING : FILTER_CHAR; arg->value.str = strdup(token); - if (!arg->value.str) - die("malloc string"); + if (!arg->value.str) { + free_arg(arg); + show_error(error_str, "failed to allocate string filter arg"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } break; case EVENT_ITEM: /* if it is a number, then convert it */ @@ -377,11 +396,11 @@ create_arg_item(struct event_format *event, const char *token, break; default: free_arg(arg); - show_error(error_str, "expected a value but found %s", - token); - return NULL; + show_error(error_str, "expected a value but found %s", token); + return PEVENT_ERRNO__UNEXPECTED_TYPE; } - return arg; + *parg = arg; + return 0; } static struct filter_arg * @@ -390,6 +409,9 @@ create_arg_op(enum filter_op_type btype) struct filter_arg *arg; arg = allocate_arg(); + if (!arg) + return NULL; + arg->type = FILTER_ARG_OP; arg->op.type = btype; @@ -402,6 +424,9 @@ create_arg_exp(enum filter_exp_type etype) struct filter_arg *arg; arg = allocate_arg(); + if (!arg) + return NULL; + arg->type = FILTER_ARG_EXP; arg->op.type = etype; @@ -414,6 +439,9 @@ create_arg_cmp(enum filter_exp_type etype) struct filter_arg *arg; arg = allocate_arg(); + if (!arg) + return NULL; + /* Use NUM and change if necessary */ arg->type = FILTER_ARG_NUM; arg->op.type = etype; @@ -421,8 +449,8 @@ create_arg_cmp(enum filter_exp_type etype) return arg; } -static int add_right(struct filter_arg *op, struct filter_arg *arg, - char **error_str) +static enum pevent_errno +add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str) { struct filter_arg *left; char *str; @@ -453,9 +481,8 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg, case FILTER_ARG_FIELD: break; default: - show_error(error_str, - "Illegal rvalue"); - return -1; + show_error(error_str, "Illegal rvalue"); + return PEVENT_ERRNO__ILLEGAL_RVALUE; } /* @@ -502,7 +529,7 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg, if (left->type != FILTER_ARG_FIELD) { show_error(error_str, "Illegal lvalue for string comparison"); - return -1; + return PEVENT_ERRNO__ILLEGAL_LVALUE; } /* Make sure this is a valid string compare */ @@ -521,25 +548,31 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg, show_error(error_str, "RegEx '%s' did not compute", str); - return -1; + return PEVENT_ERRNO__INVALID_REGEX; } break; default: show_error(error_str, "Illegal comparison for string"); - return -1; + return PEVENT_ERRNO__ILLEGAL_STRING_CMP; } op->type = FILTER_ARG_STR; op->str.type = op_type; op->str.field = left->field.field; op->str.val = strdup(str); - if (!op->str.val) - die("malloc string"); + if (!op->str.val) { + show_error(error_str, "Failed to allocate string filter"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } /* * Need a buffer to copy data for tests */ - op->str.buffer = malloc_or_die(op->str.field->size + 1); + op->str.buffer = malloc(op->str.field->size + 1); + if (!op->str.buffer) { + show_error(error_str, "Failed to allocate string filter"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } /* Null terminate this buffer */ op->str.buffer[op->str.field->size] = 0; @@ -557,7 +590,7 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg, case FILTER_CMP_NOT_REGEX: show_error(error_str, "Op not allowed with integers"); - return -1; + return PEVENT_ERRNO__ILLEGAL_INTEGER_CMP; default: break; @@ -577,9 +610,8 @@ static int add_right(struct filter_arg *op, struct filter_arg *arg, return 0; out_fail: - show_error(error_str, - "Syntax error"); - return -1; + show_error(error_str, "Syntax error"); + return PEVENT_ERRNO__SYNTAX_ERROR; } static struct filter_arg * @@ -592,7 +624,7 @@ rotate_op_right(struct filter_arg *a, struct filter_arg *b) return arg; } -static int add_left(struct filter_arg *op, struct filter_arg *arg) +static enum pevent_errno add_left(struct filter_arg *op, struct filter_arg *arg) { switch (op->type) { case FILTER_ARG_EXP: @@ -611,11 +643,11 @@ static int add_left(struct filter_arg *op, struct filter_arg *arg) /* left arg of compares must be a field */ if (arg->type != FILTER_ARG_FIELD && arg->type != FILTER_ARG_BOOLEAN) - return -1; + return PEVENT_ERRNO__INVALID_ARG_TYPE; op->num.left = arg; break; default: - return -1; + return PEVENT_ERRNO__INVALID_ARG_TYPE; } return 0; } @@ -728,15 +760,18 @@ enum filter_vals { FILTER_VAL_TRUE, }; -void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, - struct filter_arg *arg) +static enum pevent_errno +reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, + struct filter_arg *arg, char *error_str) { struct filter_arg *other_child; struct filter_arg **ptr; if (parent->type != FILTER_ARG_OP && - arg->type != FILTER_ARG_OP) - die("can not reparent other than OP"); + arg->type != FILTER_ARG_OP) { + show_error(error_str, "can not reparent other than OP"); + return PEVENT_ERRNO__REPARENT_NOT_OP; + } /* Get the sibling */ if (old_child->op.right == arg) { @@ -745,8 +780,10 @@ void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, } else if (old_child->op.left == arg) { ptr = &old_child->op.left; other_child = old_child->op.right; - } else - die("Error in reparent op, find other child"); + } else { + show_error(error_str, "Error in reparent op, find other child"); + return PEVENT_ERRNO__REPARENT_FAILED; + } /* Detach arg from old_child */ *ptr = NULL; @@ -757,23 +794,29 @@ void reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, *parent = *arg; /* Free arg without recussion */ free(arg); - return; + return 0; } if (parent->op.right == old_child) ptr = &parent->op.right; else if (parent->op.left == old_child) ptr = &parent->op.left; - else - die("Error in reparent op"); + else { + show_error(error_str, "Error in reparent op"); + return PEVENT_ERRNO__REPARENT_FAILED; + } + *ptr = arg; free_arg(old_child); + return 0; } -enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg) +/* Returns either filter_vals (success) or pevent_errno (failfure) */ +static int test_arg(struct filter_arg *parent, struct filter_arg *arg, + char *error_str) { - enum filter_vals lval, rval; + int lval, rval; switch (arg->type) { @@ -788,63 +831,68 @@ enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg) return FILTER_VAL_NORM; case FILTER_ARG_EXP: - lval = test_arg(arg, arg->exp.left); + lval = test_arg(arg, arg->exp.left, error_str); if (lval != FILTER_VAL_NORM) return lval; - rval = test_arg(arg, arg->exp.right); + rval = test_arg(arg, arg->exp.right, error_str); if (rval != FILTER_VAL_NORM) return rval; return FILTER_VAL_NORM; case FILTER_ARG_NUM: - lval = test_arg(arg, arg->num.left); + lval = test_arg(arg, arg->num.left, error_str); if (lval != FILTER_VAL_NORM) return lval; - rval = test_arg(arg, arg->num.right); + rval = test_arg(arg, arg->num.right, error_str); if (rval != FILTER_VAL_NORM) return rval; return FILTER_VAL_NORM; case FILTER_ARG_OP: if (arg->op.type != FILTER_OP_NOT) { - lval = test_arg(arg, arg->op.left); + lval = test_arg(arg, arg->op.left, error_str); switch (lval) { case FILTER_VAL_NORM: break; case FILTER_VAL_TRUE: if (arg->op.type == FILTER_OP_OR) return FILTER_VAL_TRUE; - rval = test_arg(arg, arg->op.right); + rval = test_arg(arg, arg->op.right, error_str); if (rval != FILTER_VAL_NORM) return rval; - reparent_op_arg(parent, arg, arg->op.right); - return FILTER_VAL_NORM; + return reparent_op_arg(parent, arg, arg->op.right, + error_str); case FILTER_VAL_FALSE: if (arg->op.type == FILTER_OP_AND) return FILTER_VAL_FALSE; - rval = test_arg(arg, arg->op.right); + rval = test_arg(arg, arg->op.right, error_str); if (rval != FILTER_VAL_NORM) return rval; - reparent_op_arg(parent, arg, arg->op.right); - return FILTER_VAL_NORM; + return reparent_op_arg(parent, arg, arg->op.right, + error_str); + + default: + return lval; } } - rval = test_arg(arg, arg->op.right); + rval = test_arg(arg, arg->op.right, error_str); switch (rval) { case FILTER_VAL_NORM: + default: break; + case FILTER_VAL_TRUE: if (arg->op.type == FILTER_OP_OR) return FILTER_VAL_TRUE; if (arg->op.type == FILTER_OP_NOT) return FILTER_VAL_FALSE; - reparent_op_arg(parent, arg, arg->op.left); - return FILTER_VAL_NORM; + return reparent_op_arg(parent, arg, arg->op.left, + error_str); case FILTER_VAL_FALSE: if (arg->op.type == FILTER_OP_AND) @@ -852,41 +900,56 @@ enum filter_vals test_arg(struct filter_arg *parent, struct filter_arg *arg) if (arg->op.type == FILTER_OP_NOT) return FILTER_VAL_TRUE; - reparent_op_arg(parent, arg, arg->op.left); - return FILTER_VAL_NORM; + return reparent_op_arg(parent, arg, arg->op.left, + error_str); } - return FILTER_VAL_NORM; + return rval; default: - die("bad arg in filter tree"); + show_error(error_str, "bad arg in filter tree"); + return PEVENT_ERRNO__BAD_FILTER_ARG; } return FILTER_VAL_NORM; } /* Remove any unknown event fields */ -static struct filter_arg *collapse_tree(struct filter_arg *arg) +static int collapse_tree(struct filter_arg *arg, + struct filter_arg **arg_collapsed, char *error_str) { - enum filter_vals ret; + int ret; - ret = test_arg(arg, arg); + ret = test_arg(arg, arg, error_str); switch (ret) { case FILTER_VAL_NORM: - return arg; + break; case FILTER_VAL_TRUE: case FILTER_VAL_FALSE: free_arg(arg); arg = allocate_arg(); - arg->type = FILTER_ARG_BOOLEAN; - arg->boolean.value = ret == FILTER_VAL_TRUE; + if (arg) { + arg->type = FILTER_ARG_BOOLEAN; + arg->boolean.value = ret == FILTER_VAL_TRUE; + } else { + show_error(error_str, "Failed to allocate filter arg"); + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + break; + + default: + /* test_arg() already set the error_str */ + free_arg(arg); + arg = NULL; + break; } - return arg; + *arg_collapsed = arg; + return ret; } -static int +static enum pevent_errno process_filter(struct event_format *event, struct filter_arg **parg, - char **error_str, int not) + char *error_str, int not) { enum event_type type; char *token = NULL; @@ -898,7 +961,7 @@ process_filter(struct event_format *event, struct filter_arg **parg, enum filter_op_type btype; enum filter_exp_type etype; enum filter_cmp_type ctype; - int ret; + enum pevent_errno ret; *parg = NULL; @@ -909,8 +972,8 @@ process_filter(struct event_format *event, struct filter_arg **parg, case EVENT_SQUOTE: case EVENT_DQUOTE: case EVENT_ITEM: - arg = create_arg_item(event, token, type, error_str); - if (!arg) + ret = create_arg_item(event, token, type, &arg, error_str); + if (ret < 0) goto fail; if (!left_item) left_item = arg; @@ -923,20 +986,20 @@ process_filter(struct event_format *event, struct filter_arg **parg, if (not) { arg = NULL; if (current_op) - goto fail_print; + goto fail_syntax; free(token); *parg = current_exp; return 0; } } else - goto fail_print; + goto fail_syntax; arg = NULL; break; case EVENT_DELIM: if (*token == ',') { - show_error(error_str, - "Illegal token ','"); + show_error(error_str, "Illegal token ','"); + ret = PEVENT_ERRNO__ILLEGAL_TOKEN; goto fail; } @@ -944,19 +1007,23 @@ process_filter(struct event_format *event, struct filter_arg **parg, if (left_item) { show_error(error_str, "Open paren can not come after item"); + ret = PEVENT_ERRNO__INVALID_PAREN; goto fail; } if (current_exp) { show_error(error_str, "Open paren can not come after expression"); + ret = PEVENT_ERRNO__INVALID_PAREN; goto fail; } ret = process_filter(event, &arg, error_str, 0); - if (ret != 1) { - if (ret == 0) + if (ret != PEVENT_ERRNO__UNBALANCED_PAREN) { + if (ret == 0) { show_error(error_str, "Unbalanced number of '('"); + ret = PEVENT_ERRNO__UNBALANCED_PAREN; + } goto fail; } ret = 0; @@ -964,7 +1031,7 @@ process_filter(struct event_format *event, struct filter_arg **parg, /* A not wants just one expression */ if (not) { if (current_op) - goto fail_print; + goto fail_syntax; *parg = arg; return 0; } @@ -979,19 +1046,19 @@ process_filter(struct event_format *event, struct filter_arg **parg, } else { /* ')' */ if (!current_op && !current_exp) - goto fail_print; + goto fail_syntax; /* Make sure everything is finished at this level */ if (current_exp && !check_op_done(current_exp)) - goto fail_print; + goto fail_syntax; if (current_op && !check_op_done(current_op)) - goto fail_print; + goto fail_syntax; if (current_op) *parg = current_op; else *parg = current_exp; - return 1; + return PEVENT_ERRNO__UNBALANCED_PAREN; } break; @@ -1003,21 +1070,22 @@ process_filter(struct event_format *event, struct filter_arg **parg, case OP_BOOL: /* Logic ops need a left expression */ if (!current_exp && !current_op) - goto fail_print; + goto fail_syntax; /* fall through */ case OP_NOT: /* logic only processes ops and exp */ if (left_item) - goto fail_print; + goto fail_syntax; break; case OP_EXP: case OP_CMP: if (!left_item) - goto fail_print; + goto fail_syntax; break; case OP_NONE: show_error(error_str, "Unknown op token %s", token); + ret = PEVENT_ERRNO__UNKNOWN_TOKEN; goto fail; } @@ -1025,6 +1093,8 @@ process_filter(struct event_format *event, struct filter_arg **parg, switch (op_type) { case OP_BOOL: arg = create_arg_op(btype); + if (arg == NULL) + goto fail_alloc; if (current_op) ret = add_left(arg, current_op); else @@ -1035,6 +1105,8 @@ process_filter(struct event_format *event, struct filter_arg **parg, case OP_NOT: arg = create_arg_op(btype); + if (arg == NULL) + goto fail_alloc; if (current_op) ret = add_right(current_op, arg, error_str); if (ret < 0) @@ -1054,6 +1126,8 @@ process_filter(struct event_format *event, struct filter_arg **parg, arg = create_arg_exp(etype); else arg = create_arg_cmp(ctype); + if (arg == NULL) + goto fail_alloc; if (current_op) ret = add_right(current_op, arg, error_str); @@ -1062,7 +1136,7 @@ process_filter(struct event_format *event, struct filter_arg **parg, ret = add_left(arg, left_item); if (ret < 0) { arg = NULL; - goto fail_print; + goto fail_syntax; } current_exp = arg; break; @@ -1071,57 +1145,64 @@ process_filter(struct event_format *event, struct filter_arg **parg, } arg = NULL; if (ret < 0) - goto fail_print; + goto fail_syntax; break; case EVENT_NONE: break; + case EVENT_ERROR: + goto fail_alloc; default: - goto fail_print; + goto fail_syntax; } } while (type != EVENT_NONE); if (!current_op && !current_exp) - goto fail_print; + goto fail_syntax; if (!current_op) current_op = current_exp; - current_op = collapse_tree(current_op); + ret = collapse_tree(current_op, parg, error_str); + if (ret < 0) + goto fail; *parg = current_op; return 0; - fail_print: + fail_alloc: + show_error(error_str, "failed to allocate filter arg"); + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto fail; + fail_syntax: show_error(error_str, "Syntax error"); + ret = PEVENT_ERRNO__SYNTAX_ERROR; fail: free_arg(current_op); free_arg(current_exp); free_arg(arg); free(token); - return -1; + return ret; } -static int +static enum pevent_errno process_event(struct event_format *event, const char *filter_str, - struct filter_arg **parg, char **error_str) + struct filter_arg **parg, char *error_str) { int ret; pevent_buffer_init(filter_str, strlen(filter_str)); ret = process_filter(event, parg, error_str, 0); - if (ret == 1) { - show_error(error_str, - "Unbalanced number of ')'"); - return -1; - } if (ret < 0) return ret; /* If parg is NULL, then make it into FALSE */ if (!*parg) { *parg = allocate_arg(); + if (*parg == NULL) + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + (*parg)->type = FILTER_ARG_BOOLEAN; (*parg)->boolean.value = FILTER_FALSE; } @@ -1129,13 +1210,13 @@ process_event(struct event_format *event, const char *filter_str, return 0; } -static int filter_event(struct event_filter *filter, - struct event_format *event, - const char *filter_str, char **error_str) +static enum pevent_errno +filter_event(struct event_filter *filter, struct event_format *event, + const char *filter_str, char *error_str) { struct filter_type *filter_type; struct filter_arg *arg; - int ret; + enum pevent_errno ret; if (filter_str) { ret = process_event(event, filter_str, &arg, error_str); @@ -1145,11 +1226,17 @@ static int filter_event(struct event_filter *filter, } else { /* just add a TRUE arg */ arg = allocate_arg(); + if (arg == NULL) + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + arg->type = FILTER_ARG_BOOLEAN; arg->boolean.value = FILTER_TRUE; } filter_type = add_filter_type(filter, event->id); + if (filter_type == NULL) + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + if (filter_type->filter) free_arg(filter_type->filter); filter_type->filter = arg; @@ -1157,22 +1244,24 @@ static int filter_event(struct event_filter *filter, return 0; } +static void filter_init_error_buf(struct event_filter *filter) +{ + /* clear buffer to reset show error */ + pevent_buffer_init("", 0); + filter->error_buffer[0] = '\0'; +} + /** * pevent_filter_add_filter_str - add a new filter * @filter: the event filter to add to * @filter_str: the filter string that contains the filter - * @error_str: string containing reason for failed filter * - * Returns 0 if the filter was successfully added - * -1 if there was an error. - * - * On error, if @error_str points to a string pointer, - * it is set to the reason that the filter failed. - * This string must be freed with "free". + * Returns 0 if the filter was successfully added or a + * negative error code. Use pevent_filter_strerror() to see + * actual error message in case of error. */ -int pevent_filter_add_filter_str(struct event_filter *filter, - const char *filter_str, - char **error_str) +enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, + const char *filter_str) { struct pevent *pevent = filter->pevent; struct event_list *event; @@ -1183,15 +1272,11 @@ int pevent_filter_add_filter_str(struct event_filter *filter, char *event_name = NULL; char *sys_name = NULL; char *sp; - int rtn = 0; + enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */ int len; int ret; - /* clear buffer to reset show error */ - pevent_buffer_init("", 0); - - if (error_str) - *error_str = NULL; + filter_init_error_buf(filter); filter_start = strchr(filter_str, ':'); if (filter_start) @@ -1199,7 +1284,6 @@ int pevent_filter_add_filter_str(struct event_filter *filter, else len = strlen(filter_str); - do { next_event = strchr(filter_str, ','); if (next_event && @@ -1210,7 +1294,12 @@ int pevent_filter_add_filter_str(struct event_filter *filter, else len = strlen(filter_str); - this_event = malloc_or_die(len + 1); + this_event = malloc(len + 1); + if (this_event == NULL) { + /* This can only happen when events is NULL, but still */ + free_events(events); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } memcpy(this_event, filter_str, len); this_event[len] = 0; @@ -1223,27 +1312,18 @@ int pevent_filter_add_filter_str(struct event_filter *filter, event_name = strtok_r(NULL, "/", &sp); if (!sys_name) { - show_error(error_str, "No filter found"); /* This can only happen when events is NULL, but still */ free_events(events); free(this_event); - return -1; + return PEVENT_ERRNO__FILTER_NOT_FOUND; } /* Find this event */ ret = find_event(pevent, &events, strim(sys_name), strim(event_name)); if (ret < 0) { - if (event_name) - show_error(error_str, - "No event found under '%s.%s'", - sys_name, event_name); - else - show_error(error_str, - "No event found under '%s'", - sys_name); free_events(events); free(this_event); - return -1; + return ret; } free(this_event); } while (filter_str); @@ -1255,7 +1335,7 @@ int pevent_filter_add_filter_str(struct event_filter *filter, /* filter starts here */ for (event = events; event; event = event->next) { ret = filter_event(filter, event->event, filter_start, - error_str); + filter->error_buffer); /* Failures are returned if a parse error happened */ if (ret < 0) rtn = ret; @@ -1263,8 +1343,10 @@ int pevent_filter_add_filter_str(struct event_filter *filter, if (ret >= 0 && pevent->test_filters) { char *test; test = pevent_filter_make_string(filter, event->event->id); - printf(" '%s: %s'\n", event->event->name, test); - free(test); + if (test) { + printf(" '%s: %s'\n", event->event->name, test); + free(test); + } } } @@ -1281,6 +1363,32 @@ static void free_filter_type(struct filter_type *filter_type) free_arg(filter_type->filter); } +/** + * pevent_filter_strerror - fill error message in a buffer + * @filter: the event filter contains error + * @err: the error code + * @buf: the buffer to be filled in + * @buflen: the size of the buffer + * + * Returns 0 if message was filled successfully, -1 if error + */ +int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, + char *buf, size_t buflen) +{ + if (err <= __PEVENT_ERRNO__START || err >= __PEVENT_ERRNO__END) + return -1; + + if (strlen(filter->error_buffer) > 0) { + size_t len = snprintf(buf, buflen, "%s", filter->error_buffer); + + if (len > buflen) + return -1; + return 0; + } + + return pevent_strerror(filter->pevent, err, buf, buflen); +} + /** * pevent_filter_remove_event - remove a filter for an event * @filter: the event filter to remove from @@ -1374,6 +1482,9 @@ static int copy_filter_type(struct event_filter *filter, if (strcmp(str, "TRUE") == 0 || strcmp(str, "FALSE") == 0) { /* Add trivial event */ arg = allocate_arg(); + if (arg == NULL) + return -1; + arg->type = FILTER_ARG_BOOLEAN; if (strcmp(str, "TRUE") == 0) arg->boolean.value = 1; @@ -1381,6 +1492,9 @@ static int copy_filter_type(struct event_filter *filter, arg->boolean.value = 0; filter_type = add_filter_type(filter, event->id); + if (filter_type == NULL) + return -1; + filter_type->filter = arg; free(str); @@ -1482,8 +1596,10 @@ int pevent_update_trivial(struct event_filter *dest, struct event_filter *source * @type: remove only true, false, or both * * Removes filters that only contain a TRUE or FALES boolean arg. + * + * Returns 0 on success and -1 if there was a problem. */ -void pevent_filter_clear_trivial(struct event_filter *filter, +int pevent_filter_clear_trivial(struct event_filter *filter, enum filter_trivial_type type) { struct filter_type *filter_type; @@ -1492,13 +1608,15 @@ void pevent_filter_clear_trivial(struct event_filter *filter, int i; if (!filter->filters) - return; + return 0; /* * Two steps, first get all ids with trivial filters. * then remove those ids. */ for (i = 0; i < filter->filters; i++) { + int *new_ids; + filter_type = &filter->event_filters[i]; if (filter_type->filter->type != FILTER_ARG_BOOLEAN) continue; @@ -1513,19 +1631,24 @@ void pevent_filter_clear_trivial(struct event_filter *filter, break; } - ids = realloc(ids, sizeof(*ids) * (count + 1)); - if (!ids) - die("Can't allocate ids"); + new_ids = realloc(ids, sizeof(*ids) * (count + 1)); + if (!new_ids) { + free(ids); + return -1; + } + + ids = new_ids; ids[count++] = filter_type->event_id; } if (!count) - return; + return 0; for (i = 0; i < count; i++) pevent_filter_remove_event(filter, ids[i]); free(ids); + return 0; } /** @@ -1565,8 +1688,8 @@ int pevent_filter_event_has_trivial(struct event_filter *filter, } } -static int test_filter(struct event_format *event, - struct filter_arg *arg, struct pevent_record *record); +static int test_filter(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err); static const char * get_comm(struct event_format *event, struct pevent_record *record) @@ -1612,15 +1735,24 @@ get_value(struct event_format *event, } static unsigned long long -get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record); +get_arg_value(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err); static unsigned long long -get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record) +get_exp_value(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err) { unsigned long long lval, rval; - lval = get_arg_value(event, arg->exp.left, record); - rval = get_arg_value(event, arg->exp.right, record); + lval = get_arg_value(event, arg->exp.left, record, err); + rval = get_arg_value(event, arg->exp.right, record, err); + + if (*err) { + /* + * There was an error, no need to process anymore. + */ + return 0; + } switch (arg->exp.type) { case FILTER_EXP_ADD: @@ -1655,39 +1787,51 @@ get_exp_value(struct event_format *event, struct filter_arg *arg, struct pevent_ case FILTER_EXP_NOT: default: - die("error in exp"); + if (!*err) + *err = PEVENT_ERRNO__INVALID_EXP_TYPE; } return 0; } static unsigned long long -get_arg_value(struct event_format *event, struct filter_arg *arg, struct pevent_record *record) +get_arg_value(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err) { switch (arg->type) { case FILTER_ARG_FIELD: return get_value(event, arg->field.field, record); case FILTER_ARG_VALUE: - if (arg->value.type != FILTER_NUMBER) - die("must have number field!"); + if (arg->value.type != FILTER_NUMBER) { + if (!*err) + *err = PEVENT_ERRNO__NOT_A_NUMBER; + } return arg->value.val; case FILTER_ARG_EXP: - return get_exp_value(event, arg, record); + return get_exp_value(event, arg, record, err); default: - die("oops in filter"); + if (!*err) + *err = PEVENT_ERRNO__INVALID_ARG_TYPE; } return 0; } -static int test_num(struct event_format *event, - struct filter_arg *arg, struct pevent_record *record) +static int test_num(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err) { unsigned long long lval, rval; - lval = get_arg_value(event, arg->num.left, record); - rval = get_arg_value(event, arg->num.right, record); + lval = get_arg_value(event, arg->num.left, record, err); + rval = get_arg_value(event, arg->num.right, record, err); + + if (*err) { + /* + * There was an error, no need to process anymore. + */ + return 0; + } switch (arg->num.type) { case FILTER_CMP_EQ: @@ -1709,7 +1853,8 @@ static int test_num(struct event_format *event, return lval <= rval; default: - /* ?? */ + if (!*err) + *err = PEVENT_ERRNO__ILLEGAL_INTEGER_CMP; return 0; } } @@ -1756,8 +1901,8 @@ static const char *get_field_str(struct filter_arg *arg, struct pevent_record *r return val; } -static int test_str(struct event_format *event, - struct filter_arg *arg, struct pevent_record *record) +static int test_str(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err) { const char *val; @@ -1781,48 +1926,57 @@ static int test_str(struct event_format *event, return regexec(&arg->str.reg, val, 0, NULL, 0); default: - /* ?? */ + if (!*err) + *err = PEVENT_ERRNO__ILLEGAL_STRING_CMP; return 0; } } -static int test_op(struct event_format *event, - struct filter_arg *arg, struct pevent_record *record) +static int test_op(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err) { switch (arg->op.type) { case FILTER_OP_AND: - return test_filter(event, arg->op.left, record) && - test_filter(event, arg->op.right, record); + return test_filter(event, arg->op.left, record, err) && + test_filter(event, arg->op.right, record, err); case FILTER_OP_OR: - return test_filter(event, arg->op.left, record) || - test_filter(event, arg->op.right, record); + return test_filter(event, arg->op.left, record, err) || + test_filter(event, arg->op.right, record, err); case FILTER_OP_NOT: - return !test_filter(event, arg->op.right, record); + return !test_filter(event, arg->op.right, record, err); default: - /* ?? */ + if (!*err) + *err = PEVENT_ERRNO__INVALID_OP_TYPE; return 0; } } -static int test_filter(struct event_format *event, - struct filter_arg *arg, struct pevent_record *record) +static int test_filter(struct event_format *event, struct filter_arg *arg, + struct pevent_record *record, enum pevent_errno *err) { + if (*err) { + /* + * There was an error, no need to process anymore. + */ + return 0; + } + switch (arg->type) { case FILTER_ARG_BOOLEAN: /* easy case */ return arg->boolean.value; case FILTER_ARG_OP: - return test_op(event, arg, record); + return test_op(event, arg, record, err); case FILTER_ARG_NUM: - return test_num(event, arg, record); + return test_num(event, arg, record, err); case FILTER_ARG_STR: - return test_str(event, arg, record); + return test_str(event, arg, record, err); case FILTER_ARG_EXP: case FILTER_ARG_VALUE: @@ -1831,11 +1985,11 @@ static int test_filter(struct event_format *event, * Expressions, fields and values evaluate * to true if they return non zero */ - return !!get_arg_value(event, arg, record); + return !!get_arg_value(event, arg, record, err); default: - die("oops!"); - /* ?? */ + if (!*err) + *err = PEVENT_ERRNO__INVALID_ARG_TYPE; return 0; } } @@ -1848,8 +2002,7 @@ static int test_filter(struct event_format *event, * Returns 1 if filter found for @event_id * otherwise 0; */ -int pevent_event_filtered(struct event_filter *filter, - int event_id) +int pevent_event_filtered(struct event_filter *filter, int event_id) { struct filter_type *filter_type; @@ -1866,31 +2019,38 @@ int pevent_event_filtered(struct event_filter *filter, * @filter: filter struct with filter information * @record: the record to test against the filter * - * Returns: - * 1 - filter found for event and @record matches - * 0 - filter found for event and @record does not match - * -1 - no filter found for @record's event - * -2 - if no filters exist + * Returns: match result or error code (prefixed with PEVENT_ERRNO__) + * FILTER_MATCH - filter found for event and @record matches + * FILTER_MISS - filter found for event and @record does not match + * FILTER_NOT_FOUND - no filter found for @record's event + * NO_FILTER - if no filters exist + * otherwise - error occurred during test */ -int pevent_filter_match(struct event_filter *filter, - struct pevent_record *record) +enum pevent_errno pevent_filter_match(struct event_filter *filter, + struct pevent_record *record) { struct pevent *pevent = filter->pevent; struct filter_type *filter_type; int event_id; + int ret; + enum pevent_errno err = 0; + + filter_init_error_buf(filter); if (!filter->filters) - return FILTER_NONE; + return PEVENT_ERRNO__NO_FILTER; event_id = pevent_data_type(pevent, record); filter_type = find_filter_type(filter, event_id); - if (!filter_type) - return FILTER_NOEXIST; + return PEVENT_ERRNO__FILTER_NOT_FOUND; - return test_filter(filter_type->event, filter_type->filter, record) ? - FILTER_MATCH : FILTER_MISS; + ret = test_filter(filter_type->event, filter_type->filter, record, &err); + if (err) + return err; + + return ret ? PEVENT_ERRNO__FILTER_MATCH : PEVENT_ERRNO__FILTER_MISS; } static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) @@ -1902,7 +2062,6 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) int left_val = -1; int right_val = -1; int val; - int len; switch (arg->op.type) { case FILTER_OP_AND: @@ -1949,11 +2108,7 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) default: break; } - str = malloc_or_die(6); - if (val) - strcpy(str, "TRUE"); - else - strcpy(str, "FALSE"); + asprintf(&str, val ? "TRUE" : "FALSE"); break; } } @@ -1971,10 +2126,7 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) break; } - len = strlen(left) + strlen(right) + strlen(op) + 10; - str = malloc_or_die(len); - snprintf(str, len, "(%s) %s (%s)", - left, op, right); + asprintf(&str, "(%s) %s (%s)", left, op, right); break; case FILTER_OP_NOT: @@ -1990,16 +2142,10 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) right_val = 0; if (right_val >= 0) { /* just return the opposite */ - str = malloc_or_die(6); - if (right_val) - strcpy(str, "FALSE"); - else - strcpy(str, "TRUE"); + asprintf(&str, right_val ? "FALSE" : "TRUE"); break; } - len = strlen(right) + strlen(op) + 3; - str = malloc_or_die(len); - snprintf(str, len, "%s(%s)", op, right); + asprintf(&str, "%s(%s)", op, right); break; default: @@ -2013,11 +2159,9 @@ static char *op_to_str(struct event_filter *filter, struct filter_arg *arg) static char *val_to_str(struct event_filter *filter, struct filter_arg *arg) { - char *str; + char *str = NULL; - str = malloc_or_die(30); - - snprintf(str, 30, "%lld", arg->value.val); + asprintf(&str, "%lld", arg->value.val); return str; } @@ -2033,7 +2177,6 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) char *rstr; char *op; char *str = NULL; - int len; lstr = arg_to_str(filter, arg->exp.left); rstr = arg_to_str(filter, arg->exp.right); @@ -2072,12 +2215,11 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) op = "^"; break; default: - die("oops in exp"); + op = "[ERROR IN EXPRESSION TYPE]"; + break; } - len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; - str = malloc_or_die(len); - snprintf(str, len, "%s %s %s", lstr, op, rstr); + asprintf(&str, "%s %s %s", lstr, op, rstr); out: free(lstr); free(rstr); @@ -2091,7 +2233,6 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) char *rstr; char *str = NULL; char *op = NULL; - int len; lstr = arg_to_str(filter, arg->num.left); rstr = arg_to_str(filter, arg->num.right); @@ -2122,10 +2263,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) if (!op) op = "<="; - len = strlen(lstr) + strlen(op) + strlen(rstr) + 4; - str = malloc_or_die(len); - sprintf(str, "%s %s %s", lstr, op, rstr); - + asprintf(&str, "%s %s %s", lstr, op, rstr); break; default: @@ -2143,7 +2281,6 @@ static char *str_to_str(struct event_filter *filter, struct filter_arg *arg) { char *str = NULL; char *op = NULL; - int len; switch (arg->str.type) { case FILTER_CMP_MATCH: @@ -2161,12 +2298,8 @@ static char *str_to_str(struct event_filter *filter, struct filter_arg *arg) if (!op) op = "!~"; - len = strlen(arg->str.field->name) + strlen(op) + - strlen(arg->str.val) + 6; - str = malloc_or_die(len); - snprintf(str, len, "%s %s \"%s\"", - arg->str.field->name, - op, arg->str.val); + asprintf(&str, "%s %s \"%s\"", + arg->str.field->name, op, arg->str.val); break; default: @@ -2178,15 +2311,11 @@ static char *str_to_str(struct event_filter *filter, struct filter_arg *arg) static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg) { - char *str; + char *str = NULL; switch (arg->type) { case FILTER_ARG_BOOLEAN: - str = malloc_or_die(6); - if (arg->boolean.value) - strcpy(str, "TRUE"); - else - strcpy(str, "FALSE"); + asprintf(&str, arg->boolean.value ? "TRUE" : "FALSE"); return str; case FILTER_ARG_OP: @@ -2221,7 +2350,7 @@ static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg) * * Returns a string that displays the filter contents. * This string must be freed with free(str). - * NULL is returned if no filter is found. + * NULL is returned if no filter is found or allocation failed. */ char * pevent_filter_make_string(struct event_filter *filter, int event_id) diff --git a/tools/lib/traceevent/parse-utils.c b/tools/lib/traceevent/parse-utils.c index bba701cf10e6..eda07fa31dca 100644 --- a/tools/lib/traceevent/parse-utils.c +++ b/tools/lib/traceevent/parse-utils.c @@ -25,40 +25,6 @@ #define __weak __attribute__((weak)) -void __vdie(const char *fmt, va_list ap) -{ - int ret = errno; - - if (errno) - perror("trace-cmd"); - else - ret = -1; - - fprintf(stderr, " "); - vfprintf(stderr, fmt, ap); - - fprintf(stderr, "\n"); - exit(ret); -} - -void __die(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - __vdie(fmt, ap); - va_end(ap); -} - -void __weak die(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - __vdie(fmt, ap); - va_end(ap); -} - void __vwarning(const char *fmt, va_list ap) { if (errno) @@ -117,13 +83,3 @@ void __weak pr_stat(const char *fmt, ...) __vpr_stat(fmt, ap); va_end(ap); } - -void __weak *malloc_or_die(unsigned int size) -{ - void *data; - - data = malloc(size); - if (!data) - die("malloc"); - return data; -} diff --git a/tools/lib/traceevent/plugin_cfg80211.c b/tools/lib/traceevent/plugin_cfg80211.c new file mode 100644 index 000000000000..c066b25905f8 --- /dev/null +++ b/tools/lib/traceevent/plugin_cfg80211.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include "event-parse.h" + +static unsigned long long +process___le16_to_cpup(struct trace_seq *s, + unsigned long long *args) +{ + uint16_t *val = (uint16_t *) (unsigned long) args[0]; + return val ? (long long) le16toh(*val) : 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_print_function(pevent, + process___le16_to_cpup, + PEVENT_FUNC_ARG_INT, + "__le16_to_cpup", + PEVENT_FUNC_ARG_PTR, + PEVENT_FUNC_ARG_VOID); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_print_function(pevent, process___le16_to_cpup, + "__le16_to_cpup"); +} diff --git a/tools/lib/traceevent/plugin_function.c b/tools/lib/traceevent/plugin_function.c new file mode 100644 index 000000000000..80ba4ff1fe84 --- /dev/null +++ b/tools/lib/traceevent/plugin_function.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" +#include "event-utils.h" + +static struct func_stack { + int size; + char **stack; +} *fstack; + +static int cpus = -1; + +#define STK_BLK 10 + +static void add_child(struct func_stack *stack, const char *child, int pos) +{ + int i; + + if (!child) + return; + + if (pos < stack->size) + free(stack->stack[pos]); + else { + char **ptr; + + ptr = realloc(stack->stack, sizeof(char *) * + (stack->size + STK_BLK)); + if (!ptr) { + warning("could not allocate plugin memory\n"); + return; + } + + stack->stack = ptr; + + for (i = stack->size; i < stack->size + STK_BLK; i++) + stack->stack[i] = NULL; + stack->size += STK_BLK; + } + + stack->stack[pos] = strdup(child); +} + +static int add_and_get_index(const char *parent, const char *child, int cpu) +{ + int i; + + if (cpu < 0) + return 0; + + if (cpu > cpus) { + struct func_stack *ptr; + + ptr = realloc(fstack, sizeof(*fstack) * (cpu + 1)); + if (!ptr) { + warning("could not allocate plugin memory\n"); + return 0; + } + + fstack = ptr; + + /* Account for holes in the cpu count */ + for (i = cpus + 1; i <= cpu; i++) + memset(&fstack[i], 0, sizeof(fstack[i])); + cpus = cpu; + } + + for (i = 0; i < fstack[cpu].size && fstack[cpu].stack[i]; i++) { + if (strcmp(parent, fstack[cpu].stack[i]) == 0) { + add_child(&fstack[cpu], child, i+1); + return i; + } + } + + /* Not found */ + add_child(&fstack[cpu], parent, 0); + add_child(&fstack[cpu], child, 1); + return 0; +} + +static int function_handler(struct trace_seq *s, struct pevent_record *record, + struct event_format *event, void *context) +{ + struct pevent *pevent = event->pevent; + unsigned long long function; + unsigned long long pfunction; + const char *func; + const char *parent; + int index; + + if (pevent_get_field_val(s, event, "ip", record, &function, 1)) + return trace_seq_putc(s, '!'); + + func = pevent_find_function(pevent, function); + + if (pevent_get_field_val(s, event, "parent_ip", record, &pfunction, 1)) + return trace_seq_putc(s, '!'); + + parent = pevent_find_function(pevent, pfunction); + + index = add_and_get_index(parent, func, record->cpu); + + trace_seq_printf(s, "%*s", index*3, ""); + + if (func) + trace_seq_printf(s, "%s", func); + else + trace_seq_printf(s, "0x%llx", function); + + trace_seq_printf(s, " <-- "); + if (parent) + trace_seq_printf(s, "%s", parent); + else + trace_seq_printf(s, "0x%llx", pfunction); + + return 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_event_handler(pevent, -1, "ftrace", "function", + function_handler, NULL); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + int i, x; + + pevent_unregister_event_handler(pevent, -1, "ftrace", "function", + function_handler, NULL); + + for (i = 0; i <= cpus; i++) { + for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++) + free(fstack[i].stack[x]); + free(fstack[i].stack); + } + + free(fstack); + fstack = NULL; + cpus = -1; +} diff --git a/tools/lib/traceevent/plugin_hrtimer.c b/tools/lib/traceevent/plugin_hrtimer.c new file mode 100644 index 000000000000..12bf14cc1152 --- /dev/null +++ b/tools/lib/traceevent/plugin_hrtimer.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt + * Copyright (C) 2009 Johannes Berg + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" + +static int timer_expire_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + trace_seq_printf(s, "hrtimer="); + + if (pevent_print_num_field(s, "0x%llx", event, "timer", + record, 0) == -1) + pevent_print_num_field(s, "0x%llx", event, "hrtimer", + record, 1); + + trace_seq_printf(s, " now="); + + pevent_print_num_field(s, "%llu", event, "now", record, 1); + + pevent_print_func_field(s, " function=%s", event, "function", + record, 0); + return 0; +} + +static int timer_start_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + trace_seq_printf(s, "hrtimer="); + + if (pevent_print_num_field(s, "0x%llx", event, "timer", + record, 0) == -1) + pevent_print_num_field(s, "0x%llx", event, "hrtimer", + record, 1); + + pevent_print_func_field(s, " function=%s", event, "function", + record, 0); + + trace_seq_printf(s, " expires="); + pevent_print_num_field(s, "%llu", event, "expires", record, 1); + + trace_seq_printf(s, " softexpires="); + pevent_print_num_field(s, "%llu", event, "softexpires", record, 1); + return 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_event_handler(pevent, -1, + "timer", "hrtimer_expire_entry", + timer_expire_handler, NULL); + + pevent_register_event_handler(pevent, -1, "timer", "hrtimer_start", + timer_start_handler, NULL); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_event_handler(pevent, -1, + "timer", "hrtimer_expire_entry", + timer_expire_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "timer", "hrtimer_start", + timer_start_handler, NULL); +} diff --git a/tools/lib/traceevent/plugin_jbd2.c b/tools/lib/traceevent/plugin_jbd2.c new file mode 100644 index 000000000000..0db714c721be --- /dev/null +++ b/tools/lib/traceevent/plugin_jbd2.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" + +#define MINORBITS 20 +#define MINORMASK ((1U << MINORBITS) - 1) + +#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) +#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) + +static unsigned long long +process_jbd2_dev_to_name(struct trace_seq *s, + unsigned long long *args) +{ + unsigned int dev = args[0]; + + trace_seq_printf(s, "%d:%d", MAJOR(dev), MINOR(dev)); + return 0; +} + +static unsigned long long +process_jiffies_to_msecs(struct trace_seq *s, + unsigned long long *args) +{ + unsigned long long jiffies = args[0]; + + trace_seq_printf(s, "%lld", jiffies); + return jiffies; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_print_function(pevent, + process_jbd2_dev_to_name, + PEVENT_FUNC_ARG_STRING, + "jbd2_dev_to_name", + PEVENT_FUNC_ARG_INT, + PEVENT_FUNC_ARG_VOID); + + pevent_register_print_function(pevent, + process_jiffies_to_msecs, + PEVENT_FUNC_ARG_LONG, + "jiffies_to_msecs", + PEVENT_FUNC_ARG_LONG, + PEVENT_FUNC_ARG_VOID); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_print_function(pevent, process_jbd2_dev_to_name, + "jbd2_dev_to_name"); + + pevent_unregister_print_function(pevent, process_jiffies_to_msecs, + "jiffies_to_msecs"); +} diff --git a/tools/lib/traceevent/plugin_kmem.c b/tools/lib/traceevent/plugin_kmem.c new file mode 100644 index 000000000000..70650ff48d78 --- /dev/null +++ b/tools/lib/traceevent/plugin_kmem.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" + +static int call_site_handler(struct trace_seq *s, struct pevent_record *record, + struct event_format *event, void *context) +{ + struct format_field *field; + unsigned long long val, addr; + void *data = record->data; + const char *func; + + field = pevent_find_field(event, "call_site"); + if (!field) + return 1; + + if (pevent_read_number_field(field, data, &val)) + return 1; + + func = pevent_find_function(event->pevent, val); + if (!func) + return 1; + + addr = pevent_find_function_address(event->pevent, val); + + trace_seq_printf(s, "(%s+0x%x) ", func, (int)(val - addr)); + return 1; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_event_handler(pevent, -1, "kmem", "kfree", + call_site_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kmem", "kmalloc", + call_site_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kmem", "kmalloc_node", + call_site_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_alloc", + call_site_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kmem", + "kmem_cache_alloc_node", + call_site_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kmem", "kmem_cache_free", + call_site_handler, NULL); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_event_handler(pevent, -1, "kmem", "kfree", + call_site_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc", + call_site_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kmem", "kmalloc_node", + call_site_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_alloc", + call_site_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kmem", + "kmem_cache_alloc_node", + call_site_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kmem", "kmem_cache_free", + call_site_handler, NULL); +} diff --git a/tools/lib/traceevent/plugin_kvm.c b/tools/lib/traceevent/plugin_kvm.c new file mode 100644 index 000000000000..9e0e8c61b43b --- /dev/null +++ b/tools/lib/traceevent/plugin_kvm.c @@ -0,0 +1,465 @@ +/* + * Copyright (C) 2009 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include +#include + +#include "event-parse.h" + +#ifdef HAVE_UDIS86 + +#include + +static ud_t ud; + +static void init_disassembler(void) +{ + ud_init(&ud); + ud_set_syntax(&ud, UD_SYN_ATT); +} + +static const char *disassemble(unsigned char *insn, int len, uint64_t rip, + int cr0_pe, int eflags_vm, + int cs_d, int cs_l) +{ + int mode; + + if (!cr0_pe) + mode = 16; + else if (eflags_vm) + mode = 16; + else if (cs_l) + mode = 64; + else if (cs_d) + mode = 32; + else + mode = 16; + + ud_set_pc(&ud, rip); + ud_set_mode(&ud, mode); + ud_set_input_buffer(&ud, insn, len); + ud_disassemble(&ud); + return ud_insn_asm(&ud); +} + +#else + +static void init_disassembler(void) +{ +} + +static const char *disassemble(unsigned char *insn, int len, uint64_t rip, + int cr0_pe, int eflags_vm, + int cs_d, int cs_l) +{ + static char out[15*3+1]; + int i; + + for (i = 0; i < len; ++i) + sprintf(out + i * 3, "%02x ", insn[i]); + out[len*3-1] = '\0'; + return out; +} + +#endif + + +#define VMX_EXIT_REASONS \ + _ER(EXCEPTION_NMI, 0) \ + _ER(EXTERNAL_INTERRUPT, 1) \ + _ER(TRIPLE_FAULT, 2) \ + _ER(PENDING_INTERRUPT, 7) \ + _ER(NMI_WINDOW, 8) \ + _ER(TASK_SWITCH, 9) \ + _ER(CPUID, 10) \ + _ER(HLT, 12) \ + _ER(INVD, 13) \ + _ER(INVLPG, 14) \ + _ER(RDPMC, 15) \ + _ER(RDTSC, 16) \ + _ER(VMCALL, 18) \ + _ER(VMCLEAR, 19) \ + _ER(VMLAUNCH, 20) \ + _ER(VMPTRLD, 21) \ + _ER(VMPTRST, 22) \ + _ER(VMREAD, 23) \ + _ER(VMRESUME, 24) \ + _ER(VMWRITE, 25) \ + _ER(VMOFF, 26) \ + _ER(VMON, 27) \ + _ER(CR_ACCESS, 28) \ + _ER(DR_ACCESS, 29) \ + _ER(IO_INSTRUCTION, 30) \ + _ER(MSR_READ, 31) \ + _ER(MSR_WRITE, 32) \ + _ER(MWAIT_INSTRUCTION, 36) \ + _ER(MONITOR_INSTRUCTION, 39) \ + _ER(PAUSE_INSTRUCTION, 40) \ + _ER(MCE_DURING_VMENTRY, 41) \ + _ER(TPR_BELOW_THRESHOLD, 43) \ + _ER(APIC_ACCESS, 44) \ + _ER(EOI_INDUCED, 45) \ + _ER(EPT_VIOLATION, 48) \ + _ER(EPT_MISCONFIG, 49) \ + _ER(INVEPT, 50) \ + _ER(PREEMPTION_TIMER, 52) \ + _ER(WBINVD, 54) \ + _ER(XSETBV, 55) \ + _ER(APIC_WRITE, 56) \ + _ER(INVPCID, 58) + +#define SVM_EXIT_REASONS \ + _ER(EXIT_READ_CR0, 0x000) \ + _ER(EXIT_READ_CR3, 0x003) \ + _ER(EXIT_READ_CR4, 0x004) \ + _ER(EXIT_READ_CR8, 0x008) \ + _ER(EXIT_WRITE_CR0, 0x010) \ + _ER(EXIT_WRITE_CR3, 0x013) \ + _ER(EXIT_WRITE_CR4, 0x014) \ + _ER(EXIT_WRITE_CR8, 0x018) \ + _ER(EXIT_READ_DR0, 0x020) \ + _ER(EXIT_READ_DR1, 0x021) \ + _ER(EXIT_READ_DR2, 0x022) \ + _ER(EXIT_READ_DR3, 0x023) \ + _ER(EXIT_READ_DR4, 0x024) \ + _ER(EXIT_READ_DR5, 0x025) \ + _ER(EXIT_READ_DR6, 0x026) \ + _ER(EXIT_READ_DR7, 0x027) \ + _ER(EXIT_WRITE_DR0, 0x030) \ + _ER(EXIT_WRITE_DR1, 0x031) \ + _ER(EXIT_WRITE_DR2, 0x032) \ + _ER(EXIT_WRITE_DR3, 0x033) \ + _ER(EXIT_WRITE_DR4, 0x034) \ + _ER(EXIT_WRITE_DR5, 0x035) \ + _ER(EXIT_WRITE_DR6, 0x036) \ + _ER(EXIT_WRITE_DR7, 0x037) \ + _ER(EXIT_EXCP_BASE, 0x040) \ + _ER(EXIT_INTR, 0x060) \ + _ER(EXIT_NMI, 0x061) \ + _ER(EXIT_SMI, 0x062) \ + _ER(EXIT_INIT, 0x063) \ + _ER(EXIT_VINTR, 0x064) \ + _ER(EXIT_CR0_SEL_WRITE, 0x065) \ + _ER(EXIT_IDTR_READ, 0x066) \ + _ER(EXIT_GDTR_READ, 0x067) \ + _ER(EXIT_LDTR_READ, 0x068) \ + _ER(EXIT_TR_READ, 0x069) \ + _ER(EXIT_IDTR_WRITE, 0x06a) \ + _ER(EXIT_GDTR_WRITE, 0x06b) \ + _ER(EXIT_LDTR_WRITE, 0x06c) \ + _ER(EXIT_TR_WRITE, 0x06d) \ + _ER(EXIT_RDTSC, 0x06e) \ + _ER(EXIT_RDPMC, 0x06f) \ + _ER(EXIT_PUSHF, 0x070) \ + _ER(EXIT_POPF, 0x071) \ + _ER(EXIT_CPUID, 0x072) \ + _ER(EXIT_RSM, 0x073) \ + _ER(EXIT_IRET, 0x074) \ + _ER(EXIT_SWINT, 0x075) \ + _ER(EXIT_INVD, 0x076) \ + _ER(EXIT_PAUSE, 0x077) \ + _ER(EXIT_HLT, 0x078) \ + _ER(EXIT_INVLPG, 0x079) \ + _ER(EXIT_INVLPGA, 0x07a) \ + _ER(EXIT_IOIO, 0x07b) \ + _ER(EXIT_MSR, 0x07c) \ + _ER(EXIT_TASK_SWITCH, 0x07d) \ + _ER(EXIT_FERR_FREEZE, 0x07e) \ + _ER(EXIT_SHUTDOWN, 0x07f) \ + _ER(EXIT_VMRUN, 0x080) \ + _ER(EXIT_VMMCALL, 0x081) \ + _ER(EXIT_VMLOAD, 0x082) \ + _ER(EXIT_VMSAVE, 0x083) \ + _ER(EXIT_STGI, 0x084) \ + _ER(EXIT_CLGI, 0x085) \ + _ER(EXIT_SKINIT, 0x086) \ + _ER(EXIT_RDTSCP, 0x087) \ + _ER(EXIT_ICEBP, 0x088) \ + _ER(EXIT_WBINVD, 0x089) \ + _ER(EXIT_MONITOR, 0x08a) \ + _ER(EXIT_MWAIT, 0x08b) \ + _ER(EXIT_MWAIT_COND, 0x08c) \ + _ER(EXIT_NPF, 0x400) \ + _ER(EXIT_ERR, -1) + +#define _ER(reason, val) { #reason, val }, +struct str_values { + const char *str; + int val; +}; + +static struct str_values vmx_exit_reasons[] = { + VMX_EXIT_REASONS + { NULL, -1} +}; + +static struct str_values svm_exit_reasons[] = { + SVM_EXIT_REASONS + { NULL, -1} +}; + +static struct isa_exit_reasons { + unsigned isa; + struct str_values *strings; +} isa_exit_reasons[] = { + { .isa = 1, .strings = vmx_exit_reasons }, + { .isa = 2, .strings = svm_exit_reasons }, + { } +}; + +static const char *find_exit_reason(unsigned isa, int val) +{ + struct str_values *strings = NULL; + int i; + + for (i = 0; isa_exit_reasons[i].strings; ++i) + if (isa_exit_reasons[i].isa == isa) { + strings = isa_exit_reasons[i].strings; + break; + } + if (!strings) + return "UNKNOWN-ISA"; + for (i = 0; strings[i].val >= 0; i++) + if (strings[i].val == val) + break; + if (strings[i].str) + return strings[i].str; + return "UNKNOWN"; +} + +static int kvm_exit_handler(struct trace_seq *s, struct pevent_record *record, + struct event_format *event, void *context) +{ + unsigned long long isa; + unsigned long long val; + unsigned long long info1 = 0, info2 = 0; + + if (pevent_get_field_val(s, event, "exit_reason", record, &val, 1) < 0) + return -1; + + if (pevent_get_field_val(s, event, "isa", record, &isa, 0) < 0) + isa = 1; + + trace_seq_printf(s, "reason %s", find_exit_reason(isa, val)); + + pevent_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1); + + if (pevent_get_field_val(s, event, "info1", record, &info1, 0) >= 0 + && pevent_get_field_val(s, event, "info2", record, &info2, 0) >= 0) + trace_seq_printf(s, " info %llx %llx", info1, info2); + + return 0; +} + +#define KVM_EMUL_INSN_F_CR0_PE (1 << 0) +#define KVM_EMUL_INSN_F_EFL_VM (1 << 1) +#define KVM_EMUL_INSN_F_CS_D (1 << 2) +#define KVM_EMUL_INSN_F_CS_L (1 << 3) + +static int kvm_emulate_insn_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + unsigned long long rip, csbase, len, flags, failed; + int llen; + uint8_t *insn; + const char *disasm; + + if (pevent_get_field_val(s, event, "rip", record, &rip, 1) < 0) + return -1; + + if (pevent_get_field_val(s, event, "csbase", record, &csbase, 1) < 0) + return -1; + + if (pevent_get_field_val(s, event, "len", record, &len, 1) < 0) + return -1; + + if (pevent_get_field_val(s, event, "flags", record, &flags, 1) < 0) + return -1; + + if (pevent_get_field_val(s, event, "failed", record, &failed, 1) < 0) + return -1; + + insn = pevent_get_field_raw(s, event, "insn", record, &llen, 1); + if (!insn) + return -1; + + disasm = disassemble(insn, len, rip, + flags & KVM_EMUL_INSN_F_CR0_PE, + flags & KVM_EMUL_INSN_F_EFL_VM, + flags & KVM_EMUL_INSN_F_CS_D, + flags & KVM_EMUL_INSN_F_CS_L); + + trace_seq_printf(s, "%llx:%llx: %s%s", csbase, rip, disasm, + failed ? " FAIL" : ""); + return 0; +} + +union kvm_mmu_page_role { + unsigned word; + struct { + unsigned glevels:4; + unsigned level:4; + unsigned quadrant:2; + unsigned pad_for_nice_hex_output:6; + unsigned direct:1; + unsigned access:3; + unsigned invalid:1; + unsigned cr4_pge:1; + unsigned nxe:1; + }; +}; + +static int kvm_mmu_print_role(struct trace_seq *s, struct pevent_record *record, + struct event_format *event, void *context) +{ + unsigned long long val; + static const char *access_str[] = { + "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" + }; + union kvm_mmu_page_role role; + + if (pevent_get_field_val(s, event, "role", record, &val, 1) < 0) + return -1; + + role.word = (int)val; + + /* + * We can only use the structure if file is of the same + * endianess. + */ + if (pevent_is_file_bigendian(event->pevent) == + pevent_is_host_bigendian(event->pevent)) { + + trace_seq_printf(s, "%u/%u q%u%s %s%s %spge %snxe", + role.level, + role.glevels, + role.quadrant, + role.direct ? " direct" : "", + access_str[role.access], + role.invalid ? " invalid" : "", + role.cr4_pge ? "" : "!", + role.nxe ? "" : "!"); + } else + trace_seq_printf(s, "WORD: %08x", role.word); + + pevent_print_num_field(s, " root %u ", event, + "root_count", record, 1); + + if (pevent_get_field_val(s, event, "unsync", record, &val, 1) < 0) + return -1; + + trace_seq_printf(s, "%s%c", val ? "unsync" : "sync", 0); + return 0; +} + +static int kvm_mmu_get_page_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + unsigned long long val; + + if (pevent_get_field_val(s, event, "created", record, &val, 1) < 0) + return -1; + + trace_seq_printf(s, "%s ", val ? "new" : "existing"); + + if (pevent_get_field_val(s, event, "gfn", record, &val, 1) < 0) + return -1; + + trace_seq_printf(s, "sp gfn %llx ", val); + return kvm_mmu_print_role(s, record, event, context); +} + +#define PT_WRITABLE_SHIFT 1 +#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) + +static unsigned long long +process_is_writable_pte(struct trace_seq *s, unsigned long long *args) +{ + unsigned long pte = args[0]; + return pte & PT_WRITABLE_MASK; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + init_disassembler(); + + pevent_register_event_handler(pevent, -1, "kvm", "kvm_exit", + kvm_exit_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kvm", "kvm_emulate_insn", + kvm_emulate_insn_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page", + kvm_mmu_get_page_handler, NULL); + + pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page", + kvm_mmu_print_role, NULL); + + pevent_register_event_handler(pevent, -1, + "kvmmmu", "kvm_mmu_unsync_page", + kvm_mmu_print_role, NULL); + + pevent_register_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page", + kvm_mmu_print_role, NULL); + + pevent_register_event_handler(pevent, -1, "kvmmmu", + "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, + NULL); + + pevent_register_print_function(pevent, + process_is_writable_pte, + PEVENT_FUNC_ARG_INT, + "is_writable_pte", + PEVENT_FUNC_ARG_LONG, + PEVENT_FUNC_ARG_VOID); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_exit", + kvm_exit_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kvm", "kvm_emulate_insn", + kvm_emulate_insn_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_get_page", + kvm_mmu_get_page_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_sync_page", + kvm_mmu_print_role, NULL); + + pevent_unregister_event_handler(pevent, -1, + "kvmmmu", "kvm_mmu_unsync_page", + kvm_mmu_print_role, NULL); + + pevent_unregister_event_handler(pevent, -1, "kvmmmu", "kvm_mmu_zap_page", + kvm_mmu_print_role, NULL); + + pevent_unregister_event_handler(pevent, -1, "kvmmmu", + "kvm_mmu_prepare_zap_page", kvm_mmu_print_role, + NULL); + + pevent_unregister_print_function(pevent, process_is_writable_pte, + "is_writable_pte"); +} diff --git a/tools/lib/traceevent/plugin_mac80211.c b/tools/lib/traceevent/plugin_mac80211.c new file mode 100644 index 000000000000..7e15a0f1c2fd --- /dev/null +++ b/tools/lib/traceevent/plugin_mac80211.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009 Johannes Berg + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" + +#define INDENT 65 + +static void print_string(struct trace_seq *s, struct event_format *event, + const char *name, const void *data) +{ + struct format_field *f = pevent_find_field(event, name); + int offset; + int length; + + if (!f) { + trace_seq_printf(s, "NOTFOUND:%s", name); + return; + } + + offset = f->offset; + length = f->size; + + if (!strncmp(f->type, "__data_loc", 10)) { + unsigned long long v; + if (pevent_read_number_field(f, data, &v)) { + trace_seq_printf(s, "invalid_data_loc"); + return; + } + offset = v & 0xffff; + length = v >> 16; + } + + trace_seq_printf(s, "%.*s", length, (char *)data + offset); +} + +#define SF(fn) pevent_print_num_field(s, fn ":%d", event, fn, record, 0) +#define SFX(fn) pevent_print_num_field(s, fn ":%#x", event, fn, record, 0) +#define SP() trace_seq_putc(s, ' ') + +static int drv_bss_info_changed(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + void *data = record->data; + + print_string(s, event, "wiphy_name", data); + trace_seq_printf(s, " vif:"); + print_string(s, event, "vif_name", data); + pevent_print_num_field(s, "(%d)", event, "vif_type", record, 1); + + trace_seq_printf(s, "\n%*s", INDENT, ""); + SF("assoc"); SP(); + SF("aid"); SP(); + SF("cts"); SP(); + SF("shortpre"); SP(); + SF("shortslot"); SP(); + SF("dtimper"); SP(); + trace_seq_printf(s, "\n%*s", INDENT, ""); + SF("bcnint"); SP(); + SFX("assoc_cap"); SP(); + SFX("basic_rates"); SP(); + SF("enable_beacon"); + trace_seq_printf(s, "\n%*s", INDENT, ""); + SF("ht_operation_mode"); + + return 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_event_handler(pevent, -1, "mac80211", + "drv_bss_info_changed", + drv_bss_info_changed, NULL); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_event_handler(pevent, -1, "mac80211", + "drv_bss_info_changed", + drv_bss_info_changed, NULL); +} diff --git a/tools/lib/traceevent/plugin_sched_switch.c b/tools/lib/traceevent/plugin_sched_switch.c new file mode 100644 index 000000000000..f1ce60065258 --- /dev/null +++ b/tools/lib/traceevent/plugin_sched_switch.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License (not later!) + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include +#include + +#include "event-parse.h" + +static void write_state(struct trace_seq *s, int val) +{ + const char states[] = "SDTtZXxW"; + int found = 0; + int i; + + for (i = 0; i < (sizeof(states) - 1); i++) { + if (!(val & (1 << i))) + continue; + + if (found) + trace_seq_putc(s, '|'); + + found = 1; + trace_seq_putc(s, states[i]); + } + + if (!found) + trace_seq_putc(s, 'R'); +} + +static void write_and_save_comm(struct format_field *field, + struct pevent_record *record, + struct trace_seq *s, int pid) +{ + const char *comm; + int len; + + comm = (char *)(record->data + field->offset); + len = s->len; + trace_seq_printf(s, "%.*s", + field->size, comm); + + /* make sure the comm has a \0 at the end. */ + trace_seq_terminate(s); + comm = &s->buffer[len]; + + /* Help out the comm to ids. This will handle dups */ + pevent_register_comm(field->event->pevent, comm, pid); +} + +static int sched_wakeup_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + struct format_field *field; + unsigned long long val; + + if (pevent_get_field_val(s, event, "pid", record, &val, 1)) + return trace_seq_putc(s, '!'); + + field = pevent_find_any_field(event, "comm"); + if (field) { + write_and_save_comm(field, record, s, val); + trace_seq_putc(s, ':'); + } + trace_seq_printf(s, "%lld", val); + + if (pevent_get_field_val(s, event, "prio", record, &val, 0) == 0) + trace_seq_printf(s, " [%lld]", val); + + if (pevent_get_field_val(s, event, "success", record, &val, 1) == 0) + trace_seq_printf(s, " success=%lld", val); + + if (pevent_get_field_val(s, event, "target_cpu", record, &val, 0) == 0) + trace_seq_printf(s, " CPU:%03llu", val); + + return 0; +} + +static int sched_switch_handler(struct trace_seq *s, + struct pevent_record *record, + struct event_format *event, void *context) +{ + struct format_field *field; + unsigned long long val; + + if (pevent_get_field_val(s, event, "prev_pid", record, &val, 1)) + return trace_seq_putc(s, '!'); + + field = pevent_find_any_field(event, "prev_comm"); + if (field) { + write_and_save_comm(field, record, s, val); + trace_seq_putc(s, ':'); + } + trace_seq_printf(s, "%lld ", val); + + if (pevent_get_field_val(s, event, "prev_prio", record, &val, 0) == 0) + trace_seq_printf(s, "[%lld] ", val); + + if (pevent_get_field_val(s, event, "prev_state", record, &val, 0) == 0) + write_state(s, val); + + trace_seq_puts(s, " ==> "); + + if (pevent_get_field_val(s, event, "next_pid", record, &val, 1)) + return trace_seq_putc(s, '!'); + + field = pevent_find_any_field(event, "next_comm"); + if (field) { + write_and_save_comm(field, record, s, val); + trace_seq_putc(s, ':'); + } + trace_seq_printf(s, "%lld", val); + + if (pevent_get_field_val(s, event, "next_prio", record, &val, 0) == 0) + trace_seq_printf(s, " [%lld]", val); + + return 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_event_handler(pevent, -1, "sched", "sched_switch", + sched_switch_handler, NULL); + + pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup", + sched_wakeup_handler, NULL); + + pevent_register_event_handler(pevent, -1, "sched", "sched_wakeup_new", + sched_wakeup_handler, NULL); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_event_handler(pevent, -1, "sched", "sched_switch", + sched_switch_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup", + sched_wakeup_handler, NULL); + + pevent_unregister_event_handler(pevent, -1, "sched", "sched_wakeup_new", + sched_wakeup_handler, NULL); +} diff --git a/tools/lib/traceevent/plugin_scsi.c b/tools/lib/traceevent/plugin_scsi.c new file mode 100644 index 000000000000..eda326fc8620 --- /dev/null +++ b/tools/lib/traceevent/plugin_scsi.c @@ -0,0 +1,429 @@ +#include +#include +#include +#include "event-parse.h" + +typedef unsigned long sector_t; +typedef uint64_t u64; +typedef unsigned int u32; + +/* + * SCSI opcodes + */ +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define INITIALIZE_ELEMENT_STATUS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e + +#define READ_FORMAT_CAPACITIES 0x23 +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define POSITION_TO_ELEMENT 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define UNMAP 0x42 +#define READ_TOC 0x43 +#define READ_HEADER 0x44 +#define GET_EVENT_STATUS_NOTIFICATION 0x4a +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 +#define MODE_SELECT_10 0x55 +#define RESERVE_10 0x56 +#define RELEASE_10 0x57 +#define MODE_SENSE_10 0x5a +#define PERSISTENT_RESERVE_IN 0x5e +#define PERSISTENT_RESERVE_OUT 0x5f +#define VARIABLE_LENGTH_CMD 0x7f +#define REPORT_LUNS 0xa0 +#define SECURITY_PROTOCOL_IN 0xa2 +#define MAINTENANCE_IN 0xa3 +#define MAINTENANCE_OUT 0xa4 +#define MOVE_MEDIUM 0xa5 +#define EXCHANGE_MEDIUM 0xa6 +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define READ_MEDIA_SERIAL_NUMBER 0xab +#define WRITE_VERIFY_12 0xae +#define VERIFY_12 0xaf +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define SECURITY_PROTOCOL_OUT 0xb5 +#define READ_ELEMENT_STATUS 0xb8 +#define SEND_VOLUME_TAG 0xb6 +#define WRITE_LONG_2 0xea +#define EXTENDED_COPY 0x83 +#define RECEIVE_COPY_RESULTS 0x84 +#define ACCESS_CONTROL_IN 0x86 +#define ACCESS_CONTROL_OUT 0x87 +#define READ_16 0x88 +#define WRITE_16 0x8a +#define READ_ATTRIBUTE 0x8c +#define WRITE_ATTRIBUTE 0x8d +#define VERIFY_16 0x8f +#define SYNCHRONIZE_CACHE_16 0x91 +#define WRITE_SAME_16 0x93 +#define SERVICE_ACTION_IN 0x9e +/* values for service action in */ +#define SAI_READ_CAPACITY_16 0x10 +#define SAI_GET_LBA_STATUS 0x12 +/* values for VARIABLE_LENGTH_CMD service action codes + * see spc4r17 Section D.3.5, table D.7 and D.8 */ +#define VLC_SA_RECEIVE_CREDENTIAL 0x1800 +/* values for maintenance in */ +#define MI_REPORT_IDENTIFYING_INFORMATION 0x05 +#define MI_REPORT_TARGET_PGS 0x0a +#define MI_REPORT_ALIASES 0x0b +#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c +#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d +#define MI_REPORT_PRIORITY 0x0e +#define MI_REPORT_TIMESTAMP 0x0f +#define MI_MANAGEMENT_PROTOCOL_IN 0x10 +/* value for MI_REPORT_TARGET_PGS ext header */ +#define MI_EXT_HDR_PARAM_FMT 0x20 +/* values for maintenance out */ +#define MO_SET_IDENTIFYING_INFORMATION 0x06 +#define MO_SET_TARGET_PGS 0x0a +#define MO_CHANGE_ALIASES 0x0b +#define MO_SET_PRIORITY 0x0e +#define MO_SET_TIMESTAMP 0x0f +#define MO_MANAGEMENT_PROTOCOL_OUT 0x10 +/* values for variable length command */ +#define XDREAD_32 0x03 +#define XDWRITE_32 0x04 +#define XPWRITE_32 0x06 +#define XDWRITEREAD_32 0x07 +#define READ_32 0x09 +#define VERIFY_32 0x0a +#define WRITE_32 0x0b +#define WRITE_SAME_32 0x0d + +#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) +#define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9]) + +static const char * +scsi_trace_misc(struct trace_seq *, unsigned char *, int); + +static const char * +scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= ((cdb[1] & 0x1F) << 16); + lba |= (cdb[2] << 8); + lba |= cdb[3]; + txlen = cdb[4]; + + trace_seq_printf(p, "lba=%llu txlen=%llu", + (unsigned long long)lba, (unsigned long long)txlen); + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= (cdb[2] << 24); + lba |= (cdb[3] << 16); + lba |= (cdb[4] << 8); + lba |= cdb[5]; + txlen |= (cdb[7] << 8); + txlen |= cdb[8]; + + trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", + (unsigned long long)lba, (unsigned long long)txlen, + cdb[1] >> 5); + + if (cdb[0] == WRITE_SAME) + trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); + + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= (cdb[2] << 24); + lba |= (cdb[3] << 16); + lba |= (cdb[4] << 8); + lba |= cdb[5]; + txlen |= (cdb[6] << 24); + txlen |= (cdb[7] << 16); + txlen |= (cdb[8] << 8); + txlen |= cdb[9]; + + trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", + (unsigned long long)lba, (unsigned long long)txlen, + cdb[1] >> 5); + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + sector_t lba = 0, txlen = 0; + + lba |= ((u64)cdb[2] << 56); + lba |= ((u64)cdb[3] << 48); + lba |= ((u64)cdb[4] << 40); + lba |= ((u64)cdb[5] << 32); + lba |= (cdb[6] << 24); + lba |= (cdb[7] << 16); + lba |= (cdb[8] << 8); + lba |= cdb[9]; + txlen |= (cdb[10] << 24); + txlen |= (cdb[11] << 16); + txlen |= (cdb[12] << 8); + txlen |= cdb[13]; + + trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", + (unsigned long long)lba, (unsigned long long)txlen, + cdb[1] >> 5); + + if (cdb[0] == WRITE_SAME_16) + trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1); + + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len, *cmd; + sector_t lba = 0, txlen = 0; + u32 ei_lbrt = 0; + + switch (SERVICE_ACTION32(cdb)) { + case READ_32: + cmd = "READ"; + break; + case VERIFY_32: + cmd = "VERIFY"; + break; + case WRITE_32: + cmd = "WRITE"; + break; + case WRITE_SAME_32: + cmd = "WRITE_SAME"; + break; + default: + trace_seq_printf(p, "UNKNOWN"); + goto out; + } + + lba |= ((u64)cdb[12] << 56); + lba |= ((u64)cdb[13] << 48); + lba |= ((u64)cdb[14] << 40); + lba |= ((u64)cdb[15] << 32); + lba |= (cdb[16] << 24); + lba |= (cdb[17] << 16); + lba |= (cdb[18] << 8); + lba |= cdb[19]; + ei_lbrt |= (cdb[20] << 24); + ei_lbrt |= (cdb[21] << 16); + ei_lbrt |= (cdb[22] << 8); + ei_lbrt |= cdb[23]; + txlen |= (cdb[28] << 24); + txlen |= (cdb[29] << 16); + txlen |= (cdb[30] << 8); + txlen |= cdb[31]; + + trace_seq_printf(p, "%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u", + cmd, (unsigned long long)lba, + (unsigned long long)txlen, cdb[10] >> 5, ei_lbrt); + + if (SERVICE_ACTION32(cdb) == WRITE_SAME_32) + trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1); + +out: + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + unsigned int regions = cdb[7] << 8 | cdb[8]; + + trace_seq_printf(p, "regions=%u", (regions - 8) / 16); + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len, *cmd; + sector_t lba = 0; + u32 alloc_len = 0; + + switch (SERVICE_ACTION16(cdb)) { + case SAI_READ_CAPACITY_16: + cmd = "READ_CAPACITY_16"; + break; + case SAI_GET_LBA_STATUS: + cmd = "GET_LBA_STATUS"; + break; + default: + trace_seq_printf(p, "UNKNOWN"); + goto out; + } + + lba |= ((u64)cdb[2] << 56); + lba |= ((u64)cdb[3] << 48); + lba |= ((u64)cdb[4] << 40); + lba |= ((u64)cdb[5] << 32); + lba |= (cdb[6] << 24); + lba |= (cdb[7] << 16); + lba |= (cdb[8] << 8); + lba |= cdb[9]; + alloc_len |= (cdb[10] << 24); + alloc_len |= (cdb[11] << 16); + alloc_len |= (cdb[12] << 8); + alloc_len |= cdb[13]; + + trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, + (unsigned long long)lba, alloc_len); + +out: + trace_seq_putc(p, 0); + return ret; +} + +static const char * +scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len) +{ + switch (SERVICE_ACTION32(cdb)) { + case READ_32: + case VERIFY_32: + case WRITE_32: + case WRITE_SAME_32: + return scsi_trace_rw32(p, cdb, len); + default: + return scsi_trace_misc(p, cdb, len); + } +} + +static const char * +scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len) +{ + const char *ret = p->buffer + p->len; + + trace_seq_printf(p, "-"); + trace_seq_putc(p, 0); + return ret; +} + +const char * +scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len) +{ + switch (cdb[0]) { + case READ_6: + case WRITE_6: + return scsi_trace_rw6(p, cdb, len); + case READ_10: + case VERIFY: + case WRITE_10: + case WRITE_SAME: + return scsi_trace_rw10(p, cdb, len); + case READ_12: + case VERIFY_12: + case WRITE_12: + return scsi_trace_rw12(p, cdb, len); + case READ_16: + case VERIFY_16: + case WRITE_16: + case WRITE_SAME_16: + return scsi_trace_rw16(p, cdb, len); + case UNMAP: + return scsi_trace_unmap(p, cdb, len); + case SERVICE_ACTION_IN: + return scsi_trace_service_action_in(p, cdb, len); + case VARIABLE_LENGTH_CMD: + return scsi_trace_varlen(p, cdb, len); + default: + return scsi_trace_misc(p, cdb, len); + } +} + +unsigned long long process_scsi_trace_parse_cdb(struct trace_seq *s, + unsigned long long *args) +{ + scsi_trace_parse_cdb(s, (unsigned char *) (unsigned long) args[1], args[2]); + return 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_print_function(pevent, + process_scsi_trace_parse_cdb, + PEVENT_FUNC_ARG_STRING, + "scsi_trace_parse_cdb", + PEVENT_FUNC_ARG_PTR, + PEVENT_FUNC_ARG_PTR, + PEVENT_FUNC_ARG_INT, + PEVENT_FUNC_ARG_VOID); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_print_function(pevent, process_scsi_trace_parse_cdb, + "scsi_trace_parse_cdb"); +} diff --git a/tools/lib/traceevent/plugin_xen.c b/tools/lib/traceevent/plugin_xen.c new file mode 100644 index 000000000000..3a413eaada68 --- /dev/null +++ b/tools/lib/traceevent/plugin_xen.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include "event-parse.h" + +#define __HYPERVISOR_set_trap_table 0 +#define __HYPERVISOR_mmu_update 1 +#define __HYPERVISOR_set_gdt 2 +#define __HYPERVISOR_stack_switch 3 +#define __HYPERVISOR_set_callbacks 4 +#define __HYPERVISOR_fpu_taskswitch 5 +#define __HYPERVISOR_sched_op_compat 6 +#define __HYPERVISOR_dom0_op 7 +#define __HYPERVISOR_set_debugreg 8 +#define __HYPERVISOR_get_debugreg 9 +#define __HYPERVISOR_update_descriptor 10 +#define __HYPERVISOR_memory_op 12 +#define __HYPERVISOR_multicall 13 +#define __HYPERVISOR_update_va_mapping 14 +#define __HYPERVISOR_set_timer_op 15 +#define __HYPERVISOR_event_channel_op_compat 16 +#define __HYPERVISOR_xen_version 17 +#define __HYPERVISOR_console_io 18 +#define __HYPERVISOR_physdev_op_compat 19 +#define __HYPERVISOR_grant_table_op 20 +#define __HYPERVISOR_vm_assist 21 +#define __HYPERVISOR_update_va_mapping_otherdomain 22 +#define __HYPERVISOR_iret 23 /* x86 only */ +#define __HYPERVISOR_vcpu_op 24 +#define __HYPERVISOR_set_segment_base 25 /* x86/64 only */ +#define __HYPERVISOR_mmuext_op 26 +#define __HYPERVISOR_acm_op 27 +#define __HYPERVISOR_nmi_op 28 +#define __HYPERVISOR_sched_op 29 +#define __HYPERVISOR_callback_op 30 +#define __HYPERVISOR_xenoprof_op 31 +#define __HYPERVISOR_event_channel_op 32 +#define __HYPERVISOR_physdev_op 33 +#define __HYPERVISOR_hvm_op 34 +#define __HYPERVISOR_tmem_op 38 + +/* Architecture-specific hypercall definitions. */ +#define __HYPERVISOR_arch_0 48 +#define __HYPERVISOR_arch_1 49 +#define __HYPERVISOR_arch_2 50 +#define __HYPERVISOR_arch_3 51 +#define __HYPERVISOR_arch_4 52 +#define __HYPERVISOR_arch_5 53 +#define __HYPERVISOR_arch_6 54 +#define __HYPERVISOR_arch_7 55 + +#define N(x) [__HYPERVISOR_##x] = "("#x")" +static const char *xen_hypercall_names[] = { + N(set_trap_table), + N(mmu_update), + N(set_gdt), + N(stack_switch), + N(set_callbacks), + N(fpu_taskswitch), + N(sched_op_compat), + N(dom0_op), + N(set_debugreg), + N(get_debugreg), + N(update_descriptor), + N(memory_op), + N(multicall), + N(update_va_mapping), + N(set_timer_op), + N(event_channel_op_compat), + N(xen_version), + N(console_io), + N(physdev_op_compat), + N(grant_table_op), + N(vm_assist), + N(update_va_mapping_otherdomain), + N(iret), + N(vcpu_op), + N(set_segment_base), + N(mmuext_op), + N(acm_op), + N(nmi_op), + N(sched_op), + N(callback_op), + N(xenoprof_op), + N(event_channel_op), + N(physdev_op), + N(hvm_op), + +/* Architecture-specific hypercall definitions. */ + N(arch_0), + N(arch_1), + N(arch_2), + N(arch_3), + N(arch_4), + N(arch_5), + N(arch_6), + N(arch_7), +}; +#undef N + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +static const char *xen_hypercall_name(unsigned op) +{ + if (op < ARRAY_SIZE(xen_hypercall_names) && + xen_hypercall_names[op] != NULL) + return xen_hypercall_names[op]; + + return ""; +} + +unsigned long long process_xen_hypercall_name(struct trace_seq *s, + unsigned long long *args) +{ + unsigned int op = args[0]; + + trace_seq_printf(s, "%s", xen_hypercall_name(op)); + return 0; +} + +int PEVENT_PLUGIN_LOADER(struct pevent *pevent) +{ + pevent_register_print_function(pevent, + process_xen_hypercall_name, + PEVENT_FUNC_ARG_STRING, + "xen_hypercall_name", + PEVENT_FUNC_ARG_INT, + PEVENT_FUNC_ARG_VOID); + return 0; +} + +void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent) +{ + pevent_unregister_print_function(pevent, process_xen_hypercall_name, + "xen_hypercall_name"); +} diff --git a/tools/lib/traceevent/trace-seq.c b/tools/lib/traceevent/trace-seq.c index d7f2e68bc5b9..ec3bd16a5488 100644 --- a/tools/lib/traceevent/trace-seq.c +++ b/tools/lib/traceevent/trace-seq.c @@ -22,6 +22,7 @@ #include #include +#include #include "event-parse.h" #include "event-utils.h" @@ -32,10 +33,21 @@ #define TRACE_SEQ_POISON ((void *)0xdeadbeef) #define TRACE_SEQ_CHECK(s) \ do { \ - if ((s)->buffer == TRACE_SEQ_POISON) \ - die("Usage of trace_seq after it was destroyed"); \ + if (WARN_ONCE((s)->buffer == TRACE_SEQ_POISON, \ + "Usage of trace_seq after it was destroyed")) \ + (s)->state = TRACE_SEQ__BUFFER_POISONED; \ } while (0) +#define TRACE_SEQ_CHECK_RET_N(s, n) \ +do { \ + TRACE_SEQ_CHECK(s); \ + if ((s)->state != TRACE_SEQ__GOOD) \ + return n; \ +} while (0) + +#define TRACE_SEQ_CHECK_RET(s) TRACE_SEQ_CHECK_RET_N(s, ) +#define TRACE_SEQ_CHECK_RET0(s) TRACE_SEQ_CHECK_RET_N(s, 0) + /** * trace_seq_init - initialize the trace_seq structure * @s: a pointer to the trace_seq structure to initialize @@ -45,7 +57,11 @@ void trace_seq_init(struct trace_seq *s) s->len = 0; s->readpos = 0; s->buffer_size = TRACE_SEQ_BUF_SIZE; - s->buffer = malloc_or_die(s->buffer_size); + s->buffer = malloc(s->buffer_size); + if (s->buffer != NULL) + s->state = TRACE_SEQ__GOOD; + else + s->state = TRACE_SEQ__MEM_ALLOC_FAILED; } /** @@ -71,17 +87,23 @@ void trace_seq_destroy(struct trace_seq *s) { if (!s) return; - TRACE_SEQ_CHECK(s); + TRACE_SEQ_CHECK_RET(s); free(s->buffer); s->buffer = TRACE_SEQ_POISON; } static void expand_buffer(struct trace_seq *s) { + char *buf; + + buf = realloc(s->buffer, s->buffer_size + TRACE_SEQ_BUF_SIZE); + if (WARN_ONCE(!buf, "Can't allocate trace_seq buffer memory")) { + s->state = TRACE_SEQ__MEM_ALLOC_FAILED; + return; + } + + s->buffer = buf; s->buffer_size += TRACE_SEQ_BUF_SIZE; - s->buffer = realloc(s->buffer, s->buffer_size); - if (!s->buffer) - die("Can't allocate trace_seq buffer memory"); } /** @@ -105,9 +127,9 @@ trace_seq_printf(struct trace_seq *s, const char *fmt, ...) int len; int ret; - TRACE_SEQ_CHECK(s); - try_again: + TRACE_SEQ_CHECK_RET0(s); + len = (s->buffer_size - 1) - s->len; va_start(ap, fmt); @@ -141,9 +163,9 @@ trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) int len; int ret; - TRACE_SEQ_CHECK(s); - try_again: + TRACE_SEQ_CHECK_RET0(s); + len = (s->buffer_size - 1) - s->len; ret = vsnprintf(s->buffer + s->len, len, fmt, args); @@ -172,13 +194,15 @@ int trace_seq_puts(struct trace_seq *s, const char *str) { int len; - TRACE_SEQ_CHECK(s); + TRACE_SEQ_CHECK_RET0(s); len = strlen(str); while (len > ((s->buffer_size - 1) - s->len)) expand_buffer(s); + TRACE_SEQ_CHECK_RET0(s); + memcpy(s->buffer + s->len, str, len); s->len += len; @@ -187,11 +211,13 @@ int trace_seq_puts(struct trace_seq *s, const char *str) int trace_seq_putc(struct trace_seq *s, unsigned char c) { - TRACE_SEQ_CHECK(s); + TRACE_SEQ_CHECK_RET0(s); while (s->len >= (s->buffer_size - 1)) expand_buffer(s); + TRACE_SEQ_CHECK_RET0(s); + s->buffer[s->len++] = c; return 1; @@ -199,7 +225,7 @@ int trace_seq_putc(struct trace_seq *s, unsigned char c) void trace_seq_terminate(struct trace_seq *s) { - TRACE_SEQ_CHECK(s); + TRACE_SEQ_CHECK_RET(s); /* There's always one character left on the buffer */ s->buffer[s->len] = 0; @@ -208,5 +234,16 @@ void trace_seq_terminate(struct trace_seq *s) int trace_seq_do_printf(struct trace_seq *s) { TRACE_SEQ_CHECK(s); - return printf("%.*s", s->len, s->buffer); + + switch (s->state) { + case TRACE_SEQ__GOOD: + return printf("%.*s", s->len, s->buffer); + case TRACE_SEQ__BUFFER_POISONED: + puts("Usage of trace_seq after it was destroyed"); + break; + case TRACE_SEQ__MEM_ALLOC_FAILED: + puts("Can't allocate trace_seq buffer memory"); + break; + } + return -1; } diff --git a/tools/net/Makefile b/tools/net/Makefile index b4444d53b73f..004cd74734b6 100644 --- a/tools/net/Makefile +++ b/tools/net/Makefile @@ -1,15 +1,34 @@ prefix = /usr CC = gcc +LEX = flex +YACC = bison -all : bpf_jit_disasm +%.yacc.c: %.y + $(YACC) -o $@ -d $< + +%.lex.c: %.l + $(LEX) -o $@ $< + +all : bpf_jit_disasm bpf_dbg bpf_asm bpf_jit_disasm : CFLAGS = -Wall -O2 bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl bpf_jit_disasm : bpf_jit_disasm.o +bpf_dbg : CFLAGS = -Wall -O2 +bpf_dbg : LDLIBS = -lreadline +bpf_dbg : bpf_dbg.o + +bpf_asm : CFLAGS = -Wall -O2 -I. +bpf_asm : LDLIBS = +bpf_asm : bpf_asm.o bpf_exp.yacc.o bpf_exp.lex.o +bpf_exp.lex.o : bpf_exp.yacc.c + clean : - rm -rf *.o bpf_jit_disasm + rm -rf *.o bpf_jit_disasm bpf_dbg bpf_asm bpf_exp.yacc.* bpf_exp.lex.* install : install bpf_jit_disasm $(prefix)/bin/bpf_jit_disasm + install bpf_dbg $(prefix)/bin/bpf_dbg + install bpf_asm $(prefix)/bin/bpf_asm diff --git a/tools/net/bpf_asm.c b/tools/net/bpf_asm.c new file mode 100644 index 000000000000..c15aef097b04 --- /dev/null +++ b/tools/net/bpf_asm.c @@ -0,0 +1,52 @@ +/* + * Minimal BPF assembler + * + * Instead of libpcap high-level filter expressions, it can be quite + * useful to define filters in low-level BPF assembler (that is kept + * close to Steven McCanne and Van Jacobson's original BPF paper). + * In particular for BPF JIT implementors, JIT security auditors, or + * just for defining BPF expressions that contain extensions which are + * not supported by compilers. + * + * How to get into it: + * + * 1) read Documentation/networking/filter.txt + * 2) Run `bpf_asm [-c] ` to translate into binary + * blob that is loadable with xt_bpf, cls_bpf et al. Note: -c will + * pretty print a C-like construct. + * + * Copyright 2013 Daniel Borkmann + * Licensed under the GNU General Public License, version 2.0 (GPLv2) + */ + +#include +#include +#include + +extern void bpf_asm_compile(FILE *fp, bool cstyle); + +int main(int argc, char **argv) +{ + FILE *fp = stdin; + bool cstyle = false; + int i; + + for (i = 1; i < argc; i++) { + if (!strncmp("-c", argv[i], 2)) { + cstyle = true; + continue; + } + + fp = fopen(argv[i], "r"); + if (!fp) { + fp = stdin; + continue; + } + + break; + } + + bpf_asm_compile(fp, cstyle); + + return 0; +} diff --git a/tools/net/bpf_dbg.c b/tools/net/bpf_dbg.c new file mode 100644 index 000000000000..65dc757f7f7b --- /dev/null +++ b/tools/net/bpf_dbg.c @@ -0,0 +1,1404 @@ +/* + * Minimal BPF debugger + * + * Minimal BPF debugger that mimics the kernel's engine (w/o extensions) + * and allows for single stepping through selected packets from a pcap + * with a provided user filter in order to facilitate verification of a + * BPF program. Besides others, this is useful to verify BPF programs + * before attaching to a live system, and can be used in socket filters, + * cls_bpf, xt_bpf, team driver and e.g. PTP code; in particular when a + * single more complex BPF program is being used. Reasons for a more + * complex BPF program are likely primarily to optimize execution time + * for making a verdict when multiple simple BPF programs are combined + * into one in order to prevent parsing same headers multiple times. + * + * More on how to debug BPF opcodes see Documentation/networking/filter.txt + * which is the main document on BPF. Mini howto for getting started: + * + * 1) `./bpf_dbg` to enter the shell (shell cmds denoted with '>'): + * 2) > load bpf 6,40 0 0 12,21 0 3 20... (output from `bpf_asm` or + * `tcpdump -iem1 -ddd port 22 | tr '\n' ','` to load as filter) + * 3) > load pcap foo.pcap + * 4) > run /disassemble/dump/quit (self-explanatory) + * 5) > breakpoint 2 (sets bp at loaded BPF insns 2, do `run` then; + * multiple bps can be set, of course, a call to `breakpoint` + * w/o args shows currently loaded bps, `breakpoint reset` for + * resetting all breakpoints) + * 6) > select 3 (`run` etc will start from the 3rd packet in the pcap) + * 7) > step [-, +] (performs single stepping through the BPF) + * + * Copyright 2013 Daniel Borkmann + * Licensed under the GNU General Public License, version 2.0 (GPLv2) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TCPDUMP_MAGIC 0xa1b2c3d4 + +#define BPF_LDX_B (BPF_LDX | BPF_B) +#define BPF_LDX_W (BPF_LDX | BPF_W) +#define BPF_JMP_JA (BPF_JMP | BPF_JA) +#define BPF_JMP_JEQ (BPF_JMP | BPF_JEQ) +#define BPF_JMP_JGT (BPF_JMP | BPF_JGT) +#define BPF_JMP_JGE (BPF_JMP | BPF_JGE) +#define BPF_JMP_JSET (BPF_JMP | BPF_JSET) +#define BPF_ALU_ADD (BPF_ALU | BPF_ADD) +#define BPF_ALU_SUB (BPF_ALU | BPF_SUB) +#define BPF_ALU_MUL (BPF_ALU | BPF_MUL) +#define BPF_ALU_DIV (BPF_ALU | BPF_DIV) +#define BPF_ALU_MOD (BPF_ALU | BPF_MOD) +#define BPF_ALU_NEG (BPF_ALU | BPF_NEG) +#define BPF_ALU_AND (BPF_ALU | BPF_AND) +#define BPF_ALU_OR (BPF_ALU | BPF_OR) +#define BPF_ALU_XOR (BPF_ALU | BPF_XOR) +#define BPF_ALU_LSH (BPF_ALU | BPF_LSH) +#define BPF_ALU_RSH (BPF_ALU | BPF_RSH) +#define BPF_MISC_TAX (BPF_MISC | BPF_TAX) +#define BPF_MISC_TXA (BPF_MISC | BPF_TXA) +#define BPF_LD_B (BPF_LD | BPF_B) +#define BPF_LD_H (BPF_LD | BPF_H) +#define BPF_LD_W (BPF_LD | BPF_W) + +#ifndef array_size +# define array_size(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#ifndef __check_format_printf +# define __check_format_printf(pos_fmtstr, pos_fmtargs) \ + __attribute__ ((format (printf, (pos_fmtstr), (pos_fmtargs)))) +#endif + +#define CMD(_name, _func) { .name = _name, .func = _func, } +#define OP(_op, _name) [_op] = _name + +enum { + CMD_OK, + CMD_ERR, + CMD_EX, +}; + +struct shell_cmd { + const char *name; + int (*func)(char *args); +}; + +struct pcap_filehdr { + uint32_t magic; + uint16_t version_major; + uint16_t version_minor; + int32_t thiszone; + uint32_t sigfigs; + uint32_t snaplen; + uint32_t linktype; +}; + +struct pcap_timeval { + int32_t tv_sec; + int32_t tv_usec; +}; + +struct pcap_pkthdr { + struct pcap_timeval ts; + uint32_t caplen; + uint32_t len; +}; + +struct bpf_regs { + uint32_t A; + uint32_t X; + uint32_t M[BPF_MEMWORDS]; + uint32_t R; + bool Rs; + uint16_t Pc; +}; + +static struct sock_filter bpf_image[BPF_MAXINSNS + 1]; +static unsigned int bpf_prog_len = 0; + +static int bpf_breakpoints[64]; +static struct bpf_regs bpf_regs[BPF_MAXINSNS + 1]; +static struct bpf_regs bpf_curr; +static unsigned int bpf_regs_len = 0; + +static int pcap_fd = -1; +static unsigned int pcap_packet = 0; +static size_t pcap_map_size = 0; +static char *pcap_ptr_va_start, *pcap_ptr_va_curr; + +static const char * const op_table[] = { + OP(BPF_ST, "st"), + OP(BPF_STX, "stx"), + OP(BPF_LD_B, "ldb"), + OP(BPF_LD_H, "ldh"), + OP(BPF_LD_W, "ld"), + OP(BPF_LDX, "ldx"), + OP(BPF_LDX_B, "ldxb"), + OP(BPF_JMP_JA, "ja"), + OP(BPF_JMP_JEQ, "jeq"), + OP(BPF_JMP_JGT, "jgt"), + OP(BPF_JMP_JGE, "jge"), + OP(BPF_JMP_JSET, "jset"), + OP(BPF_ALU_ADD, "add"), + OP(BPF_ALU_SUB, "sub"), + OP(BPF_ALU_MUL, "mul"), + OP(BPF_ALU_DIV, "div"), + OP(BPF_ALU_MOD, "mod"), + OP(BPF_ALU_NEG, "neg"), + OP(BPF_ALU_AND, "and"), + OP(BPF_ALU_OR, "or"), + OP(BPF_ALU_XOR, "xor"), + OP(BPF_ALU_LSH, "lsh"), + OP(BPF_ALU_RSH, "rsh"), + OP(BPF_MISC_TAX, "tax"), + OP(BPF_MISC_TXA, "txa"), + OP(BPF_RET, "ret"), +}; + +static __check_format_printf(1, 2) int rl_printf(const char *fmt, ...) +{ + int ret; + va_list vl; + + va_start(vl, fmt); + ret = vfprintf(rl_outstream, fmt, vl); + va_end(vl); + + return ret; +} + +static int matches(const char *cmd, const char *pattern) +{ + int len = strlen(cmd); + + if (len > strlen(pattern)) + return -1; + + return memcmp(pattern, cmd, len); +} + +static void hex_dump(const uint8_t *buf, size_t len) +{ + int i; + + rl_printf("%3u: ", 0); + for (i = 0; i < len; i++) { + if (i && !(i % 16)) + rl_printf("\n%3u: ", i); + rl_printf("%02x ", buf[i]); + } + rl_printf("\n"); +} + +static bool bpf_prog_loaded(void) +{ + if (bpf_prog_len == 0) + rl_printf("no bpf program loaded!\n"); + + return bpf_prog_len > 0; +} + +static void bpf_disasm(const struct sock_filter f, unsigned int i) +{ + const char *op, *fmt; + int val = f.k; + char buf[256]; + + switch (f.code) { + case BPF_RET | BPF_K: + op = op_table[BPF_RET]; + fmt = "#%#x"; + break; + case BPF_RET | BPF_A: + op = op_table[BPF_RET]; + fmt = "a"; + break; + case BPF_RET | BPF_X: + op = op_table[BPF_RET]; + fmt = "x"; + break; + case BPF_MISC_TAX: + op = op_table[BPF_MISC_TAX]; + fmt = ""; + break; + case BPF_MISC_TXA: + op = op_table[BPF_MISC_TXA]; + fmt = ""; + break; + case BPF_ST: + op = op_table[BPF_ST]; + fmt = "M[%d]"; + break; + case BPF_STX: + op = op_table[BPF_STX]; + fmt = "M[%d]"; + break; + case BPF_LD_W | BPF_ABS: + op = op_table[BPF_LD_W]; + fmt = "[%d]"; + break; + case BPF_LD_H | BPF_ABS: + op = op_table[BPF_LD_H]; + fmt = "[%d]"; + break; + case BPF_LD_B | BPF_ABS: + op = op_table[BPF_LD_B]; + fmt = "[%d]"; + break; + case BPF_LD_W | BPF_LEN: + op = op_table[BPF_LD_W]; + fmt = "#len"; + break; + case BPF_LD_W | BPF_IND: + op = op_table[BPF_LD_W]; + fmt = "[x+%d]"; + break; + case BPF_LD_H | BPF_IND: + op = op_table[BPF_LD_H]; + fmt = "[x+%d]"; + break; + case BPF_LD_B | BPF_IND: + op = op_table[BPF_LD_B]; + fmt = "[x+%d]"; + break; + case BPF_LD | BPF_IMM: + op = op_table[BPF_LD_W]; + fmt = "#%#x"; + break; + case BPF_LDX | BPF_IMM: + op = op_table[BPF_LDX]; + fmt = "#%#x"; + break; + case BPF_LDX_B | BPF_MSH: + op = op_table[BPF_LDX_B]; + fmt = "4*([%d]&0xf)"; + break; + case BPF_LD | BPF_MEM: + op = op_table[BPF_LD_W]; + fmt = "M[%d]"; + break; + case BPF_LDX | BPF_MEM: + op = op_table[BPF_LDX]; + fmt = "M[%d]"; + break; + case BPF_JMP_JA: + op = op_table[BPF_JMP_JA]; + fmt = "%d"; + val = i + 1 + f.k; + break; + case BPF_JMP_JGT | BPF_X: + op = op_table[BPF_JMP_JGT]; + fmt = "x"; + break; + case BPF_JMP_JGT | BPF_K: + op = op_table[BPF_JMP_JGT]; + fmt = "#%#x"; + break; + case BPF_JMP_JGE | BPF_X: + op = op_table[BPF_JMP_JGE]; + fmt = "x"; + break; + case BPF_JMP_JGE | BPF_K: + op = op_table[BPF_JMP_JGE]; + fmt = "#%#x"; + break; + case BPF_JMP_JEQ | BPF_X: + op = op_table[BPF_JMP_JEQ]; + fmt = "x"; + break; + case BPF_JMP_JEQ | BPF_K: + op = op_table[BPF_JMP_JEQ]; + fmt = "#%#x"; + break; + case BPF_JMP_JSET | BPF_X: + op = op_table[BPF_JMP_JSET]; + fmt = "x"; + break; + case BPF_JMP_JSET | BPF_K: + op = op_table[BPF_JMP_JSET]; + fmt = "#%#x"; + break; + case BPF_ALU_NEG: + op = op_table[BPF_ALU_NEG]; + fmt = ""; + break; + case BPF_ALU_LSH | BPF_X: + op = op_table[BPF_ALU_LSH]; + fmt = "x"; + break; + case BPF_ALU_LSH | BPF_K: + op = op_table[BPF_ALU_LSH]; + fmt = "#%d"; + break; + case BPF_ALU_RSH | BPF_X: + op = op_table[BPF_ALU_RSH]; + fmt = "x"; + break; + case BPF_ALU_RSH | BPF_K: + op = op_table[BPF_ALU_RSH]; + fmt = "#%d"; + break; + case BPF_ALU_ADD | BPF_X: + op = op_table[BPF_ALU_ADD]; + fmt = "x"; + break; + case BPF_ALU_ADD | BPF_K: + op = op_table[BPF_ALU_ADD]; + fmt = "#%d"; + break; + case BPF_ALU_SUB | BPF_X: + op = op_table[BPF_ALU_SUB]; + fmt = "x"; + break; + case BPF_ALU_SUB | BPF_K: + op = op_table[BPF_ALU_SUB]; + fmt = "#%d"; + break; + case BPF_ALU_MUL | BPF_X: + op = op_table[BPF_ALU_MUL]; + fmt = "x"; + break; + case BPF_ALU_MUL | BPF_K: + op = op_table[BPF_ALU_MUL]; + fmt = "#%d"; + break; + case BPF_ALU_DIV | BPF_X: + op = op_table[BPF_ALU_DIV]; + fmt = "x"; + break; + case BPF_ALU_DIV | BPF_K: + op = op_table[BPF_ALU_DIV]; + fmt = "#%d"; + break; + case BPF_ALU_MOD | BPF_X: + op = op_table[BPF_ALU_MOD]; + fmt = "x"; + break; + case BPF_ALU_MOD | BPF_K: + op = op_table[BPF_ALU_MOD]; + fmt = "#%d"; + break; + case BPF_ALU_AND | BPF_X: + op = op_table[BPF_ALU_AND]; + fmt = "x"; + break; + case BPF_ALU_AND | BPF_K: + op = op_table[BPF_ALU_AND]; + fmt = "#%#x"; + break; + case BPF_ALU_OR | BPF_X: + op = op_table[BPF_ALU_OR]; + fmt = "x"; + break; + case BPF_ALU_OR | BPF_K: + op = op_table[BPF_ALU_OR]; + fmt = "#%#x"; + break; + case BPF_ALU_XOR | BPF_X: + op = op_table[BPF_ALU_XOR]; + fmt = "x"; + break; + case BPF_ALU_XOR | BPF_K: + op = op_table[BPF_ALU_XOR]; + fmt = "#%#x"; + break; + default: + op = "nosup"; + fmt = "%#x"; + val = f.code; + break; + } + + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf), fmt, val); + buf[sizeof(buf) - 1] = 0; + + if ((BPF_CLASS(f.code) == BPF_JMP && BPF_OP(f.code) != BPF_JA)) + rl_printf("l%d:\t%s %s, l%d, l%d\n", i, op, buf, + i + 1 + f.jt, i + 1 + f.jf); + else + rl_printf("l%d:\t%s %s\n", i, op, buf); +} + +static void bpf_dump_curr(struct bpf_regs *r, struct sock_filter *f) +{ + int i, m = 0; + + rl_printf("pc: [%u]\n", r->Pc); + rl_printf("code: [%u] jt[%u] jf[%u] k[%u]\n", + f->code, f->jt, f->jf, f->k); + rl_printf("curr: "); + bpf_disasm(*f, r->Pc); + + if (f->jt || f->jf) { + rl_printf("jt: "); + bpf_disasm(*(f + f->jt + 1), r->Pc + f->jt + 1); + rl_printf("jf: "); + bpf_disasm(*(f + f->jf + 1), r->Pc + f->jf + 1); + } + + rl_printf("A: [%#08x][%u]\n", r->A, r->A); + rl_printf("X: [%#08x][%u]\n", r->X, r->X); + if (r->Rs) + rl_printf("ret: [%#08x][%u]!\n", r->R, r->R); + + for (i = 0; i < BPF_MEMWORDS; i++) { + if (r->M[i]) { + m++; + rl_printf("M[%d]: [%#08x][%u]\n", i, r->M[i], r->M[i]); + } + } + if (m == 0) + rl_printf("M[0,%d]: [%#08x][%u]\n", BPF_MEMWORDS - 1, 0, 0); +} + +static void bpf_dump_pkt(uint8_t *pkt, uint32_t pkt_caplen, uint32_t pkt_len) +{ + if (pkt_caplen != pkt_len) + rl_printf("cap: %u, len: %u\n", pkt_caplen, pkt_len); + else + rl_printf("len: %u\n", pkt_len); + + hex_dump(pkt, pkt_caplen); +} + +static void bpf_disasm_all(const struct sock_filter *f, unsigned int len) +{ + unsigned int i; + + for (i = 0; i < len; i++) + bpf_disasm(f[i], i); +} + +static void bpf_dump_all(const struct sock_filter *f, unsigned int len) +{ + unsigned int i; + + rl_printf("/* { op, jt, jf, k }, */\n"); + for (i = 0; i < len; i++) + rl_printf("{ %#04x, %2u, %2u, %#010x },\n", + f[i].code, f[i].jt, f[i].jf, f[i].k); +} + +static bool bpf_runnable(struct sock_filter *f, unsigned int len) +{ + int sock, ret, i; + struct sock_fprog bpf = { + .filter = f, + .len = len, + }; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + rl_printf("cannot open socket!\n"); + return false; + } + ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); + close(sock); + if (ret < 0) { + rl_printf("program not allowed to run by kernel!\n"); + return false; + } + for (i = 0; i < len; i++) { + if (BPF_CLASS(f[i].code) == BPF_LD && + f[i].k > SKF_AD_OFF) { + rl_printf("extensions currently not supported!\n"); + return false; + } + } + + return true; +} + +static void bpf_reset_breakpoints(void) +{ + int i; + + for (i = 0; i < array_size(bpf_breakpoints); i++) + bpf_breakpoints[i] = -1; +} + +static void bpf_set_breakpoints(unsigned int where) +{ + int i; + bool set = false; + + for (i = 0; i < array_size(bpf_breakpoints); i++) { + if (bpf_breakpoints[i] == (int) where) { + rl_printf("breakpoint already set!\n"); + set = true; + break; + } + + if (bpf_breakpoints[i] == -1 && set == false) { + bpf_breakpoints[i] = where; + set = true; + } + } + + if (!set) + rl_printf("too many breakpoints set, reset first!\n"); +} + +static void bpf_dump_breakpoints(void) +{ + int i; + + rl_printf("breakpoints: "); + + for (i = 0; i < array_size(bpf_breakpoints); i++) { + if (bpf_breakpoints[i] < 0) + continue; + rl_printf("%d ", bpf_breakpoints[i]); + } + + rl_printf("\n"); +} + +static void bpf_reset(void) +{ + bpf_regs_len = 0; + + memset(bpf_regs, 0, sizeof(bpf_regs)); + memset(&bpf_curr, 0, sizeof(bpf_curr)); +} + +static void bpf_safe_regs(void) +{ + memcpy(&bpf_regs[bpf_regs_len++], &bpf_curr, sizeof(bpf_curr)); +} + +static bool bpf_restore_regs(int off) +{ + unsigned int index = bpf_regs_len - 1 + off; + + if (index == 0) { + bpf_reset(); + return true; + } else if (index < bpf_regs_len) { + memcpy(&bpf_curr, &bpf_regs[index], sizeof(bpf_curr)); + bpf_regs_len = index; + return true; + } else { + rl_printf("reached bottom of register history stack!\n"); + return false; + } +} + +static uint32_t extract_u32(uint8_t *pkt, uint32_t off) +{ + uint32_t r; + + memcpy(&r, &pkt[off], sizeof(r)); + + return ntohl(r); +} + +static uint16_t extract_u16(uint8_t *pkt, uint32_t off) +{ + uint16_t r; + + memcpy(&r, &pkt[off], sizeof(r)); + + return ntohs(r); +} + +static uint8_t extract_u8(uint8_t *pkt, uint32_t off) +{ + return pkt[off]; +} + +static void set_return(struct bpf_regs *r) +{ + r->R = 0; + r->Rs = true; +} + +static void bpf_single_step(struct bpf_regs *r, struct sock_filter *f, + uint8_t *pkt, uint32_t pkt_caplen, + uint32_t pkt_len) +{ + uint32_t K = f->k; + int d; + + switch (f->code) { + case BPF_RET | BPF_K: + r->R = K; + r->Rs = true; + break; + case BPF_RET | BPF_A: + r->R = r->A; + r->Rs = true; + break; + case BPF_RET | BPF_X: + r->R = r->X; + r->Rs = true; + break; + case BPF_MISC_TAX: + r->X = r->A; + break; + case BPF_MISC_TXA: + r->A = r->X; + break; + case BPF_ST: + r->M[K] = r->A; + break; + case BPF_STX: + r->M[K] = r->X; + break; + case BPF_LD_W | BPF_ABS: + d = pkt_caplen - K; + if (d >= sizeof(uint32_t)) + r->A = extract_u32(pkt, K); + else + set_return(r); + break; + case BPF_LD_H | BPF_ABS: + d = pkt_caplen - K; + if (d >= sizeof(uint16_t)) + r->A = extract_u16(pkt, K); + else + set_return(r); + break; + case BPF_LD_B | BPF_ABS: + d = pkt_caplen - K; + if (d >= sizeof(uint8_t)) + r->A = extract_u8(pkt, K); + else + set_return(r); + break; + case BPF_LD_W | BPF_IND: + d = pkt_caplen - (r->X + K); + if (d >= sizeof(uint32_t)) + r->A = extract_u32(pkt, r->X + K); + break; + case BPF_LD_H | BPF_IND: + d = pkt_caplen - (r->X + K); + if (d >= sizeof(uint16_t)) + r->A = extract_u16(pkt, r->X + K); + else + set_return(r); + break; + case BPF_LD_B | BPF_IND: + d = pkt_caplen - (r->X + K); + if (d >= sizeof(uint8_t)) + r->A = extract_u8(pkt, r->X + K); + else + set_return(r); + break; + case BPF_LDX_B | BPF_MSH: + d = pkt_caplen - K; + if (d >= sizeof(uint8_t)) { + r->X = extract_u8(pkt, K); + r->X = (r->X & 0xf) << 2; + } else + set_return(r); + break; + case BPF_LD_W | BPF_LEN: + r->A = pkt_len; + break; + case BPF_LDX_W | BPF_LEN: + r->A = pkt_len; + break; + case BPF_LD | BPF_IMM: + r->A = K; + break; + case BPF_LDX | BPF_IMM: + r->X = K; + break; + case BPF_LD | BPF_MEM: + r->A = r->M[K]; + break; + case BPF_LDX | BPF_MEM: + r->X = r->M[K]; + break; + case BPF_JMP_JA: + r->Pc += K; + break; + case BPF_JMP_JGT | BPF_X: + r->Pc += r->A > r->X ? f->jt : f->jf; + break; + case BPF_JMP_JGT | BPF_K: + r->Pc += r->A > K ? f->jt : f->jf; + break; + case BPF_JMP_JGE | BPF_X: + r->Pc += r->A >= r->X ? f->jt : f->jf; + break; + case BPF_JMP_JGE | BPF_K: + r->Pc += r->A >= K ? f->jt : f->jf; + break; + case BPF_JMP_JEQ | BPF_X: + r->Pc += r->A == r->X ? f->jt : f->jf; + break; + case BPF_JMP_JEQ | BPF_K: + r->Pc += r->A == K ? f->jt : f->jf; + break; + case BPF_JMP_JSET | BPF_X: + r->Pc += r->A & r->X ? f->jt : f->jf; + break; + case BPF_JMP_JSET | BPF_K: + r->Pc += r->A & K ? f->jt : f->jf; + break; + case BPF_ALU_NEG: + r->A = -r->A; + break; + case BPF_ALU_LSH | BPF_X: + r->A <<= r->X; + break; + case BPF_ALU_LSH | BPF_K: + r->A <<= K; + break; + case BPF_ALU_RSH | BPF_X: + r->A >>= r->X; + break; + case BPF_ALU_RSH | BPF_K: + r->A >>= K; + break; + case BPF_ALU_ADD | BPF_X: + r->A += r->X; + break; + case BPF_ALU_ADD | BPF_K: + r->A += K; + break; + case BPF_ALU_SUB | BPF_X: + r->A -= r->X; + break; + case BPF_ALU_SUB | BPF_K: + r->A -= K; + break; + case BPF_ALU_MUL | BPF_X: + r->A *= r->X; + break; + case BPF_ALU_MUL | BPF_K: + r->A *= K; + break; + case BPF_ALU_DIV | BPF_X: + case BPF_ALU_MOD | BPF_X: + if (r->X == 0) { + set_return(r); + break; + } + goto do_div; + case BPF_ALU_DIV | BPF_K: + case BPF_ALU_MOD | BPF_K: + if (K == 0) { + set_return(r); + break; + } +do_div: + switch (f->code) { + case BPF_ALU_DIV | BPF_X: + r->A /= r->X; + break; + case BPF_ALU_DIV | BPF_K: + r->A /= K; + break; + case BPF_ALU_MOD | BPF_X: + r->A %= r->X; + break; + case BPF_ALU_MOD | BPF_K: + r->A %= K; + break; + } + break; + case BPF_ALU_AND | BPF_X: + r->A &= r->X; + break; + case BPF_ALU_AND | BPF_K: + r->A &= r->X; + break; + case BPF_ALU_OR | BPF_X: + r->A |= r->X; + break; + case BPF_ALU_OR | BPF_K: + r->A |= K; + break; + case BPF_ALU_XOR | BPF_X: + r->A ^= r->X; + break; + case BPF_ALU_XOR | BPF_K: + r->A ^= K; + break; + } +} + +static bool bpf_pc_has_breakpoint(uint16_t pc) +{ + int i; + + for (i = 0; i < array_size(bpf_breakpoints); i++) { + if (bpf_breakpoints[i] < 0) + continue; + if (bpf_breakpoints[i] == pc) + return true; + } + + return false; +} + +static bool bpf_handle_breakpoint(struct bpf_regs *r, struct sock_filter *f, + uint8_t *pkt, uint32_t pkt_caplen, + uint32_t pkt_len) +{ + rl_printf("-- register dump --\n"); + bpf_dump_curr(r, &f[r->Pc]); + rl_printf("-- packet dump --\n"); + bpf_dump_pkt(pkt, pkt_caplen, pkt_len); + rl_printf("(breakpoint)\n"); + return true; +} + +static int bpf_run_all(struct sock_filter *f, uint16_t bpf_len, uint8_t *pkt, + uint32_t pkt_caplen, uint32_t pkt_len) +{ + bool stop = false; + + while (bpf_curr.Rs == false && stop == false) { + bpf_safe_regs(); + + if (bpf_pc_has_breakpoint(bpf_curr.Pc)) + stop = bpf_handle_breakpoint(&bpf_curr, f, pkt, + pkt_caplen, pkt_len); + + bpf_single_step(&bpf_curr, &f[bpf_curr.Pc], pkt, pkt_caplen, + pkt_len); + bpf_curr.Pc++; + } + + return stop ? -1 : bpf_curr.R; +} + +static int bpf_run_stepping(struct sock_filter *f, uint16_t bpf_len, + uint8_t *pkt, uint32_t pkt_caplen, + uint32_t pkt_len, int next) +{ + bool stop = false; + int i = 1; + + while (bpf_curr.Rs == false && stop == false) { + bpf_safe_regs(); + + if (i++ == next) + stop = bpf_handle_breakpoint(&bpf_curr, f, pkt, + pkt_caplen, pkt_len); + + bpf_single_step(&bpf_curr, &f[bpf_curr.Pc], pkt, pkt_caplen, + pkt_len); + bpf_curr.Pc++; + } + + return stop ? -1 : bpf_curr.R; +} + +static bool pcap_loaded(void) +{ + if (pcap_fd < 0) + rl_printf("no pcap file loaded!\n"); + + return pcap_fd >= 0; +} + +static struct pcap_pkthdr *pcap_curr_pkt(void) +{ + return (void *) pcap_ptr_va_curr; +} + +static bool pcap_next_pkt(void) +{ + struct pcap_pkthdr *hdr = pcap_curr_pkt(); + + if (pcap_ptr_va_curr + sizeof(*hdr) - + pcap_ptr_va_start >= pcap_map_size) + return false; + if (hdr->caplen == 0 || hdr->len == 0 || hdr->caplen > hdr->len) + return false; + if (pcap_ptr_va_curr + sizeof(*hdr) + hdr->caplen - + pcap_ptr_va_start >= pcap_map_size) + return false; + + pcap_ptr_va_curr += (sizeof(*hdr) + hdr->caplen); + return true; +} + +static void pcap_reset_pkt(void) +{ + pcap_ptr_va_curr = pcap_ptr_va_start + sizeof(struct pcap_filehdr); +} + +static int try_load_pcap(const char *file) +{ + struct pcap_filehdr *hdr; + struct stat sb; + int ret; + + pcap_fd = open(file, O_RDONLY); + if (pcap_fd < 0) { + rl_printf("cannot open pcap [%s]!\n", strerror(errno)); + return CMD_ERR; + } + + ret = fstat(pcap_fd, &sb); + if (ret < 0) { + rl_printf("cannot fstat pcap file!\n"); + return CMD_ERR; + } + + if (!S_ISREG(sb.st_mode)) { + rl_printf("not a regular pcap file, duh!\n"); + return CMD_ERR; + } + + pcap_map_size = sb.st_size; + if (pcap_map_size <= sizeof(struct pcap_filehdr)) { + rl_printf("pcap file too small!\n"); + return CMD_ERR; + } + + pcap_ptr_va_start = mmap(NULL, pcap_map_size, PROT_READ, + MAP_SHARED | MAP_LOCKED, pcap_fd, 0); + if (pcap_ptr_va_start == MAP_FAILED) { + rl_printf("mmap of file failed!"); + return CMD_ERR; + } + + hdr = (void *) pcap_ptr_va_start; + if (hdr->magic != TCPDUMP_MAGIC) { + rl_printf("wrong pcap magic!\n"); + return CMD_ERR; + } + + pcap_reset_pkt(); + + return CMD_OK; + +} + +static void try_close_pcap(void) +{ + if (pcap_fd >= 0) { + munmap(pcap_ptr_va_start, pcap_map_size); + close(pcap_fd); + + pcap_ptr_va_start = pcap_ptr_va_curr = NULL; + pcap_map_size = 0; + pcap_packet = 0; + pcap_fd = -1; + } +} + +static int cmd_load_bpf(char *bpf_string) +{ + char sp, *token, separator = ','; + unsigned short bpf_len, i = 0; + struct sock_filter tmp; + + bpf_prog_len = 0; + memset(bpf_image, 0, sizeof(bpf_image)); + + if (sscanf(bpf_string, "%hu%c", &bpf_len, &sp) != 2 || + sp != separator || bpf_len > BPF_MAXINSNS || bpf_len == 0) { + rl_printf("syntax error in head length encoding!\n"); + return CMD_ERR; + } + + token = bpf_string; + while ((token = strchr(token, separator)) && (++token)[0]) { + if (i >= bpf_len) { + rl_printf("program exceeds encoded length!\n"); + return CMD_ERR; + } + + if (sscanf(token, "%hu %hhu %hhu %u,", + &tmp.code, &tmp.jt, &tmp.jf, &tmp.k) != 4) { + rl_printf("syntax error at instruction %d!\n", i); + return CMD_ERR; + } + + bpf_image[i].code = tmp.code; + bpf_image[i].jt = tmp.jt; + bpf_image[i].jf = tmp.jf; + bpf_image[i].k = tmp.k; + + i++; + } + + if (i != bpf_len) { + rl_printf("syntax error exceeding encoded length!\n"); + return CMD_ERR; + } else + bpf_prog_len = bpf_len; + if (!bpf_runnable(bpf_image, bpf_prog_len)) + bpf_prog_len = 0; + + return CMD_OK; +} + +static int cmd_load_pcap(char *file) +{ + char *file_trim, *tmp; + + file_trim = strtok_r(file, " ", &tmp); + if (file_trim == NULL) + return CMD_ERR; + + try_close_pcap(); + + return try_load_pcap(file_trim); +} + +static int cmd_load(char *arg) +{ + char *subcmd, *cont, *tmp = strdup(arg); + int ret = CMD_OK; + + subcmd = strtok_r(tmp, " ", &cont); + if (subcmd == NULL) + goto out; + if (matches(subcmd, "bpf") == 0) { + bpf_reset(); + bpf_reset_breakpoints(); + + ret = cmd_load_bpf(cont); + } else if (matches(subcmd, "pcap") == 0) { + ret = cmd_load_pcap(cont); + } else { +out: + rl_printf("bpf : load bpf code\n"); + rl_printf("pcap : load pcap file\n"); + ret = CMD_ERR; + } + + free(tmp); + return ret; +} + +static int cmd_step(char *num) +{ + struct pcap_pkthdr *hdr; + int steps, ret; + + if (!bpf_prog_loaded() || !pcap_loaded()) + return CMD_ERR; + + steps = strtol(num, NULL, 10); + if (steps == 0 || strlen(num) == 0) + steps = 1; + if (steps < 0) { + if (!bpf_restore_regs(steps)) + return CMD_ERR; + steps = 1; + } + + hdr = pcap_curr_pkt(); + ret = bpf_run_stepping(bpf_image, bpf_prog_len, + (uint8_t *) hdr + sizeof(*hdr), + hdr->caplen, hdr->len, steps); + if (ret >= 0 || bpf_curr.Rs) { + bpf_reset(); + if (!pcap_next_pkt()) { + rl_printf("(going back to first packet)\n"); + pcap_reset_pkt(); + } else { + rl_printf("(next packet)\n"); + } + } + + return CMD_OK; +} + +static int cmd_select(char *num) +{ + unsigned int which, i; + struct pcap_pkthdr *hdr; + bool have_next = true; + + if (!pcap_loaded() || strlen(num) == 0) + return CMD_ERR; + + which = strtoul(num, NULL, 10); + if (which == 0) { + rl_printf("packet count starts with 1, clamping!\n"); + which = 1; + } + + pcap_reset_pkt(); + bpf_reset(); + + for (i = 0; i < which && (have_next = pcap_next_pkt()); i++) + /* noop */; + if (!have_next || (hdr = pcap_curr_pkt()) == NULL) { + rl_printf("no packet #%u available!\n", which); + pcap_reset_pkt(); + return CMD_ERR; + } + + return CMD_OK; +} + +static int cmd_breakpoint(char *subcmd) +{ + if (!bpf_prog_loaded()) + return CMD_ERR; + if (strlen(subcmd) == 0) + bpf_dump_breakpoints(); + else if (matches(subcmd, "reset") == 0) + bpf_reset_breakpoints(); + else { + unsigned int where = strtoul(subcmd, NULL, 10); + + if (where < bpf_prog_len) { + bpf_set_breakpoints(where); + rl_printf("breakpoint at: "); + bpf_disasm(bpf_image[where], where); + } + } + + return CMD_OK; +} + +static int cmd_run(char *num) +{ + static uint32_t pass = 0, fail = 0; + struct pcap_pkthdr *hdr; + bool has_limit = true; + int ret, pkts = 0, i = 0; + + if (!bpf_prog_loaded() || !pcap_loaded()) + return CMD_ERR; + + pkts = strtol(num, NULL, 10); + if (pkts == 0 || strlen(num) == 0) + has_limit = false; + + do { + hdr = pcap_curr_pkt(); + ret = bpf_run_all(bpf_image, bpf_prog_len, + (uint8_t *) hdr + sizeof(*hdr), + hdr->caplen, hdr->len); + if (ret > 0) + pass++; + else if (ret == 0) + fail++; + else + return CMD_OK; + bpf_reset(); + } while (pcap_next_pkt() && (!has_limit || (has_limit && ++i < pkts))); + + rl_printf("bpf passes:%u fails:%u\n", pass, fail); + + pcap_reset_pkt(); + bpf_reset(); + + pass = fail = 0; + return CMD_OK; +} + +static int cmd_disassemble(char *line_string) +{ + bool single_line = false; + unsigned long line; + + if (!bpf_prog_loaded()) + return CMD_ERR; + if (strlen(line_string) > 0 && + (line = strtoul(line_string, NULL, 10)) < bpf_prog_len) + single_line = true; + if (single_line) + bpf_disasm(bpf_image[line], line); + else + bpf_disasm_all(bpf_image, bpf_prog_len); + + return CMD_OK; +} + +static int cmd_dump(char *dontcare) +{ + if (!bpf_prog_loaded()) + return CMD_ERR; + + bpf_dump_all(bpf_image, bpf_prog_len); + + return CMD_OK; +} + +static int cmd_quit(char *dontcare) +{ + return CMD_EX; +} + +static const struct shell_cmd cmds[] = { + CMD("load", cmd_load), + CMD("select", cmd_select), + CMD("step", cmd_step), + CMD("run", cmd_run), + CMD("breakpoint", cmd_breakpoint), + CMD("disassemble", cmd_disassemble), + CMD("dump", cmd_dump), + CMD("quit", cmd_quit), +}; + +static int execf(char *arg) +{ + char *cmd, *cont, *tmp = strdup(arg); + int i, ret = 0, len; + + cmd = strtok_r(tmp, " ", &cont); + if (cmd == NULL) + goto out; + len = strlen(cmd); + for (i = 0; i < array_size(cmds); i++) { + if (len != strlen(cmds[i].name)) + continue; + if (strncmp(cmds[i].name, cmd, len) == 0) { + ret = cmds[i].func(cont); + break; + } + } +out: + free(tmp); + return ret; +} + +static char *shell_comp_gen(const char *buf, int state) +{ + static int list_index, len; + const char *name; + + if (!state) { + list_index = 0; + len = strlen(buf); + } + + for (; list_index < array_size(cmds); ) { + name = cmds[list_index].name; + list_index++; + + if (strncmp(name, buf, len) == 0) + return strdup(name); + } + + return NULL; +} + +static char **shell_completion(const char *buf, int start, int end) +{ + char **matches = NULL; + + if (start == 0) + matches = rl_completion_matches(buf, shell_comp_gen); + + return matches; +} + +static void intr_shell(int sig) +{ + if (rl_end) + rl_kill_line(-1, 0); + + rl_crlf(); + rl_refresh_line(0, 0); + rl_free_line_state(); +} + +static void init_shell(FILE *fin, FILE *fout) +{ + char file[128]; + + memset(file, 0, sizeof(file)); + snprintf(file, sizeof(file) - 1, + "%s/.bpf_dbg_history", getenv("HOME")); + + read_history(file); + + memset(file, 0, sizeof(file)); + snprintf(file, sizeof(file) - 1, + "%s/.bpf_dbg_init", getenv("HOME")); + + rl_instream = fin; + rl_outstream = fout; + + rl_readline_name = "bpf_dbg"; + rl_terminal_name = getenv("TERM"); + + rl_catch_signals = 0; + rl_catch_sigwinch = 1; + + rl_attempted_completion_function = shell_completion; + + rl_bind_key('\t', rl_complete); + + rl_bind_key_in_map('\t', rl_complete, emacs_meta_keymap); + rl_bind_key_in_map('\033', rl_complete, emacs_meta_keymap); + + rl_read_init_file(file); + rl_prep_terminal(0); + rl_set_signals(); + + signal(SIGINT, intr_shell); +} + +static void exit_shell(void) +{ + char file[128]; + + memset(file, 0, sizeof(file)); + snprintf(file, sizeof(file) - 1, + "%s/.bpf_dbg_history", getenv("HOME")); + + write_history(file); + clear_history(); + rl_deprep_terminal(); + + try_close_pcap(); +} + +static int run_shell_loop(FILE *fin, FILE *fout) +{ + char *buf; + int ret; + + init_shell(fin, fout); + + while ((buf = readline("> ")) != NULL) { + ret = execf(buf); + if (ret == CMD_EX) + break; + if (ret == CMD_OK && strlen(buf) > 0) + add_history(buf); + + free(buf); + } + + exit_shell(); + return 0; +} + +int main(int argc, char **argv) +{ + FILE *fin = NULL, *fout = NULL; + + if (argc >= 2) + fin = fopen(argv[1], "r"); + if (argc >= 3) + fout = fopen(argv[2], "w"); + + return run_shell_loop(fin ? : stdin, fout ? : stdout); +} diff --git a/tools/net/bpf_exp.l b/tools/net/bpf_exp.l new file mode 100644 index 000000000000..bf7be77ddd62 --- /dev/null +++ b/tools/net/bpf_exp.l @@ -0,0 +1,143 @@ +/* + * BPF asm code lexer + * + * This program is free software; you can distribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * Syntax kept close to: + * + * Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new + * architecture for user-level packet capture. In Proceedings of the + * USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 + * Conference Proceedings (USENIX'93). USENIX Association, Berkeley, + * CA, USA, 2-2. + * + * Copyright 2013 Daniel Borkmann + * Licensed under the GNU General Public License, version 2.0 (GPLv2) + */ + +%{ + +#include +#include +#include + +#include "bpf_exp.yacc.h" + +extern void yyerror(const char *str); + +%} + +%option align +%option ecs + +%option nounput +%option noreject +%option noinput +%option noyywrap + +%option 8bit +%option caseless +%option yylineno + +%% + +"ldb" { return OP_LDB; } +"ldh" { return OP_LDH; } +"ld" { return OP_LD; } +"ldi" { return OP_LDI; } +"ldx" { return OP_LDX; } +"ldxi" { return OP_LDXI; } +"ldxb" { return OP_LDXB; } +"st" { return OP_ST; } +"stx" { return OP_STX; } +"jmp" { return OP_JMP; } +"ja" { return OP_JMP; } +"jeq" { return OP_JEQ; } +"jneq" { return OP_JNEQ; } +"jne" { return OP_JNEQ; } +"jlt" { return OP_JLT; } +"jle" { return OP_JLE; } +"jgt" { return OP_JGT; } +"jge" { return OP_JGE; } +"jset" { return OP_JSET; } +"add" { return OP_ADD; } +"sub" { return OP_SUB; } +"mul" { return OP_MUL; } +"div" { return OP_DIV; } +"mod" { return OP_MOD; } +"neg" { return OP_NEG; } +"and" { return OP_AND; } +"xor" { return OP_XOR; } +"or" { return OP_OR; } +"lsh" { return OP_LSH; } +"rsh" { return OP_RSH; } +"ret" { return OP_RET; } +"tax" { return OP_TAX; } +"txa" { return OP_TXA; } + +"#"?("len") { return K_PKT_LEN; } +"#"?("proto") { return K_PROTO; } +"#"?("type") { return K_TYPE; } +"#"?("poff") { return K_POFF; } +"#"?("ifidx") { return K_IFIDX; } +"#"?("nla") { return K_NLATTR; } +"#"?("nlan") { return K_NLATTR_NEST; } +"#"?("mark") { return K_MARK; } +"#"?("queue") { return K_QUEUE; } +"#"?("hatype") { return K_HATYPE; } +"#"?("rxhash") { return K_RXHASH; } +"#"?("cpu") { return K_CPU; } +"#"?("vlan_tci") { return K_VLANT; } +"#"?("vlan_pr") { return K_VLANP; } + +":" { return ':'; } +"," { return ','; } +"#" { return '#'; } +"%" { return '%'; } +"[" { return '['; } +"]" { return ']'; } +"(" { return '('; } +")" { return ')'; } +"x" { return 'x'; } +"a" { return 'a'; } +"+" { return '+'; } +"M" { return 'M'; } +"*" { return '*'; } +"&" { return '&'; } + +([0][x][a-fA-F0-9]+) { + yylval.number = strtoul(yytext, NULL, 16); + return number; + } +([0][b][0-1]+) { + yylval.number = strtol(yytext + 2, NULL, 2); + return number; + } +(([0])|([-+]?[1-9][0-9]*)) { + yylval.number = strtol(yytext, NULL, 10); + return number; + } +([0][0-9]+) { + yylval.number = strtol(yytext + 1, NULL, 8); + return number; + } +[a-zA-Z_][a-zA-Z0-9_]+ { + yylval.label = strdup(yytext); + return label; + } + +"/*"([^\*]|\*[^/])*"*/" { /* NOP */ } +";"[^\n]* { /* NOP */ } +^#.* { /* NOP */ } +[ \t]+ { /* NOP */ } +[ \n]+ { /* NOP */ } + +. { + printf("unknown character \'%s\'", yytext); + yyerror("lex unknown character"); + } + +%% diff --git a/tools/net/bpf_exp.y b/tools/net/bpf_exp.y new file mode 100644 index 000000000000..d15efc989ef5 --- /dev/null +++ b/tools/net/bpf_exp.y @@ -0,0 +1,762 @@ +/* + * BPF asm code parser + * + * This program is free software; you can distribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * Syntax kept close to: + * + * Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new + * architecture for user-level packet capture. In Proceedings of the + * USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 + * Conference Proceedings (USENIX'93). USENIX Association, Berkeley, + * CA, USA, 2-2. + * + * Copyright 2013 Daniel Borkmann + * Licensed under the GNU General Public License, version 2.0 (GPLv2) + */ + +%{ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bpf_exp.yacc.h" + +enum jmp_type { JTL, JFL, JKL }; + +extern FILE *yyin; +extern int yylex(void); +extern void yyerror(const char *str); + +extern void bpf_asm_compile(FILE *fp, bool cstyle); +static void bpf_set_curr_instr(uint16_t op, uint8_t jt, uint8_t jf, uint32_t k); +static void bpf_set_curr_label(char *label); +static void bpf_set_jmp_label(char *label, enum jmp_type type); + +%} + +%union { + char *label; + uint32_t number; +} + +%token OP_LDB OP_LDH OP_LD OP_LDX OP_ST OP_STX OP_JMP OP_JEQ OP_JGT OP_JGE +%token OP_JSET OP_ADD OP_SUB OP_MUL OP_DIV OP_AND OP_OR OP_XOR OP_LSH OP_RSH +%token OP_RET OP_TAX OP_TXA OP_LDXB OP_MOD OP_NEG OP_JNEQ OP_JLT OP_JLE OP_LDI +%token OP_LDXI + +%token K_PKT_LEN K_PROTO K_TYPE K_NLATTR K_NLATTR_NEST K_MARK K_QUEUE K_HATYPE +%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF + +%token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%' + +%token number label + +%type

.*)", msg); + f = sm.group("f") + n = sm.group("n") + p = sm.group("p") + if(f and n and p): + data.newAction(phase, f, int(n), p, ktime, -1) + # device init return + elif(re.match(r"call (?P.*)\+ returned .* after (?P.*) usecs", msg)): + sm = re.match(r"call (?P.*)\+ returned .* after (?P.*) usecs(?P.*)", msg); + f = sm.group("f") + t = sm.group("t") + list = data.dmesg[phase]['list'] + if(f in list): + dev = list[f] + dev['length'] = int(t) + dev['end'] = ktime + data.vprint("%15s [%f - %f] %s(%d) %s" % + (phase, dev['start'], dev['end'], f, dev['pid'], dev['par'])) + + # -- phase specific actions -- + if(phase == "suspend_general"): + if(re.match(r"PM: Preparing system for mem sleep.*", msg)): + data.newAction(phase, "filesystem-sync", -1, "", action_start, ktime) + elif(re.match(r"Freezing user space processes .*", msg)): + action_start = ktime + elif(re.match(r"Freezing remaining freezable tasks.*", msg)): + data.newAction(phase, "freeze-user-processes", -1, "", action_start, ktime) + action_start = ktime + elif(re.match(r"PM: Entering (?P[a-z,A-Z]*) sleep.*", msg)): + data.newAction(phase, "freeze-tasks", -1, "", action_start, ktime) + elif(phase == "suspend_cpu"): + m = re.match(r"smpboot: CPU (?P[0-9]*) is now offline", msg) + if(m): + cpu = "CPU"+m.group("cpu") + data.newAction(phase, cpu, -1, "", action_start, ktime) + action_start = ktime + elif(re.match(r"ACPI: Preparing to enter system sleep state.*", msg)): + action_start = ktime + elif(re.match(r"Disabling non-boot CPUs .*", msg)): + data.newAction(phase, "ACPI", -1, "", action_start, ktime) + action_start = ktime + elif(phase == "resume_cpu"): + m = re.match(r"CPU(?P[0-9]*) is up", msg) + if(m): + cpu = "CPU"+m.group("cpu") + data.newAction(phase, cpu, -1, "", action_start, ktime) + action_start = ktime + elif(re.match(r"Enabling non-boot CPUs .*", msg)): + action_start = ktime + + # fill in any missing phases + lp = "suspend_general" + for p in data.phases: + if(p == "suspend_general"): + continue + if(data.dmesg[p]['start'] < 0): + data.dmesg[p]['start'] = data.dmesg[lp]['end'] + if(p == "resume_cpu"): + data.tSuspended = data.dmesg[lp]['end'] + if(data.dmesg[p]['end'] < 0): + data.dmesg[p]['end'] = data.dmesg[p]['start'] + lp = p + + data.fixupInitcallsThatDidntReturn() + return True + +# Function: setTimelineRows +# Description: +# Organize the device or thread lists into the smallest +# number of rows possible, with no entry overlapping +# Arguments: +# list: the list to sort (dmesg or ftrace) +# sortedkeys: sorted key list to use +def setTimelineRows(list, sortedkeys): + global data + + # clear all rows and set them to undefined + remaining = len(list) + rowdata = dict() + row = 0 + for item in list: + list[item]['row'] = -1 + + # try to pack each row with as many ranges as possible + while(remaining > 0): + if(row not in rowdata): + rowdata[row] = [] + for item in sortedkeys: + if(list[item]['row'] < 0): + s = list[item]['start'] + e = list[item]['end'] + valid = True + for ritem in rowdata[row]: + rs = ritem['start'] + re = ritem['end'] + if(not (((s <= rs) and (e <= rs)) or ((s >= re) and (e >= re)))): + valid = False + break + if(valid): + rowdata[row].append(list[item]) + list[item]['row'] = row + remaining -= 1 + row += 1 + return row + +# Function: createTimeScale +# Description: +# Create timescale lines for the dmesg and ftrace timelines +# Arguments: +# t0: start time (suspend begin) +# tMax: end time (resume end) +# tSuspend: time when suspend occurs +def createTimeScale(t0, tMax, tSuspended): + global data + timescale = "