
Changes in 5.10.209 f2fs: explicitly null-terminate the xattr list pinctrl: lochnagar: Don't build on MIPS ALSA: hda - Fix speaker and headset mic pin config for CHUWI CoreBook XPro mptcp: fix uninit-value in mptcp_incoming_options debugfs: fix automount d_fsdata usage drm/amdgpu: Fix cat debugfs amdgpu_regs_didt causes kernel null pointer nvme-core: check for too small lba shift ASoC: wm8974: Correct boost mixer inputs ASoC: Intel: Skylake: Fix mem leak in few functions ASoC: nau8822: Fix incorrect type in assignment and cast to restricted __be16 ASoC: Intel: Skylake: mem leak in skl register function ASoC: cs43130: Fix the position of const qualifier ASoC: cs43130: Fix incorrect frame delay configuration ASoC: rt5650: add mutex to avoid the jack detection failure nouveau/tu102: flush all pdbs on vmm flush net/tg3: fix race condition in tg3_reset_task() ASoC: da7219: Support low DC impedance headset nvme: introduce helper function to get ctrl state drm/exynos: fix a potential error pointer dereference drm/exynos: fix a wrong error checking clk: rockchip: rk3128: Fix HCLK_OTG gate register jbd2: correct the printing of write_flags in jbd2_write_superblock() drm/crtc: Fix uninit-value bug in drm_mode_setcrtc neighbour: Don't let neigh_forced_gc() disable preemption for long jbd2: fix soft lockup in journal_finish_inode_data_buffers() tracing: Have large events show up as '[LINE TOO BIG]' instead of nothing tracing: Add size check when printing trace_marker output ring-buffer: Do not record in NMI if the arch does not support cmpxchg in NMI reset: hisilicon: hi6220: fix Wvoid-pointer-to-enum-cast warning Input: atkbd - skip ATKBD_CMD_GETID in translated mode Input: i8042 - add nomux quirk for Acer P459-G2-M s390/scm: fix virtual vs physical address confusion ARC: fix spare error Input: xpad - add Razer Wolverine V2 support i2c: rk3x: fix potential spinlock recursion on poll ida: Fix crash in ida_free when the bitmap is empty net: qrtr: ns: Return 0 if server port is not present ARM: sun9i: smp: fix return code check of of_property_match_string drm/crtc: fix uninitialized variable use ACPI: resource: Add another DMI match for the TongFang GMxXGxx binder: use EPOLLERR from eventpoll.h binder: fix trivial typo of binder_free_buf_locked() binder: fix comment on binder_alloc_new_buf() return value uio: Fix use-after-free in uio_open parport: parport_serial: Add Brainboxes BAR details parport: parport_serial: Add Brainboxes device IDs and geometry PCI: Add ACS quirk for more Zhaoxin Root Ports coresight: etm4x: Fix width of CCITMIN field x86/lib: Fix overflow when counting digits EDAC/thunderx: Fix possible out-of-bounds string access powerpc: add crtsavres.o to always-y instead of extra-y powerpc: Remove in_kernel_text() powerpc/44x: select I2C for CURRITUCK powerpc/pseries/memhotplug: Quieten some DLPAR operations powerpc/pseries/memhp: Fix access beyond end of drmem array selftests/powerpc: Fix error handling in FPU/VMX preemption tests powerpc/powernv: Add a null pointer check to scom_debug_init_one() powerpc/powernv: Add a null pointer check in opal_event_init() powerpc/powernv: Add a null pointer check in opal_powercap_init() powerpc/imc-pmu: Add a null pointer check in update_events_in_group() spi: spi-zynqmp-gqspi: fix driver kconfig dependencies mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response ACPI: video: check for error while searching for backlight device parent ACPI: LPIT: Avoid u32 multiplication overflow of: property: define of_property_read_u{8,16,32,64}_array() unconditionally of: Add of_property_present() helper cpufreq: Use of_property_present() for testing DT property presence cpufreq: scmi: process the result of devm_of_clk_add_hw_provider() net: netlabel: Fix kerneldoc warnings netlabel: remove unused parameter in netlbl_netlink_auditinfo() calipso: fix memory leak in netlbl_calipso_add_pass() efivarfs: force RO when remounting if SetVariable is not supported spi: sh-msiof: Enforce fixed DTDL for R-Car H3 ACPI: extlog: Clear Extended Error Log status when RAS_CEC handled the error mtd: Fix gluebi NULL pointer dereference caused by ftl notifier selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket virtio_crypto: Introduce VIRTIO_CRYPTO_NOSPC virtio-crypto: introduce akcipher service virtio-crypto: implement RSA algorithm virtio-crypto: change code style virtio-crypto: use private buffer for control request virtio-crypto: wait ctrl queue instead of busy polling crypto: virtio - Handle dataq logic with tasklet crypto: sa2ul - Return crypto_aead_setkey to transfer the error crypto: ccp - fix memleak in ccp_init_dm_workarea crypto: af_alg - Disallow multiple in-flight AIO requests crypto: sahara - remove FLAGS_NEW_KEY logic crypto: sahara - fix cbc selftest failure crypto: sahara - fix ahash selftest failure crypto: sahara - fix processing requests with cryptlen < sg->length crypto: sahara - fix error handling in sahara_hw_descriptor_create() pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() fs: indicate request originates from old mount API Revert "gfs2: Don't reject a supposedly full bitmap if we have blocks reserved" gfs2: Also reflect single-block allocations in rgd->rd_extfail_pt gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump crypto: virtio - Wait for tasklet to complete on device remove crypto: sahara - avoid skcipher fallback code duplication crypto: sahara - handle zero-length aes requests crypto: sahara - fix ahash reqsize crypto: sahara - fix wait_for_completion_timeout() error handling crypto: sahara - improve error handling in sahara_sha_process() crypto: sahara - fix processing hash requests with req->nbytes < sg->length crypto: sahara - do not resize req->src when doing hash operations crypto: scomp - fix req->dst buffer overflow blocklayoutdriver: Fix reference leak of pnfs_device_node NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT wifi: rtw88: fix RX filter in FIF_ALLMULTI flag bpf, lpm: Fix check prefixlen before walking trie bpf: Add crosstask check to __bpf_get_stack wifi: ath11k: Defer on rproc_get failure wifi: libertas: stop selecting wext ARM: dts: qcom: apq8064: correct XOADC register address ncsi: internal.h: Fix a spello net/ncsi: Fix netlink major/minor version numbers firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() firmware: meson_sm: populate platform devices from sm device tree data wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior arm64: dts: ti: k3-am65-main: Fix DSS irq trigger type bpf: fix check for attempt to corrupt spilled pointer scsi: fnic: Return error if vmalloc() failed arm64: dts: qcom: qrb5165-rb5: correct LED panic indicator arm64: dts: qcom: sdm845-db845c: correct LED panic indicator bpf: Fix verification of indirect var-off stack access scsi: hisi_sas: Replace with standard error code return value selftests/net: fix grep checking for fib_nexthop_multiprefix virtio/vsock: fix logic which reduces credit update messages dma-mapping: Add dma_release_coherent_memory to DMA API dma-mapping: clear dev->dma_mem to NULL after freeing it wifi: rtlwifi: add calculate_bit_shift() wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() wifi: rtlwifi: rtl8192c: using calculate_bit_shift() wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() rtlwifi: rtl8192de: make arrays static const, makes object smaller wifi: rtlwifi: rtl8192de: using calculate_bit_shift() wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() wifi: rtlwifi: rtl8192se: using calculate_bit_shift() netfilter: nf_tables: mark newset as dead on transaction abort Bluetooth: Fix bogus check for re-auth no supported with non-ssp Bluetooth: btmtkuart: fix recv_buf() return value ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() ARM: davinci: always select CONFIG_CPU_ARM926T RDMA/usnic: Silence uninitialized symbol smatch warnings drm/panel-elida-kd35t133: hold panel in reset for unprepare rcu: Create an unrcu_pointer() to remove __rcu from a pointer drm/nouveau/fence:: fix warning directly dereferencing a rcu pointer drm/bridge: tpd12s015: Drop buggy __exit annotation for remove function media: pvrusb2: fix use after free on context disconnection drm/bridge: Fix typo in post_disable() description f2fs: fix to avoid dirent corruption drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() drm/radeon: check return value of radeon_ring_lock() ASoC: cs35l33: Fix GPIO name and drop legacy include ASoC: cs35l34: Fix GPIO name and drop legacy include drm/msm/mdp4: flush vblank event on disable drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks drm/drv: propagate errors from drm_modeset_register_all() drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() drm/radeon/dpm: fix a memleak in sumo_parse_power_table drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table drm/bridge: tc358767: Fix return value on error case media: cx231xx: fix a memleak in cx231xx_init_isoc clk: qcom: gpucc-sm8150: Update the gpu_cc_pll1 config media: rkisp1: Disable runtime PM in probe error path f2fs: fix to check compress file in f2fs_move_file_range() f2fs: fix to update iostat correctly in f2fs_filemap_fault() media: dvbdev: drop refcount on error path in dvb_device_open() media: dvb-frontends: m88ds3103: Fix a memory leak in an error handling path of m88ds3103_probe() drm/amdgpu/debugfs: fix error code when smc register accessors are NULL drm/amd/pm: fix a double-free in si_dpm_init drivers/amd/pm: fix a use-after-free in kv_parse_power_table gpu/drm/radeon: fix two memleaks in radeon_vm_init dt-bindings: clock: Update the videocc resets for sm8150 clk: qcom: videocc-sm8150: Update the videocc resets clk: qcom: videocc-sm8150: Add missing PLL config property drivers: clk: zynqmp: calculate closest mux rate clk: zynqmp: make bestdiv unsigned clk: zynqmp: Add a check for NULL pointer drivers: clk: zynqmp: update divider round rate logic watchdog: set cdev owner before adding watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling watchdog: rti_wdt: Drop runtime pm reference count when watchdog is unused clk: si5341: fix an error code problem in si5341_output_clk_set_rate clk: fixed-rate: add devm_clk_hw_register_fixed_rate clk: fixed-rate: fix clk_hw_register_fixed_rate_with_accuracy_parent_hw pwm: stm32: Use regmap_clear_bits and regmap_set_bits where applicable pwm: stm32: Use hweight32 in stm32_pwm_detect_channels pwm: stm32: Fix enable count for clk in .probe() mmc: sdhci_am654: Fix TI SoC dependencies mmc: sdhci_omap: Fix TI SoC dependencies IB/iser: Prevent invalidating wrong MR of: Fix double free in of_parse_phandle_with_args_map of: unittest: Fix of_count_phandle_with_args() expected value message keys, dns: Fix size check of V1 server-list header binder: fix async space check for 0-sized buffers binder: fix unused alloc->free_async_space binder: fix use-after-free in shinker's callback Input: atkbd - use ab83 as id when skipping the getid command dma-mapping: Fix build error unused-value virtio-crypto: fix memory-leak virtio-crypto: fix memory leak in virtio_crypto_alg_skcipher_close_session() Revert "ASoC: atmel: Remove system clock tree configuration for at91sam9g20ek" kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list net: ethernet: mtk_eth_soc: remove duplicate if statements xen-netback: don't produce zero-size SKB frags binder: fix race between mmput() and do_exit() tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart Revert "usb: dwc3: Soft reset phy on probe for host" Revert "usb: dwc3: don't reset device side if dwc3 was configured as host-only" usb: chipidea: wait controller resume finished for wakeup irq Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" usb: typec: class: fix typec_altmode_put_partner to put plugs usb: mon: Fix atomicity violation in mon_bin_vma_fault serial: imx: Ensure that imx_uart_rs485_config() is called with enabled clock ALSA: oxygen: Fix right channel of capture volume mixer ALSA: hda/relatek: Enable Mute LED on HP Laptop 15s-fq2xxx fbdev: flush deferred work in fb_deferred_io_fsync() pwm: jz4740: Don't use dev_err_probe() in .request() io_uring/rw: ensure io->bytes_done is always initialized rootfs: Fix support for rootfstype= when root= is given Bluetooth: Fix atomicity violation in {min,max}_key_size_set iommu/arm-smmu-qcom: Add missing GMU entry to match table wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors wifi: mwifiex: configure BSSID consistently when starting AP x86/kvm: Do not try to disable kvmclock if it was not enabled KVM: arm64: vgic-v4: Restore pending state on host userspace write KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache iio: adc: ad7091r: Pass iio_dev to event handler HID: wacom: Correct behavior when processing some confidence == false touches mfd: syscon: Fix null pointer dereference in of_syscon_register() leds: aw2013: Select missing dependency REGMAP_I2C mips: dmi: Fix early remap on MIPS32 mips: Fix incorrect max_low_pfn adjustment MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() power: supply: cw2015: correct time_to_empty units in sysfs serial: 8250: omap: Don't skip resource freeing if pm_runtime_resume_and_get() failed libapi: Add missing linux/types.h header to get the __u64 type on io.h acpi: property: Let args be NULL in __acpi_node_get_property_reference software node: Let args be NULL in software_node_get_reference_args serial: imx: fix tx statemachine deadlock iio: adc: ad9467: Benefit from devm_clk_get_enabled() to simplify iio: adc: ad9467: fix reset gpio handling iio: adc: ad9467: don't ignore error codes iio: adc: ad9467: fix scale setting perf genelf: Set ELF program header addresses properly tty: change tty_write_lock()'s ndelay parameter to bool tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK tty: don't check for signal_pending() in send_break() tty: use 'if' in send_break() instead of 'goto' usb: cdc-acm: return correct error code on unsupported break nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length nvmet-tcp: fix a crash in nvmet_req_complete() perf env: Avoid recursively taking env->bpf_progs.lock apparmor: avoid crash when parsed profile name is empty serial: imx: Correct clock error message in function probe() nvmet-tcp: Fix the H2C expected PDU len calculation PCI: keystone: Fix race condition when initializing PHYs s390/pci: fix max size calculation in zpci_memcpy_toio() net: qualcomm: rmnet: fix global oob in rmnet_policy net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames net: phy: micrel: populate .soft_reset for KSZ9131 net: ravb: Fix dma_addr_t truncation in error case net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe netfilter: nf_tables: do not allow mismatch field size and set key length netfilter: nf_tables: skip dead set elements in netlink dump netfilter: nf_tables: reject NFT_SET_CONCAT with not field length description ipvs: avoid stat macros calls from preemptible context kdb: Fix a potential buffer overflow in kdb_local() ethtool: netlink: Add missing ethnl_ops_begin/complete mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure mlxsw: spectrum: Use 'bitmap_zalloc()' when applicable mlxsw: spectrum_acl_tcam: Add missing mutex_destroy() mlxsw: spectrum_acl_tcam: Make fini symmetric to init mlxsw: spectrum_acl_tcam: Reorder functions to avoid forward declarations mlxsw: spectrum_acl_tcam: Fix stack corruption selftests: mlxsw: qos_pfc: Convert to iproute2 dcb selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes i2c: s3c24xx: fix read transfers in polling mode i2c: s3c24xx: fix transferring more than one message in polling mode arm64: dts: armada-3720-turris-mox: set irq type for RTC Linux 5.10.209 Change-Id: I86438e299a811ccb08c5a27b2259c33cd482ff00 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
340 lines
7.5 KiB
C
340 lines
7.5 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Amlogic Secure Monitor driver
|
|
*
|
|
* Copyright (C) 2016 Endless Mobile, Inc.
|
|
* Author: Carlo Caione <carlo@endlessm.com>
|
|
*/
|
|
|
|
#define pr_fmt(fmt) "meson-sm: " fmt
|
|
|
|
#include <linux/arm-smccc.h>
|
|
#include <linux/bug.h>
|
|
#include <linux/io.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/printk.h>
|
|
#include <linux/types.h>
|
|
#include <linux/sizes.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/firmware/meson/meson_sm.h>
|
|
|
|
struct meson_sm_cmd {
|
|
unsigned int index;
|
|
u32 smc_id;
|
|
};
|
|
#define CMD(d, s) { .index = (d), .smc_id = (s), }
|
|
|
|
struct meson_sm_chip {
|
|
unsigned int shmem_size;
|
|
u32 cmd_shmem_in_base;
|
|
u32 cmd_shmem_out_base;
|
|
struct meson_sm_cmd cmd[];
|
|
};
|
|
|
|
static const struct meson_sm_chip gxbb_chip = {
|
|
.shmem_size = SZ_4K,
|
|
.cmd_shmem_in_base = 0x82000020,
|
|
.cmd_shmem_out_base = 0x82000021,
|
|
.cmd = {
|
|
CMD(SM_EFUSE_READ, 0x82000030),
|
|
CMD(SM_EFUSE_WRITE, 0x82000031),
|
|
CMD(SM_EFUSE_USER_MAX, 0x82000033),
|
|
CMD(SM_GET_CHIP_ID, 0x82000044),
|
|
CMD(SM_A1_PWRC_SET, 0x82000093),
|
|
CMD(SM_A1_PWRC_GET, 0x82000095),
|
|
{ /* sentinel */ },
|
|
},
|
|
};
|
|
|
|
struct meson_sm_firmware {
|
|
const struct meson_sm_chip *chip;
|
|
void __iomem *sm_shmem_in_base;
|
|
void __iomem *sm_shmem_out_base;
|
|
};
|
|
|
|
static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
|
|
unsigned int cmd_index)
|
|
{
|
|
const struct meson_sm_cmd *cmd = chip->cmd;
|
|
|
|
while (cmd->smc_id && cmd->index != cmd_index)
|
|
cmd++;
|
|
|
|
return cmd->smc_id;
|
|
}
|
|
|
|
static u32 __meson_sm_call(u32 cmd, u32 arg0, u32 arg1, u32 arg2,
|
|
u32 arg3, u32 arg4)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(cmd, arg0, arg1, arg2, arg3, arg4, 0, 0, &res);
|
|
return res.a0;
|
|
}
|
|
|
|
static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
|
|
{
|
|
u32 sm_phy_base;
|
|
|
|
sm_phy_base = __meson_sm_call(cmd_shmem, 0, 0, 0, 0, 0);
|
|
if (!sm_phy_base)
|
|
return 0;
|
|
|
|
return ioremap_cache(sm_phy_base, size);
|
|
}
|
|
|
|
/**
|
|
* meson_sm_call - generic SMC32 call to the secure-monitor
|
|
*
|
|
* @fw: Pointer to secure-monitor firmware
|
|
* @cmd_index: Index of the SMC32 function ID
|
|
* @ret: Returned value
|
|
* @arg0: SMC32 Argument 0
|
|
* @arg1: SMC32 Argument 1
|
|
* @arg2: SMC32 Argument 2
|
|
* @arg3: SMC32 Argument 3
|
|
* @arg4: SMC32 Argument 4
|
|
*
|
|
* Return: 0 on success, a negative value on error
|
|
*/
|
|
int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
|
|
u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
|
{
|
|
u32 cmd, lret;
|
|
|
|
if (!fw->chip)
|
|
return -ENOENT;
|
|
|
|
cmd = meson_sm_get_cmd(fw->chip, cmd_index);
|
|
if (!cmd)
|
|
return -EINVAL;
|
|
|
|
lret = __meson_sm_call(cmd, arg0, arg1, arg2, arg3, arg4);
|
|
|
|
if (ret)
|
|
*ret = lret;
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(meson_sm_call);
|
|
|
|
/**
|
|
* meson_sm_call_read - retrieve data from secure-monitor
|
|
*
|
|
* @fw: Pointer to secure-monitor firmware
|
|
* @buffer: Buffer to store the retrieved data
|
|
* @bsize: Size of the buffer
|
|
* @cmd_index: Index of the SMC32 function ID
|
|
* @arg0: SMC32 Argument 0
|
|
* @arg1: SMC32 Argument 1
|
|
* @arg2: SMC32 Argument 2
|
|
* @arg3: SMC32 Argument 3
|
|
* @arg4: SMC32 Argument 4
|
|
*
|
|
* Return: size of read data on success, a negative value on error
|
|
* When 0 is returned there is no guarantee about the amount of
|
|
* data read and bsize bytes are copied in buffer.
|
|
*/
|
|
int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
|
|
unsigned int bsize, unsigned int cmd_index, u32 arg0,
|
|
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
|
{
|
|
u32 size;
|
|
int ret;
|
|
|
|
if (!fw->chip)
|
|
return -ENOENT;
|
|
|
|
if (!fw->chip->cmd_shmem_out_base)
|
|
return -EINVAL;
|
|
|
|
if (bsize > fw->chip->shmem_size)
|
|
return -EINVAL;
|
|
|
|
if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
|
|
return -EINVAL;
|
|
|
|
if (size > bsize)
|
|
return -EINVAL;
|
|
|
|
ret = size;
|
|
|
|
if (!size)
|
|
size = bsize;
|
|
|
|
if (buffer)
|
|
memcpy(buffer, fw->sm_shmem_out_base, size);
|
|
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(meson_sm_call_read);
|
|
|
|
/**
|
|
* meson_sm_call_write - send data to secure-monitor
|
|
*
|
|
* @fw: Pointer to secure-monitor firmware
|
|
* @buffer: Buffer containing data to send
|
|
* @size: Size of the data to send
|
|
* @cmd_index: Index of the SMC32 function ID
|
|
* @arg0: SMC32 Argument 0
|
|
* @arg1: SMC32 Argument 1
|
|
* @arg2: SMC32 Argument 2
|
|
* @arg3: SMC32 Argument 3
|
|
* @arg4: SMC32 Argument 4
|
|
*
|
|
* Return: size of sent data on success, a negative value on error
|
|
*/
|
|
int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
|
|
unsigned int size, unsigned int cmd_index, u32 arg0,
|
|
u32 arg1, u32 arg2, u32 arg3, u32 arg4)
|
|
{
|
|
u32 written;
|
|
|
|
if (!fw->chip)
|
|
return -ENOENT;
|
|
|
|
if (size > fw->chip->shmem_size)
|
|
return -EINVAL;
|
|
|
|
if (!fw->chip->cmd_shmem_in_base)
|
|
return -EINVAL;
|
|
|
|
memcpy(fw->sm_shmem_in_base, buffer, size);
|
|
|
|
if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
|
|
return -EINVAL;
|
|
|
|
if (!written)
|
|
return -EINVAL;
|
|
|
|
return written;
|
|
}
|
|
EXPORT_SYMBOL(meson_sm_call_write);
|
|
|
|
/**
|
|
* meson_sm_get - get pointer to meson_sm_firmware structure.
|
|
*
|
|
* @sm_node: Pointer to the secure-monitor Device Tree node.
|
|
*
|
|
* Return: NULL is the secure-monitor device is not ready.
|
|
*/
|
|
struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
|
|
{
|
|
struct platform_device *pdev = of_find_device_by_node(sm_node);
|
|
|
|
if (!pdev)
|
|
return NULL;
|
|
|
|
return platform_get_drvdata(pdev);
|
|
}
|
|
EXPORT_SYMBOL_GPL(meson_sm_get);
|
|
|
|
#define SM_CHIP_ID_LENGTH 119
|
|
#define SM_CHIP_ID_OFFSET 4
|
|
#define SM_CHIP_ID_SIZE 12
|
|
|
|
static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
struct platform_device *pdev = to_platform_device(dev);
|
|
struct meson_sm_firmware *fw;
|
|
uint8_t *id_buf;
|
|
int ret;
|
|
|
|
fw = platform_get_drvdata(pdev);
|
|
|
|
id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
|
|
if (!id_buf)
|
|
return -ENOMEM;
|
|
|
|
ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
|
|
0, 0, 0, 0, 0);
|
|
if (ret < 0) {
|
|
kfree(id_buf);
|
|
return ret;
|
|
}
|
|
|
|
ret = sprintf(buf, "%12phN\n", &id_buf[SM_CHIP_ID_OFFSET]);
|
|
|
|
kfree(id_buf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static DEVICE_ATTR_RO(serial);
|
|
|
|
static struct attribute *meson_sm_sysfs_attributes[] = {
|
|
&dev_attr_serial.attr,
|
|
NULL,
|
|
};
|
|
|
|
static const struct attribute_group meson_sm_sysfs_attr_group = {
|
|
.attrs = meson_sm_sysfs_attributes,
|
|
};
|
|
|
|
static const struct of_device_id meson_sm_ids[] = {
|
|
{ .compatible = "amlogic,meson-gxbb-sm", .data = &gxbb_chip },
|
|
{ /* sentinel */ },
|
|
};
|
|
|
|
static int __init meson_sm_probe(struct platform_device *pdev)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
const struct meson_sm_chip *chip;
|
|
struct meson_sm_firmware *fw;
|
|
|
|
fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
|
|
if (!fw)
|
|
return -ENOMEM;
|
|
|
|
chip = of_match_device(meson_sm_ids, dev)->data;
|
|
if (!chip)
|
|
return -EINVAL;
|
|
|
|
if (chip->cmd_shmem_in_base) {
|
|
fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
|
|
chip->shmem_size);
|
|
if (WARN_ON(!fw->sm_shmem_in_base))
|
|
goto out;
|
|
}
|
|
|
|
if (chip->cmd_shmem_out_base) {
|
|
fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
|
|
chip->shmem_size);
|
|
if (WARN_ON(!fw->sm_shmem_out_base))
|
|
goto out_in_base;
|
|
}
|
|
|
|
fw->chip = chip;
|
|
|
|
platform_set_drvdata(pdev, fw);
|
|
|
|
if (devm_of_platform_populate(dev))
|
|
goto out_in_base;
|
|
|
|
if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
|
|
goto out_in_base;
|
|
|
|
pr_info("secure-monitor enabled\n");
|
|
|
|
return 0;
|
|
|
|
out_in_base:
|
|
iounmap(fw->sm_shmem_in_base);
|
|
out:
|
|
return -EINVAL;
|
|
}
|
|
|
|
static struct platform_driver meson_sm_driver = {
|
|
.driver = {
|
|
.name = "meson-sm",
|
|
.of_match_table = of_match_ptr(meson_sm_ids),
|
|
},
|
|
};
|
|
module_platform_driver_probe(meson_sm_driver, meson_sm_probe);
|
|
MODULE_LICENSE("GPL v2");
|