msm5.15: Import ayn changes from ayn_8550.xz (01/18/2026)

Signed-off-by: AnierinB <anierin@evolution-x.org>
This commit is contained in:
2026-01-19 09:53:56 +00:00
parent 09f888c92a
commit a24c65a6ea
35 changed files with 1952 additions and 42 deletions

View File

@@ -32,7 +32,7 @@ CONFIG_CORESIGHT_TGU=m
CONFIG_CORESIGHT_TPDA=m CONFIG_CORESIGHT_TPDA=m
CONFIG_CORESIGHT_TPDM=m CONFIG_CORESIGHT_TPDM=m
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
CONFIG_DRM_LT9611UXC=m # CONFIG_DRM_LT9611UXC is not set
CONFIG_EDAC_QCOM=m CONFIG_EDAC_QCOM=m
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set # CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
@@ -135,10 +135,16 @@ CONFIG_NL80211_TESTMODE=y
CONFIG_NOP_USB_XCEIV=m CONFIG_NOP_USB_XCEIV=m
CONFIG_NVMEM_SPMI_SDAM=m CONFIG_NVMEM_SPMI_SDAM=m
CONFIG_NVME_CORE=m CONFIG_NVME_CORE=m
CONFIG_ETHERNET=y
CONFIG_NET_VENDOR_QUALCOMM=y
# CONFIG_NVME_HWMON is not set # CONFIG_NVME_HWMON is not set
# CONFIG_NVME_MULTIPATH is not set # CONFIG_NVME_MULTIPATH is not set
# CONFIG_NXP_TJA11XX_PHY is not set # CONFIG_NXP_TJA11XX_PHY is not set
CONFIG_PCI_MSM=m CONFIG_PCI_MSM=m
CONFIG_PAGE_POOL=y
CONFIG_PHYLINK=y
#CONFIG_QPS615=y
#CONFIG_r8168=y
CONFIG_PDR_INDICATION_NOTIF_TIMEOUT=9000 CONFIG_PDR_INDICATION_NOTIF_TIMEOUT=9000
CONFIG_PHY_QCOM_UFS=m CONFIG_PHY_QCOM_UFS=m
CONFIG_PHY_QCOM_UFS_QRBTC_SDM845=m CONFIG_PHY_QCOM_UFS_QRBTC_SDM845=m
@@ -561,3 +567,4 @@ CONFIG_VIRT_DRIVERS=y
# CONFIG_WFX is not set # CONFIG_WFX is not set
# CONFIG_WILC1000_SDIO is not set # CONFIG_WILC1000_SDIO is not set
# CONFIG_WILC1000_SPI is not set # CONFIG_WILC1000_SPI is not set
CONFIG_PWM_PM=m

View File

@@ -35,7 +35,7 @@ CONFIG_CORESIGHT_TGU=m
CONFIG_CORESIGHT_TPDA=m CONFIG_CORESIGHT_TPDA=m
CONFIG_CORESIGHT_TPDM=m CONFIG_CORESIGHT_TPDM=m
CONFIG_CPU_IDLE_GOV_QCOM_LPM=m CONFIG_CPU_IDLE_GOV_QCOM_LPM=m
# CONFIG_DRM_LT9611UXC is not set CONFIG_DRM_LT9611UXC=m
CONFIG_EDAC_QCOM=m CONFIG_EDAC_QCOM=m
# CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set # CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set
CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y

View File

@@ -68,6 +68,7 @@ CONFIG_DRM_TTM=y
# CONFIG_EEPROM_93XX46 is not set # CONFIG_EEPROM_93XX46 is not set
# CONFIG_EEPROM_AT25 is not set # CONFIG_EEPROM_AT25 is not set
# CONFIG_EZX_PCAP is not set # CONFIG_EZX_PCAP is not set
CONFIG_FB=y
CONFIG_FB_CMDLINE=y CONFIG_FB_CMDLINE=y
CONFIG_GENERIC_PINCONF=y CONFIG_GENERIC_PINCONF=y
CONFIG_GH_ARM64_DRV=y CONFIG_GH_ARM64_DRV=y

View File

@@ -6,8 +6,8 @@
################################################################################ ################################################################################
## Variant setup ## Variant setup
MSM_ARCH=kalama MSM_ARCH=kalama
VARIANTS=(consolidate gki) VARIANTS=gki
[ -z "${VARIANT}" ] && VARIANT=consolidate [ -z "${VARIANT}" ] && VARIANT=gki
ABL_SRC=bootable/bootloader/edk2 ABL_SRC=bootable/bootloader/edk2
BOOT_IMAGE_HEADER_VERSION=4 BOOT_IMAGE_HEADER_VERSION=4

View File

@@ -184,6 +184,11 @@ static const struct __extcon_info {
.id = EXTCON_MECHANICAL, .id = EXTCON_MECHANICAL,
.name = "MECHANICAL", .name = "MECHANICAL",
}, },
[EXTCON_DEMO_A] = {
.type = EXTCON_TYPE_MISC,
.id = EXTCON_DEMO_A,
.name = "EXTCON_DEMO_AENG",
},
{ /* sentinel */ } { /* sentinel */ }
}; };

View File

@@ -50,6 +50,7 @@ config I2C_COMPAT
config I2C_CHARDEV config I2C_CHARDEV
tristate "I2C device interface" tristate "I2C device interface"
default y
help help
Say Y here to use i2c-* device files, usually found in the /dev Say Y here to use i2c-* device files, usually found in the /dev
directory on your system. They make it possible to have user-space directory on your system. They make it possible to have user-space

View File

@@ -2425,6 +2425,7 @@ static int geni_i2c_suspend_late(struct device *device)
pm_runtime_set_suspended(device); pm_runtime_set_suspended(device);
pm_runtime_enable(device); pm_runtime_enable(device);
} }
pm_runtime_enable(device);
i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT); i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT);
I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret); I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret);
return 0; return 0;

View File

@@ -1380,6 +1380,12 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
SCALE_HW_CALIB_DEFAULT) SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 9, [ADC5_GEN3_AMUX3_THM] = ADC5_CHAN_TEMP("smb_temp", 9,
SCALE_HW_CALIB_PM7_SMB_TEMP) SCALE_HW_CALIB_PM7_SMB_TEMP)
[ADC5_GEN3_AMUX2_THM] = ADC5_CHAN_VOLT("amux2_volt", 1,
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_AMUX4_THM] = ADC5_CHAN_VOLT("amux4_volt", 0,
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_AMUX5_THM] = ADC5_CHAN_VOLT("amux5_volt", 0,
SCALE_HW_CALIB_DEFAULT)
[ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0, [ADC5_GEN3_CHG_TEMP] = ADC5_CHAN_TEMP("chg_temp", 0,
SCALE_HW_CALIB_PM7_CHG_TEMP) SCALE_HW_CALIB_PM7_CHG_TEMP)
[ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 8, [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP("usb_sns_v_div_16", 8,

View File

@@ -1666,6 +1666,7 @@ static int haptics_wait_brake_complete(struct haptics_chip *chip)
t_lra_us = (chip->config.cl_t_lra_us) ? t_lra_us = (chip->config.cl_t_lra_us) ?
chip->config.cl_t_lra_us : chip->config.t_lra_us; chip->config.cl_t_lra_us : chip->config.t_lra_us;
t_lra_us = 2000;
brake_length_us = get_brake_play_length_us(play->brake, t_lra_us); brake_length_us = get_brake_play_length_us(play->brake, t_lra_us);
@@ -1673,7 +1674,7 @@ static int haptics_wait_brake_complete(struct haptics_chip *chip)
brake_length_us += t_lra_us; brake_length_us += t_lra_us;
delay_us = t_lra_us / 2; delay_us = t_lra_us / 2;
timeout = brake_length_us / delay_us + 1; timeout = brake_length_us / delay_us + 1;
dev_dbg(chip->dev, "wait %d us for brake pattern to complete\n", brake_length_us); dev_warn(chip->dev, "wait %d us for brake pattern to complete timeout=%d delay_us=%d\n", brake_length_us, timeout, delay_us);
/* poll HPWR_DISABLED to guarantee the brake pattern has been played completely */ /* poll HPWR_DISABLED to guarantee the brake pattern has been played completely */
do { do {
@@ -4065,6 +4066,8 @@ static int haptics_create_debugfs(struct haptics_chip *chip)
debugfs_create_u32("fifo_empty_thresh", 0600, hap_dir, debugfs_create_u32("fifo_empty_thresh", 0600, hap_dir,
&chip->config.fifo_empty_thresh); &chip->config.fifo_empty_thresh);
debugfs_create_u32("user_vmax_mv", 0666, hap_dir,
&chip->config.vmax_mv);
chip->debugfs_dir = hap_dir; chip->debugfs_dir = hap_dir;
return 0; return 0;
@@ -4341,7 +4344,7 @@ static int haptics_parse_per_effect_dt(struct haptics_chip *chip,
return rc; return rc;
} }
if (!config->is_erm) //if (!config->is_erm)
effect->auto_res_disable = of_property_read_bool(node, effect->auto_res_disable = of_property_read_bool(node,
"qcom,wf-auto-res-disable"); "qcom,wf-auto-res-disable");
@@ -5591,7 +5594,8 @@ static int haptics_probe(struct platform_device *pdev)
rc = haptics_hw_init(chip); rc = haptics_hw_init(chip);
if (rc < 0) { if (rc < 0) {
dev_err(chip->dev, "Initialize HW failed, rc = %d\n", rc); dev_err(chip->dev, "probe() Initialize HW failed, rc = %d\n", rc);
if(rc != -EBUSY)
return rc; return rc;
} }
@@ -5600,6 +5604,7 @@ static int haptics_probe(struct platform_device *pdev)
if (rc < 0) { if (rc < 0) {
dev_err(chip->dev, "Initialize swr slave regulator failed, rc = %d\n", dev_err(chip->dev, "Initialize swr slave regulator failed, rc = %d\n",
rc); rc);
if(rc != -EBUSY)
return rc; return rc;
} }
} }
@@ -5610,6 +5615,7 @@ static int haptics_probe(struct platform_device *pdev)
if (rc < 0) { if (rc < 0) {
dev_err(chip->dev, "request fifo-empty IRQ failed, rc=%d\n", dev_err(chip->dev, "request fifo-empty IRQ failed, rc=%d\n",
rc); rc);
if(rc != -EBUSY)
return rc; return rc;
} }
@@ -5714,7 +5720,7 @@ static int haptics_ds_resume_config(struct device *dev)
rc = haptics_hw_init(chip); rc = haptics_hw_init(chip);
if (rc < 0) { if (rc < 0) {
dev_err(chip->dev, "Initialize HW failed, rc = %d\n", rc); dev_err(chip->dev, "resume() Initialize HW failed, rc = %d\n", rc);
return rc; return rc;
} }

View File

@@ -285,6 +285,9 @@ config LEDS_QTI_FLASH
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called leds-qti-flash. module will be called leds-qti-flash.
config PWM_PM
tristate "Support for PWM_PM"
config LEDS_QPNP_FLASH_V2 config LEDS_QPNP_FLASH_V2
tristate "Support for QPNP V2 Flash LEDs" tristate "Support for QPNP V2 Flash LEDs"
depends on LEDS_CLASS && MFD_SPMI_PMIC depends on LEDS_CLASS && MFD_SPMI_PMIC

View File

@@ -110,3 +110,4 @@ obj-$(CONFIG_LEDS_TRIGGERS) += trigger/
# LED Blink # LED Blink
obj-y += blink/ obj-y += blink/
obj-$(CONFIG_PWM_PM) += gpio5_pwm.o

550
drivers/leds/gpio5_pwm.c Normal file
View File

@@ -0,0 +1,550 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/hrtimer.h>
#include <mydebug.h>
#define SAMPLING_TIME 100
#define DP_HDMI_UNUSE 2
static int thermal_mode = 0;
int en_backlight = 1;
static int dp_state = 0;
static int hdmi_state = 0;
EXPORT_SYMBOL(en_backlight);
int secondary_en_backlight = 1;
EXPORT_SYMBOL(secondary_en_backlight);
//extern int dp_display_connected;
//extern int default_display_connected;
int dp_display_connected = 0; //redefined
int default_display_connected = 0;
struct gpio5_pwm_data
{
unsigned int state;
unsigned int duty_ns;
unsigned int period_ns;
unsigned int fan_en_gpio;
unsigned int fan_int_gpio;
int fan_irq;
struct pwm_device *pwm_dev;
};
struct class gpio5_pwm_class;
static struct gpio5_pwm_data *data;
static int fan_fg_count,rpm;
//static struct timeval fg_time;
//static unsigned long fg_time_sec_start;
//static unsigned long fg_time_sec_end;
//static unsigned long fg_time_usec_start;
//static unsigned long fg_time_usec_end;
//static unsigned long fg_time_sec;
//static unsigned long fg_time_usec;
static ssize_t state_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", data->state));
}
static ssize_t state_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
if (sysfs_streq(buf, "1"))
{
gpio_direction_output(data->fan_en_gpio, 1);
__gpio_set_value(data->fan_en_gpio,1);
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
printk("[kevin]%s: %d %d\n", __func__, data->duty_ns, data->period_ns);
pwm_enable(data->pwm_dev);
data->state = 1;
//pr_err("kevin fan_en_gpio = 1!\n");
}
else if (sysfs_streq(buf, "0"))
{
pwm_disable(data->pwm_dev);
data->state = 0;
gpio_direction_output(data->fan_en_gpio, 0);
__gpio_set_value(data->fan_en_gpio,0);
//pr_err("kevin fan_en_gpio = 0!\n");
}
return len;
}
static CLASS_ATTR_RW(state);
static ssize_t duty_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", data->duty_ns));
}
static ssize_t duty_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &data->duty_ns);
if (rc < 0)
pr_err("get duty value failed!\n");
//if(data->duty_ns <= data->period_ns){
// data->duty_ns = data->period_ns-data->duty_ns;
//}
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
return len;
}
static CLASS_ATTR_RW(duty);
static ssize_t thermal_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", thermal_mode));
}
static ssize_t thermal_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &thermal_mode);
if (rc < 0)
pr_err("get thermal_mode value failed!\n");
return len;
}
static CLASS_ATTR_RW(thermal);
static ssize_t en_backlight_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", en_backlight));
}
static ssize_t en_backlight_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &en_backlight);
if (rc < 0)
pr_err("get en_backlight value failed!\n");
return len;
}
static CLASS_ATTR_RW(en_backlight);
static ssize_t secondary_en_backlight_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", secondary_en_backlight));
}
static ssize_t secondary_en_backlight_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &secondary_en_backlight);
if (rc < 0)
pr_err("get secondary_en_backlight value failed!\n");
return len;
}
static CLASS_ATTR_RW(secondary_en_backlight);
static ssize_t dp_state_show(struct class *class, struct class_attribute *attr, char *buf)
{
if(dp_display_connected == DP_HDMI_UNUSE)
dp_state = 0;
else
dp_state = dp_display_connected;
return (sprintf(buf, "%u\n", dp_state));
}
static ssize_t dp_state_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
int pre_dp_state = dp_state;
rc = kstrtouint(buf, 0, &dp_state);
if (rc < 0)
pr_err("get dp_state value failed!\n");
if(dp_state != 0 && dp_state != 1){
dp_state = pre_dp_state;
}
dp_display_connected = dp_state;
return len;
}
static CLASS_ATTR_RW(dp_state);
static ssize_t hdmi_state_show(struct class *class, struct class_attribute *attr, char *buf)
{
if(default_display_connected == DP_HDMI_UNUSE)
hdmi_state = 0;
else
hdmi_state = default_display_connected;
return (sprintf(buf, "%u\n", hdmi_state));
}
static ssize_t hdmi_state_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
int pre_hdmi_state = hdmi_state;
rc = kstrtouint(buf, 0, &hdmi_state);
if (rc < 0)
pr_err("get hdmi_state value failed!\n");
if(hdmi_state != 0 && hdmi_state != 1){
hdmi_state = pre_hdmi_state;
}
default_display_connected = hdmi_state;
return len;
}
static CLASS_ATTR_RW(hdmi_state);
static ssize_t period_show(struct class *class, struct class_attribute *attr, char *buf)
{
return (sprintf(buf, "%u\n", data->period_ns));
}
static ssize_t period_store(struct class *class, struct class_attribute *attr, const char *buf, size_t len)
{
int rc;
rc = kstrtouint(buf, 0, &data->period_ns);
if (rc < 0)
pr_err("get period value failed!\n");
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
return len;
}
static CLASS_ATTR_RW(period);
//cat sys/class/gpio5_pwm2/speed
static ssize_t speed_show(struct class *class, struct class_attribute *attr, char *buf)
{
rpm = 0;
fan_fg_count = 0;
enable_irq(data->fan_irq);
mdelay(SAMPLING_TIME);
disable_irq(data->fan_irq);
//printk("fan_fg_count = %d\n",fan_fg_count);
rpm = 60000/(SAMPLING_TIME*2)*fan_fg_count;
return (sprintf(buf, "%d\n", rpm));
}
static CLASS_ATTR_RO(speed);
static irqreturn_t fan_irq_handler(int irq, void *data)
{
fan_fg_count = fan_fg_count+1;
return IRQ_HANDLED;
}
#if 0
static irqreturn_t fan_irq_handler(int irq, void *data)
{
//printk("******* %s ********start \n",__func__);
if (fan_fg_count == 0){
do_gettimeofday(&fg_time);
fg_time_sec_start = fg_time.tv_sec;
fg_time_usec_start = fg_time.tv_usec;
//printk("******* fg start time sec:%ld, usec: %ld\n", fg_time.tv_sec, fg_time.tv_usec);
//disable_irq_nosync(fan_irq);
}
fan_fg_count++;
if (fan_fg_count == 3){
do_gettimeofday(&fg_time);
fg_time_sec_end = fg_time.tv_sec;
fg_time_usec_end = fg_time.tv_usec;
//printk("********** fg end time sec:%ld, usec: %ld\n", fg_time.tv_sec, fg_time.tv_usec);
fg_time_sec = fg_time_sec_end - fg_time_sec_start;
if(fg_time_usec_end > fg_time_usec_start)
fg_time_usec = fg_time_usec_end - fg_time_usec_start;
else{
fg_time_usec = 1000000+fg_time_usec_end - fg_time_usec_start;
fg_time_sec = fg_time_sec - 1;
}
rpm = 1000/((fg_time_sec *1000 + fg_time_usec/1000));//unit: 1sec/rpm
//printk("********** rpm = %d \n",rpm);
printk("count=%d,s_sec:%ld, s_usec: %ld,e_sec:%ld,e_usec:%ld\n",fan_fg_count, fg_time_sec_start, fg_time_usec_start,fg_time_sec_end,fg_time_usec_end);
}
//printk("******* %s ********end \n",__func__);
return IRQ_HANDLED;
}
#endif
/*
static int fan_pwm_suspend(struct device *dev)
{
if (data->state) {
pwm_disable(data->pwm_dev);
// data->state = 0;
gpio_direction_output(data->fan_en_gpio, 0);
__gpio_set_value(data->fan_en_gpio,0);
pr_err("kevin fan_en_gpio = 0!\n");
}
return 0;
}
static int fan_pwm_resume(struct device *dev)
{
if (data->state) {
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
printk("[kevin]%s: %d %d\n", __func__, data->duty_ns, data->period_ns);
pwm_enable(data->pwm_dev);
// data->state = 1;
gpio_direction_output(data->fan_en_gpio, 1);
__gpio_set_value(data->fan_en_gpio,1);
//pr_err("kevin fan_en_gpio = 1!\n");
}
return 0;
}
*/
static int gpio5_pwm_probe(struct platform_device *pdev)
{
int rc = 0;
int ret = 0;
struct device_node *of_node = pdev->dev.of_node;
printk("xxh ------------- %s start!\n",__func__);
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
{
return -ENOMEM;
}
data->pwm_dev = devm_of_pwm_get(&pdev->dev, of_node, NULL);
if (!data->pwm_dev)
{
pr_err("%s: failed to request pwm\n", __func__);
rc = -EINVAL;
goto error;
}
rc = of_property_read_s32(of_node, "gpio5-pwm-duty-ns", &data->duty_ns);
if (rc)
{
pr_warn("%s: duty-ns is not defind\n", __func__);
}
rc = of_property_read_s32(of_node, "gpio5-pwm-period-ns", &data->period_ns);
if (rc)
{
pr_warn("%s: gpio5-pwm-period-ns is not defind\n", __func__);
}
rc = of_property_read_s32(of_node, "gpio5-pwm-state", &data->state);
if (rc)
{
pr_warn("%s: gpio5-pwm-state is not defind\n", __func__);
}
//rc = pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
//if (rc)
//{
// pr_err("%s: failed to change pwm config\n", __func__);
// goto error;
//}
data->fan_en_gpio = of_get_named_gpio(of_node, "qcom,fan-en-gpio", 0);
if (data->fan_en_gpio < 0){
pr_err("%s: get qcom,fan-en-gpio failed\n", __func__);
goto error;
}
if (gpio_is_valid(data->fan_en_gpio)) {
ret = gpio_request(data->fan_en_gpio, "quectel_red_led_en");
if (ret) {
pr_err("%s: Unable to request fan_en_gpio [%d]\n", __func__,data->fan_en_gpio);
goto error;
}
} else {
pr_err("%s: Invalid fan_en_gpio [%d]!\n", __func__,data->fan_en_gpio);
ret = -EINVAL;
goto err_free_red_led_en;
}
data->fan_int_gpio = of_get_named_gpio(of_node, "qcom,fan-fg-gpio", 0);
if (data->fan_int_gpio < 0){
pr_err("%s: get qcom,fan-int-gpio failed\n", __func__);
goto error;
}
if (gpio_request(data->fan_int_gpio, "fan_fg_int_gpio") != 0) {
gpio_free(data->fan_int_gpio);
pr_err("%s: get data->fan_int_gpio failed\n", __func__);
goto error;
}
gpio_direction_input(data->fan_int_gpio);
data->fan_irq = gpio_to_irq(data->fan_int_gpio);
rc = request_threaded_irq(data->fan_irq, NULL,
fan_irq_handler,
IRQF_TRIGGER_RISING |IRQF_ONESHOT,
"gpio5-pwm", data);
if (rc)
{
pr_err("%s: request irq err = %d\n",__func__,rc);
gpio_free(data->fan_int_gpio);
goto error;
}
printk("%s: fan_irq= %d\n",__func__,data->fan_irq);
//if (1 == data->state)
//{
// rc = pwm_enable(data->pwm_dev);
// if (rc)
// {
// pr_err("%s: failed to enable pwm\n", __func__);
// goto error;
// }
//}
pwm_config(data->pwm_dev, data->duty_ns, data->period_ns);
pwm_enable(data->pwm_dev);
pwm_disable(data->pwm_dev);
data->state = 0;
gpio_direction_output(data->fan_en_gpio, 0);
__gpio_set_value(data->fan_en_gpio,0);
printk("xxh ------------- %s end!\n",__func__);
return 0;
err_free_red_led_en:
if (gpio_is_valid(data->fan_en_gpio))
gpio_free(data->fan_en_gpio);
error:
kfree(data);
return rc;
}
static int gpio5_pwm_remove(struct platform_device *pdev)
{
if (data->state)
pwm_disable(data->pwm_dev);
kfree(data);
return 0;
}
static void gpio5_pwm_shutdown(struct platform_device *pdev)
{
if (data->state)
pwm_disable(data->pwm_dev);
pr_err("gpio5_pwm_shutdown\n");
}
/*
static struct class_attribute gpio_class_attrs[] =
{
__ATTR(state, 0664, state_show, state_store),
__ATTR(duty, 0664, duty_show, duty_store),
__ATTR(period, 0664, period_show, period_store),
__ATTR(speed, 0664, speed_show, NULL),
__ATTR(thermal_mode, 0664, thermal_show, thermal_store),
__ATTR(en_backlight, 0664, en_backlight_show, en_backlight_store),
__ATTR(hdmi_state, 0664, hdmi_state_show, hdmi_state_store),
__ATTR(dp_state, 0664, dp_state_show, dp_state_store),
__ATTR_NULL,
};
*/
static struct attribute *gpio5_pwm_attrs[] = {
&class_attr_state.attr,
&class_attr_duty.attr,
&class_attr_period.attr,
&class_attr_speed.attr,
&class_attr_thermal.attr,
&class_attr_en_backlight.attr,
&class_attr_secondary_en_backlight.attr,
&class_attr_hdmi_state.attr,
&class_attr_dp_state.attr,
NULL,
};
/*
static struct class gpio5_pwm_class =
{
.name = "gpio5_pwm2",
.class_groups = gpio5_pwm_attrs,
};
*/
ATTRIBUTE_GROUPS(gpio5_pwm);
static const struct of_device_id pwm_match_table[] =
{
{ .compatible = "gpio5-pwm", },
{},
};
/*
#ifdef CONFIG_PM
static const struct dev_pm_ops fan_pwm_dev_pm_ops = {
.suspend = fan_pwm_suspend,
.resume = fan_pwm_resume,
};
#endif
*/
static struct platform_driver gpio5_pwm_driver =
{
.driver = {
.name = "gpio5-pwm",
.of_match_table = pwm_match_table,
.owner = THIS_MODULE,
#ifdef CONFIG_PM
//.pm = &fan_pwm_dev_pm_ops,
#endif
},
.probe = gpio5_pwm_probe,
.remove = gpio5_pwm_remove,
.shutdown = gpio5_pwm_shutdown,
};
static int __init gpio5_pwm_init(void)
{
int rc = 0;
printk("[kevin]%s: %d\n", __func__,__LINE__);
gpio5_pwm_class.name = "gpio5_pwm2";
gpio5_pwm_class.class_groups = gpio5_pwm_groups;
rc = class_register(&gpio5_pwm_class);
if (0 == rc)
{
platform_driver_register(&gpio5_pwm_driver);
printk("[kevin]%s: %d\n", __func__,__LINE__);
}
return rc;
}
static void __exit gpio5_pwm_exit(void)
{
platform_driver_unregister(&gpio5_pwm_driver);
class_unregister(&gpio5_pwm_class);
}
module_init(gpio5_pwm_init);
module_exit(gpio5_pwm_exit);
MODULE_LICENSE("GPL");

View File

@@ -64,4 +64,4 @@ obj-$(CONFIG_OPEN_DICE) += open-dice.o
obj-$(CONFIG_QSEECOM_PROXY) += qseecom_proxy.o obj-$(CONFIG_QSEECOM_PROXY) += qseecom_proxy.o
obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o obj-$(CONFIG_QPNP_MISC) += qpnp-misc.o
obj-$(CONFIG_PROFILER) += profiler.o obj-$(CONFIG_PROFILER) += profiler.o
obj-$(CONFIG_QRC) += qrc/ obj-y += ayn/

6
drivers/misc/ayn/Kconfig Executable file
View File

@@ -0,0 +1,6 @@
# to add sprd vsp configs in the future
config KEY_CHECK
tristate "M0 M1 driver"
config SHELL_ADC
tristate "shell adc driver"

1
drivers/misc/ayn/Makefile Executable file
View File

@@ -0,0 +1 @@
obj-y += gpio.o

437
drivers/misc/ayn/gpio.c Executable file
View File

@@ -0,0 +1,437 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/kobject.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/unistd.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <asm/uaccess.h>
#include <mydebug.h>
#define GPIO_NUM_MAX 4
struct gpio_info{
char name[64];
int pin;
int direction;
int out_def;
};
static struct gpio_info all_gpio_pin[GPIO_NUM_MAX]={
{
.name = "mcu_boot",
.pin = MCU_BOOT,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
{
.name = "mcu_reset",
.pin = MCU_RESET,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
{
.name = "mcu_pwr",
.pin = MCU_PWR,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
{
.name = "mcu_uart_pwr",
.pin = MCU_UART_PWR,
.direction = GPIO_DIR_OUT,
.out_def = GPIO_OUT_LOW,
},
};
static void rs_gpio_request(void)
{
int ret;
int index;
for(index=0; index<GPIO_NUM_MAX; index++){
if (gpio_is_valid(all_gpio_pin[index].pin)) {
ret = gpio_request(all_gpio_pin[index].pin, all_gpio_pin[index].name);
if (ret < 0) {
KERNEL_INFO("Unable to request gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
if(all_gpio_pin[index].direction == GPIO_DIR_IN){
ret = gpio_direction_input(all_gpio_pin[index].pin);
if (ret < 0) {
KERNEL_INFO("Unable to set direction in for gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
} else {
ret = gpio_direction_output(all_gpio_pin[index].pin, all_gpio_pin[index].out_def);
if (ret < 0) {
KERNEL_INFO("Unable to set direction out for gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
}
ret = gpio_export(all_gpio_pin[index].pin, 1); // /sys/class/gpio/gpiox/
if (ret < 0) {
KERNEL_INFO("Unable to export gpio%d ret=%d\n", all_gpio_pin[index].pin, ret);
gpio_free(all_gpio_pin[index].pin);
}
KERNEL_INFO("request gpio%d success ret=%d\n", all_gpio_pin[index].pin, ret);
}
}
}
static void rs_gpio_free(void)
{
int index;
for(index=0; index<GPIO_NUM_MAX; index++){
if (gpio_is_valid(all_gpio_pin[index].pin)) {
gpio_unexport(all_gpio_pin[index].pin);
gpio_free(all_gpio_pin[index].pin);
KERNEL_INFO("free gpio%d success\n", all_gpio_pin[index].pin);
}
}
}
void rs_gpio_set(int pin, int value)
{
int index;
for(index=0; index<GPIO_NUM_MAX; index++){
if(all_gpio_pin[index].pin != pin)
continue;
if (gpio_is_valid(all_gpio_pin[index].pin)) {
gpio_set_value(all_gpio_pin[index].pin, value);
KERNEL_INFO("name:%s %d", all_gpio_pin[index].name, value);
}
break;
}
}
EXPORT_SYMBOL(rs_gpio_set);
int rs_gpio_get(int pin)
{
int index;
int value = -1;
for(index=0; index<GPIO_NUM_MAX; index++){
if(all_gpio_pin[index].pin != pin)
continue;
if (gpio_is_valid(all_gpio_pin[index].pin)) {
value = gpio_get_value(all_gpio_pin[index].pin);
}
break;
}
KERNEL_INFO("name:%s %d", all_gpio_pin[index].name, value);
return value;
}
EXPORT_SYMBOL(rs_gpio_get);
int gpio_index = 0;
// 当用户试图从设备空间读取数据时,调用这个函数
ssize_t rs_gpio_read(struct file *file, char __user *buf, size_t len, loff_t *offset)
{
ssize_t cnt = 0;
char send_msg[64]={0};
if(gpio_index >= GPIO_NUM_MAX){
KERNEL_INFO("ERROR gpio=%d when reading!!\n", gpio_index);
return -EFAULT;
}
sprintf(send_msg, "%u\n", gpio_get_value(all_gpio_pin[gpio_index].pin));;
cnt = copy_to_user(buf, send_msg, sizeof(send_msg));// 将内核空间的数据copy到用户空间
if(cnt){
KERNEL_INFO("ERROR occur when reading!!\n");
return -EFAULT;
}
KERNEL_INFO("name:%s %d", all_gpio_pin[gpio_index].name, gpio_get_value(all_gpio_pin[gpio_index].pin));
return cnt;
}
// 当用户往设备文件写数据时,调用这个函数
// counter 10 intervalgpio 30 intervaladc 30 bufsize 2048 gpiopin 总个数 0 122 124 threshold
ssize_t rs_gpio_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
{
int gpio = 0;
KERNEL_INFO("%s\n", ubuf);
if(!strncmp(ubuf, "SETGPIO ", 8) && count > 8){ // SETGPIO 1 1
gpio = ubuf[8];
if(gpio < GPIO_NUM_MAX){
if (gpio_is_valid(all_gpio_pin[gpio].pin)) {
if(count > 10){
gpio_set_value(all_gpio_pin[gpio].pin, ubuf[10]);
} else {
KERNEL_INFO("error pin=%d", all_gpio_pin[gpio].pin);
}
}
} else {
KERNEL_INFO("error gpio=%d", gpio);
}
}else if(!strncmp(ubuf, "GETGPIO ", 8) && count > 8){ // GETGPIO 1
gpio = ubuf[8];
if(gpio < GPIO_NUM_MAX){
gpio_index = gpio;
}
}
return count;
}
// File opertion 结构体,我们通过这个结构体建立应用程序到内核之间操作的映射
static struct file_operations file_oprts = {
.owner = THIS_MODULE,
.read = rs_gpio_read,
.write = rs_gpio_write,
};
#define DEVICE_NAME "rsgpio" // Device 名称,对应/dev下的目录名称
static struct miscdevice rs_gpio_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &file_oprts
};
/*
static int rs_gpio_suspend(void)
{
bright = 0;
printk("bright %d gpio_get_value(88) = %d \n",bright,gpio_get_value(88));
return 0;
}
static int rs_gpio_resume(void)
{
bright = 1;
printk("bright %d gpio_get_value(88) = %d \n",bright,gpio_get_value(88));
return 0;
}
static struct dev_pm_ops rs_gpio_pm_ops = {
.suspend = rs_gpio_suspend,
.resume = rs_gpio_resume,
};
*/
static void mcu_power_on(void)
{
// Init MCU_Boot = 0 && MCU_Reset = 1'b0
if (gpio_is_valid(MCU_BOOT)) {
gpio_direction_output(MCU_BOOT, GPIO_OUT_LOW);
}
if (gpio_is_valid(MCU_RESET)) {
gpio_direction_output(MCU_RESET, GPIO_OUT_LOW);
}
// Enable MCU 3.3
if (gpio_is_valid(MCU_PWR)) {
gpio_direction_output(MCU_PWR, GPIO_OUT_HIGH);
msleep(20);
}
// Enable OE of AW3911 - Level shifter
if (gpio_is_valid(MCU_UART_PWR)) {
gpio_direction_output(MCU_UART_PWR, GPIO_OUT_HIGH);
msleep(20);
}
if (gpio_is_valid(MCU_RESET)) {
gpio_direction_output(MCU_RESET, GPIO_OUT_HIGH);
}
}
static void mcu_power_off(void)
{
//rs_gpio_set(MCU_PWR, GPIO_OUT_LOW);
if (gpio_is_valid(MCU_PWR)) {
gpio_direction_output(MCU_PWR, GPIO_OUT_LOW);
}
//rs_gpio_set(MCU_UART_PWR, GPIO_OUT_LOW);
if (gpio_is_valid(MCU_UART_PWR)) {
gpio_direction_output(MCU_UART_PWR, GPIO_OUT_LOW);
}
if (gpio_is_valid(MCU_BOOT)) {
gpio_direction_output(MCU_BOOT, GPIO_OUT_LOW);
}
if (gpio_is_valid(MCU_RESET)) {
gpio_direction_output(MCU_RESET, GPIO_OUT_LOW);
}
}
/*
// android_print 表示Android层LOG打印开关
#ifdef CONFIG_ANDROID_LOG_CLOSED
static char android_print = 0; // 0表示不打印user版本的默认不打印
#else
static char android_print = 1; // 1表示打印
#endif
#define LOG_SEEK_OFFSET 8*1024*1024
#define LOG_PATH "/dev/block/sde65"
static int rwdev(char* buf, int len, int flag) {
struct file *log_filp;
mm_segment_t old_fs;
int length=0;
log_filp=filp_open(LOG_PATH,O_RDWR,0);
if(IS_ERR(log_filp)){
KERNEL_ERROR("open %s err:%d !\n",LOG_PATH,PTR_ERR(log_filp));
return -1;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
log_filp->f_op->llseek(log_filp, LOG_SEEK_OFFSET, SEEK_SET);
if(flag==0)
length=vfs_read(log_filp, buf, len, &log_filp->f_pos);
else
length=vfs_write(log_filp, buf, len, &log_filp->f_pos);
set_fs(old_fs);
return length;
}
static int get_log_enable(void) {
char buf[2];
int length = rwdev(buf, 2, 0);
if(length < 2) {
KERNEL_ERROR("get_log_enable %s err!\n",LOG_PATH);
return -1;
}
if(buf[0] == '1') {
if(buf[1] == '1') {
return 1;
} else {
return 0;
}
} else {
return android_print;
}
}
static int write_log_enable(char is_enable) {
char buf[2] = {'1',is_enable};
int length = rwdev(buf, 2, 1);
if(length < 2) {
KERNEL_ERROR("write_log_enable %s err!\n",LOG_PATH);
return -1;
}
return 0;
}
*/
// 添加节点控制
static ssize_t sysfs_set_driver_ctl(struct device *dev, struct device_attribute *attr, const char *ubuf, size_t size)
{
KERNEL_ERROR("cmd_write:%s", ubuf);
if(!strncmp(ubuf, "mcupower ", 9) && size > 9){
if(ubuf[9] == '1'){
// 打开MCU的电
mcu_power_on();
} else {
// 关掉MCU的电
mcu_power_off();
}
} else if(!strncmp(ubuf, "logenable ", 10) && size > 10){
if(ubuf[10] == '1'){
//write_log_enable('1');
} else {
//write_log_enable('0');
}
} else {
KERNEL_ERROR(KERN_ERR "muxcmd error for cmd %s", ubuf);
}
return size;
}
static ssize_t sysfs_get_driver_ctl(struct device *dev, struct device_attribute *attr, char *ubuf)
{
ssize_t size = 0;//sprintf(ubuf, "%d", get_log_enable());
KERNEL_ERROR("cmd_read: size=%d, ubuf=%s", size, ubuf);
return size;
}
static DEVICE_ATTR(driver_ctl, 0644, sysfs_get_driver_ctl, sysfs_set_driver_ctl);
static void rs_gpio_shutdown(struct platform_device *device)
{
KERNEL_INFO("done!");
}
static int rs_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int ret = misc_register(&rs_gpio_misc_device);
if (ret) {
KERNEL_INFO("rs_gpio: Unable to register misc device ret=%d\n", ret);
}
rs_gpio_request();
device_create_file(dev, &dev_attr_driver_ctl);
//mcu_power_on();
KERNEL_INFO("\n");
return ret;
}
static int __exit rs_gpio_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
KERNEL_INFO("\n");
rs_gpio_free();
misc_deregister(&rs_gpio_misc_device);
device_remove_file(dev, &dev_attr_driver_ctl);
return 0;
}
static struct platform_driver rs_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = DEVICE_NAME,
//.pm = &rs_gpio_pm_ops,
},
.shutdown = rs_gpio_shutdown,
.probe = rs_gpio_probe,
.remove = rs_gpio_remove,
};
static struct platform_device rs_gpio_dev = {
.name = DEVICE_NAME,
.id = -1,
};
int __init rs_gpio_init(void)
{
platform_device_register(&rs_gpio_dev);
platform_driver_register(&rs_gpio_driver);
KERNEL_INFO("driver init success!!\n");
return 0;
}
void __exit rs_gpio_exit(void)
{
platform_device_unregister(&rs_gpio_dev);
platform_driver_unregister(&rs_gpio_driver);
KERNEL_INFO("driver %s removed\n", DEVICE_NAME);
}
module_init(rs_gpio_init);
module_exit(rs_gpio_exit);
MODULE_AUTHOR("kevin");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("GPIO driver");

View File

@@ -23,7 +23,7 @@
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mmc/slot-gpio.h> #include <linux/mmc/slot-gpio.h>
#include <mydebug.h>
#include "core.h" #include "core.h"
#include "crypto.h" #include "crypto.h"
#include "host.h" #include "host.h"
@@ -277,7 +277,7 @@ EXPORT_SYMBOL(mmc_of_parse_clk_phase);
int mmc_of_parse(struct mmc_host *host) int mmc_of_parse(struct mmc_host *host)
{ {
struct device *dev = host->parent; struct device *dev = host->parent;
u32 bus_width, drv_type, cd_debounce_delay_ms; u32 bus_width, drv_type;
int ret; int ret;
if (!dev || !dev_fwnode(dev)) if (!dev || !dev_fwnode(dev))
@@ -329,14 +329,14 @@ int mmc_of_parse(struct mmc_host *host)
host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
if (device_property_read_u32(dev, "cd-debounce-delay-ms", if (device_property_read_u32(dev, "cd-debounce-delay-ms",
&cd_debounce_delay_ms)) &host->cd_debounce_delay_ms))
cd_debounce_delay_ms = 200; host->cd_debounce_delay_ms = 200;
if (device_property_read_bool(dev, "broken-cd")) if (device_property_read_bool(dev, "broken-cd"))
host->caps |= MMC_CAP_NEEDS_POLL; host->caps |= MMC_CAP_NEEDS_POLL;
ret = mmc_gpiod_request_cd(host, "cd", 0, false, ret = mmc_gpiod_request_cd(host, "cd", 0, false,
cd_debounce_delay_ms * 1000); host->cd_debounce_delay_ms * 1000);
if (!ret) if (!ret)
dev_info(host->parent, "Got CD GPIO\n"); dev_info(host->parent, "Got CD GPIO\n");
else if (ret != -ENOENT && ret != -ENOSYS) else if (ret != -ENOENT && ret != -ENOSYS)
@@ -662,6 +662,7 @@ EXPORT_SYMBOL(mmc_remove_host);
*/ */
void mmc_free_host(struct mmc_host *host) void mmc_free_host(struct mmc_host *host)
{ {
cancel_delayed_work_sync(&host->detect);
mmc_pwrseq_free(host); mmc_pwrseq_free(host);
put_device(&host->class_dev); put_device(&host->class_dev);
} }

View File

@@ -920,11 +920,14 @@ static int mmc_sd_get_ro(struct mmc_host *host)
return ro; return ro;
} }
#define MMC_SD_INIT_RETRIES 1
int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
bool reinit) bool reinit)
{ {
int err; int err;
#ifdef MMC_SD_INIT_RETRIES
int retries;
#endif
if (!reinit) { if (!reinit) {
/* /*
@@ -953,7 +956,25 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
* Fetch switch information from card. Note, sd3_bus_mode can change if * Fetch switch information from card. Note, sd3_bus_mode can change if
* voltage switch outcome changes, so do this always. * voltage switch outcome changes, so do this always.
*/ */
#ifdef MMC_SD_INIT_RETRIES
for (retries = 1; retries <= 3; retries++) {
err = mmc_read_switch(card); err = mmc_read_switch(card);
if (!err) {
if (retries > 1) {
printk(KERN_WARNING
"%s: recovered\n",
mmc_hostname(host));
}
break;
} else {
printk(KERN_WARNING
"%s: read switch failed (attempt %d)\n",
mmc_hostname(host), retries);
}
}
#else
err = mmc_read_switch(card);
#endif
if (err) if (err)
return err; return err;
@@ -1604,14 +1625,33 @@ static int mmc_sd_alive(struct mmc_host *host)
*/ */
static void mmc_sd_detect(struct mmc_host *host) static void mmc_sd_detect(struct mmc_host *host)
{ {
int err; int err = 0;
#ifdef MMC_SD_INIT_RETRIES
int retries = 5;
#endif
mmc_get_card(host->card, NULL); mmc_get_card(host->card, NULL);
/* /*
* Just check if our card has been removed. * Just check if our card has been removed.
*/ */
#ifdef MMC_SD_INIT_RETRIES
while(retries) {
err = mmc_send_status(host->card, NULL);
if (err) {
retries--;
udelay(5);
continue;
}
break;
}
if (!retries) {
printk(KERN_ERR "%s(%s): Unable to re-detect card (%d)\n",
__func__, mmc_hostname(host), err);
}
#else
err = _mmc_detect_card_removed(host); err = _mmc_detect_card_removed(host);
#endif
mmc_put_card(host->card, NULL); mmc_put_card(host->card, NULL);
@@ -1739,6 +1779,9 @@ static int mmc_sd_suspend(struct mmc_host *host)
static int _mmc_sd_resume(struct mmc_host *host) static int _mmc_sd_resume(struct mmc_host *host)
{ {
int err = 0; int err = 0;
#ifdef MMC_SD_INIT_RETRIES
int retries;
#endif
mmc_claim_host(host); mmc_claim_host(host);
@@ -1746,7 +1789,23 @@ static int _mmc_sd_resume(struct mmc_host *host)
goto out; goto out;
mmc_power_up(host, host->card->ocr); mmc_power_up(host, host->card->ocr);
#ifdef MMC_SD_INIT_RETRIES
retries = 5;
while (retries) {
err = mmc_sd_init_card(host, host->card->ocr, host->card); err = mmc_sd_init_card(host, host->card->ocr, host->card);
if (err) {
printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
mmc_hostname(host), err, retries);
mdelay(5);
retries--;
continue;
}
break;
}
#else
err = mmc_sd_init_card(host, host->card->ocr, host->card);
#endif
mmc_card_clr_suspended(host->card); mmc_card_clr_suspended(host->card);
out: out:
@@ -1823,6 +1882,9 @@ int mmc_attach_sd(struct mmc_host *host)
{ {
int err; int err;
u32 ocr, rocr; u32 ocr, rocr;
#ifdef MMC_SD_INIT_RETRIES
int retries;
#endif
WARN_ON(!host->claimed); WARN_ON(!host->claimed);
@@ -1864,9 +1926,27 @@ int mmc_attach_sd(struct mmc_host *host)
/* /*
* Detect and init the card. * Detect and init the card.
*/ */
#ifdef MMC_SD_INIT_RETRIES
retries = 5;
while (retries) {
err = mmc_sd_init_card(host, rocr, NULL);
if (err) {
retries--;
continue;
}
break;
}
if (!retries) {
printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n",
mmc_hostname(host), err);
goto err;
}
#else
err = mmc_sd_init_card(host, rocr, NULL); err = mmc_sd_init_card(host, rocr, NULL);
if (err) if (err)
goto err; goto err;
#endif
mmc_release_host(host); mmc_release_host(host);
err = mmc_add_card(host->card); err = mmc_add_card(host->card);

View File

@@ -1216,6 +1216,8 @@ int mmc_attach_sdio(struct mmc_host *host)
* Detect and init the card. * Detect and init the card.
*/ */
err = mmc_sdio_init_card(host, rocr, NULL); err = mmc_sdio_init_card(host, rocr, NULL);
if (err)
err = mmc_sdio_init_card(host, rocr, NULL);
if (err) if (err)
goto err; goto err;

View File

@@ -4716,7 +4716,7 @@ static int sdhci_msm_setup_ice_clk(struct sdhci_msm_host *msm_host,
static void sdhci_msm_set_caps(struct sdhci_msm_host *msm_host) static void sdhci_msm_set_caps(struct sdhci_msm_host *msm_host)
{ {
msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM; //msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
} }
/* RUMI W/A for SD card */ /* RUMI W/A for SD card */

View File

@@ -57,6 +57,13 @@
#define WLS_FW_BUF_SIZE 128 #define WLS_FW_BUF_SIZE 128
#define DEFAULT_RESTRICT_FCC_UA 1000000 #define DEFAULT_RESTRICT_FCC_UA 1000000
//#undef dev_dbg
//#define dev_dbg dev_err
//#undef pr_debug
//#define pr_debug pr_info
extern void bcl_configure_bcl(int e);
enum psy_type { enum psy_type {
PSY_TYPE_BATTERY, PSY_TYPE_BATTERY,
PSY_TYPE_USB, PSY_TYPE_USB,
@@ -95,6 +102,9 @@ enum battery_property_id {
BATT_RESISTANCE, BATT_RESISTANCE,
BATT_POWER_NOW, BATT_POWER_NOW,
BATT_POWER_AVG, BATT_POWER_AVG,
BATT_SMB_PRESENT,
BATT_SMB1_CURRENT,
BATT_SMB2_CURRENT,
BATT_PROP_MAX, BATT_PROP_MAX,
}; };
@@ -112,6 +122,9 @@ enum usb_property_id {
USB_TEMP, USB_TEMP,
USB_REAL_TYPE, USB_REAL_TYPE,
USB_TYPEC_COMPLIANT, USB_TYPEC_COMPLIANT,
USB_TYPEC_ORIENTATION,
USB_TYPEC_DISABLE,
USB_CHARGE_NOW,
USB_PROP_MAX, USB_PROP_MAX,
}; };
@@ -297,6 +310,7 @@ static const int usb_prop_map[USB_PROP_MAX] = {
[USB_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, [USB_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
[USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE, [USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE,
[USB_TEMP] = POWER_SUPPLY_PROP_TEMP, [USB_TEMP] = POWER_SUPPLY_PROP_TEMP,
[USB_CHARGE_NOW]= POWER_SUPPLY_PROP_CHARGE_NOW,
}; };
static const int wls_prop_map[WLS_PROP_MAX] = { static const int wls_prop_map[WLS_PROP_MAX] = {
@@ -325,6 +339,8 @@ static const char * const qc_power_supply_wls_type_text[] = {
"Unknown", "BPP", "EPP", "HPP" "Unknown", "BPP", "EPP", "HPP"
}; };
static struct battery_chg_dev *g_bcdev = NULL;
static RAW_NOTIFIER_HEAD(hboost_notifier); static RAW_NOTIFIER_HEAD(hboost_notifier);
int register_hboost_event_notifier(struct notifier_block *nb) int register_hboost_event_notifier(struct notifier_block *nb)
@@ -728,6 +744,7 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data,
static struct power_supply_desc usb_psy_desc; static struct power_supply_desc usb_psy_desc;
int temp_type;
static void battery_chg_update_usb_type_work(struct work_struct *work) static void battery_chg_update_usb_type_work(struct work_struct *work)
{ {
struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev *bcdev = container_of(work,
@@ -748,6 +765,14 @@ static void battery_chg_update_usb_type_work(struct work_struct *work)
pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]); pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]);
if (pst->prop[USB_ADAP_TYPE]!=temp_type){
if(pst->prop[USB_ADAP_TYPE] >= POWER_SUPPLY_USB_TYPE_PD){
bcl_configure_bcl(0);
}else{
bcl_configure_bcl(1);
}
temp_type = pst->prop[USB_ADAP_TYPE];
}
switch (pst->prop[USB_ADAP_TYPE]) { switch (pst->prop[USB_ADAP_TYPE]) {
case POWER_SUPPLY_USB_TYPE_SDP: case POWER_SUPPLY_USB_TYPE_SDP:
usb_psy_desc.type = POWER_SUPPLY_TYPE_USB; usb_psy_desc.type = POWER_SUPPLY_TYPE_USB;
@@ -1111,6 +1136,7 @@ static enum power_supply_property usb_props[] = {
POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_CURRENT_MAX,
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_USB_TYPE, POWER_SUPPLY_PROP_USB_TYPE,
POWER_SUPPLY_PROP_TEMP, POWER_SUPPLY_PROP_TEMP,
}; };
@@ -1701,6 +1727,81 @@ static ssize_t usb_typec_compliant_show(struct class *c,
} }
static CLASS_ATTR_RO(usb_typec_compliant); static CLASS_ATTR_RO(usb_typec_compliant);
static ssize_t usb_charge_now_store(struct class *c,
struct class_attribute *attr,
const char *buf, size_t count)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
u32 val;
int rc;
if (kstrtou32(buf, 0, &val))
return -EINVAL;
rc = write_property_id(bcdev, pst, USB_CHARGE_NOW, val);
if (rc < 0)
return rc;
printk(KERN_ERR "jaden usb_charge_now_store val :%d\n",val);
return count;
}
static CLASS_ATTR_WO(usb_charge_now);
static ssize_t usb_typec_orientation_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
int rc;
rc = read_property_id(bcdev, pst, USB_TYPEC_ORIENTATION);
if (rc < 0)
return rc;
printk(KERN_ERR "jaden usb_typec_orientation_show\n");
//kernel_power_off();
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[USB_TYPEC_ORIENTATION]);
}
static CLASS_ATTR_RO(usb_typec_orientation);
static ssize_t usb_typec_disable_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
int rc;
rc = read_property_id(bcdev, pst, USB_TYPEC_DISABLE);
printk(KERN_ERR "jaden usb_typec_disable_show\n");
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[USB_TYPEC_DISABLE]);
}
static CLASS_ATTR_RO(usb_typec_disable);
int usb_typec_disable(void)
{
struct psy_state *pst = &g_bcdev->psy_list[PSY_TYPE_USB];
int rc;
rc = read_property_id(g_bcdev, pst, USB_TYPEC_DISABLE);
printk(KERN_ERR "jaden usb_typec_disable\n");
if (rc < 0)
return rc;
return 0;
}
EXPORT_SYMBOL(usb_typec_disable);
static ssize_t usb_real_type_show(struct class *c, static ssize_t usb_real_type_show(struct class *c,
struct class_attribute *attr, char *buf) struct class_attribute *attr, char *buf)
{ {
@@ -1750,7 +1851,8 @@ static ssize_t restrict_cur_show(struct class *c, struct class_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "%u\n", bcdev->restrict_fcc_ua); return scnprintf(buf, PAGE_SIZE, "%u\n", bcdev->restrict_fcc_ua);
} }
static CLASS_ATTR_RW(restrict_cur); //static CLASS_ATTR_RW(restrict_cur);
static struct class_attribute class_attr_restrict_cur = __ATTR(restrict_cur, 0664, restrict_cur_show, restrict_cur_store);
static ssize_t restrict_chg_store(struct class *c, struct class_attribute *attr, static ssize_t restrict_chg_store(struct class *c, struct class_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
@@ -1780,7 +1882,8 @@ static ssize_t restrict_chg_show(struct class *c, struct class_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "%d\n", bcdev->restrict_chg_en); return scnprintf(buf, PAGE_SIZE, "%d\n", bcdev->restrict_chg_en);
} }
static CLASS_ATTR_RW(restrict_chg); //static CLASS_ATTR_RW(restrict_chg);
static struct class_attribute class_attr_restrict_chg = __ATTR(restrict_chg, 0664, restrict_chg_show, restrict_chg_store);
static ssize_t fake_soc_store(struct class *c, struct class_attribute *attr, static ssize_t fake_soc_store(struct class *c, struct class_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
@@ -1917,6 +2020,54 @@ static ssize_t resistance_show(struct class *c,
return scnprintf(buf, PAGE_SIZE, "%u\n", pst->prop[BATT_RESISTANCE]); return scnprintf(buf, PAGE_SIZE, "%u\n", pst->prop[BATT_RESISTANCE]);
} }
static CLASS_ATTR_RO(resistance); static CLASS_ATTR_RO(resistance);
static ssize_t smb1_current_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_BATTERY];
int rc;
rc = read_property_id(bcdev, pst, BATT_SMB1_CURRENT);
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[BATT_SMB1_CURRENT]);
}
static CLASS_ATTR_RO(smb1_current);
static ssize_t smb2_current_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_BATTERY];
int rc;
rc = read_property_id(bcdev, pst, BATT_SMB2_CURRENT);
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[BATT_SMB2_CURRENT]);
}
static CLASS_ATTR_RO(smb2_current);
static ssize_t smb_present_show(struct class *c,
struct class_attribute *attr, char *buf)
{
struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev,
battery_class);
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_BATTERY];
int rc;
rc = read_property_id(bcdev, pst, BATT_SMB_PRESENT);
if (rc < 0)
return rc;
return scnprintf(buf, PAGE_SIZE, "%d\n",
(int)pst->prop[BATT_SMB_PRESENT]);
}
static CLASS_ATTR_RO(smb_present);
static ssize_t soh_show(struct class *c, struct class_attribute *attr, static ssize_t soh_show(struct class *c, struct class_attribute *attr,
char *buf) char *buf)
@@ -1974,6 +2125,12 @@ static struct attribute *battery_class_attrs[] = {
&class_attr_restrict_cur.attr, &class_attr_restrict_cur.attr,
&class_attr_usb_real_type.attr, &class_attr_usb_real_type.attr,
&class_attr_usb_typec_compliant.attr, &class_attr_usb_typec_compliant.attr,
&class_attr_usb_typec_orientation.attr,
&class_attr_usb_typec_disable.attr,
&class_attr_usb_charge_now.attr,
&class_attr_smb_present.attr,
&class_attr_smb1_current.attr,
&class_attr_smb2_current.attr,
NULL, NULL,
}; };
ATTRIBUTE_GROUPS(battery_class); ATTRIBUTE_GROUPS(battery_class);
@@ -2320,8 +2477,13 @@ static int battery_chg_probe(struct platform_device *pdev)
rc = battery_chg_parse_dt(bcdev); rc = battery_chg_parse_dt(bcdev);
if (rc < 0) { if (rc < 0) {
dev_err(dev, "Failed to parse dt rc=%d\n", rc); msleep(500);
dev_err(dev, "Failed to parse dt rc=%d delay 500ms retry", rc);
rc = battery_chg_parse_dt(bcdev);
if (rc < 0) {
dev_err(dev, "Failed to parse dt rc=%d", rc);
goto error; goto error;
};
} }
bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA; bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA;
@@ -2353,6 +2515,7 @@ static int battery_chg_probe(struct platform_device *pdev)
bcdev->wls_fw_update_time_ms = WLS_FW_UPDATE_TIME_MS; bcdev->wls_fw_update_time_ms = WLS_FW_UPDATE_TIME_MS;
battery_chg_add_debugfs(bcdev); battery_chg_add_debugfs(bcdev);
bcdev->notify_en = false; bcdev->notify_en = false;
g_bcdev = bcdev;
battery_chg_notify_enable(bcdev); battery_chg_notify_enable(bcdev);
device_init_wakeup(bcdev->dev, true); device_init_wakeup(bcdev->dev, true);
schedule_work(&bcdev->usb_type_work); schedule_work(&bcdev->usb_type_work);

View File

@@ -25,6 +25,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/pinctrl/consumer.h>
#include <linux/string.h>
#define REG_SIZE_PER_LPG 0x100 #define REG_SIZE_PER_LPG 0x100
#define LPG_BASE "lpg-base" #define LPG_BASE "lpg-base"
@@ -164,6 +166,12 @@ static const int clk_period_ns_hi_res[NUM_PWM_HI_RES_CLK] = {976562, 30517, 52,
static const int clk_prediv[NUM_CLK_PREDIV] = {1, 3, 5, 6}; static const int clk_prediv[NUM_CLK_PREDIV] = {1, 3, 5, 6};
static const int pwm_exponent[NUM_PWM_EXP] = {0, 1, 2, 3, 4, 5, 6, 7}; static const int pwm_exponent[NUM_PWM_EXP] = {0, 1, 2, 3, 4, 5, 6, 7};
static struct pinctrl *pmk8550_gpio5_pinctrl;
static struct pinctrl_state *pinctrl_state_active;
static struct pinctrl_state *pinctrl_state_suspend;
#define PINCTRL_STATE_ACTIVE "active"
#define PINCTRL_STATE_SUSPEND "suspend"
struct lpg_ramp_config { struct lpg_ramp_config {
u16 step_ms; u16 step_ms;
u8 pause_hi_count; u8 pause_hi_count;
@@ -1506,11 +1514,33 @@ static int qpnp_lpg_pwm_apply(struct pwm_chip *pwm_chip, struct pwm_device *pwm,
if (state->enabled != pwm->state.enabled) { if (state->enabled != pwm->state.enabled) {
if (state->enabled) { if (state->enabled) {
if(!strncmp(pwm->label, "qcom,mdss_dsi", 13)){
if(IS_ERR_OR_NULL(pmk8550_gpio5_pinctrl)){
rc = PTR_ERR(pmk8550_gpio5_pinctrl);
printk(KERN_ERR "Darcy pwm enabled pmk8550_gpio5_pinctrl not use %d\n",rc);
} else if(pmk8550_gpio5_pinctrl && pinctrl_state_active){
rc = pinctrl_select_state(pmk8550_gpio5_pinctrl, pinctrl_state_active);
if(rc<0){
printk(KERN_ERR "Failed to select pmk8550_gpio5 pin to active state\n");
}
}
}
rc = qpnp_lpg_pwm_enable(pwm->chip, pwm); rc = qpnp_lpg_pwm_enable(pwm->chip, pwm);
if (rc < 0) if (rc < 0)
return rc; return rc;
} else { } else {
qpnp_lpg_pwm_disable(pwm->chip, pwm); qpnp_lpg_pwm_disable(pwm->chip, pwm);
if(!strncmp(pwm->label, "qcom,mdss_dsi", 13)){
if(IS_ERR_OR_NULL(pmk8550_gpio5_pinctrl)){
rc = PTR_ERR(pmk8550_gpio5_pinctrl);
printk(KERN_ERR "Darcy pwm Disable pmk8550_gpio5_pinctrl not use %d\n",rc);
}else if(pmk8550_gpio5_pinctrl && pinctrl_state_suspend){
rc = pinctrl_select_state(pmk8550_gpio5_pinctrl, pinctrl_state_suspend);
if(rc<0){
printk(KERN_ERR "Failed to select pmk8550_gpio5 pin to suspend state\n");
}
}
}
} }
pwm->state.enabled = state->enabled; pwm->state.enabled = state->enabled;
@@ -2013,6 +2043,29 @@ static int qpnp_lpg_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
chip->dev = &pdev->dev; chip->dev = &pdev->dev;
//pmk8550_gpio5_pinctrl add
pmk8550_gpio5_pinctrl = devm_pinctrl_get(chip->dev);
if(IS_ERR_OR_NULL(pmk8550_gpio5_pinctrl)){
rc = PTR_ERR(pmk8550_gpio5_pinctrl);
dev_err(&pdev->dev,"Darcy Target does not use pinctrl %d\n",rc);
goto err_pinctrl_get;
}
pinctrl_state_active = pinctrl_lookup_state(pmk8550_gpio5_pinctrl,PINCTRL_STATE_ACTIVE);
if(IS_ERR_OR_NULL(pinctrl_state_active)){
rc = PTR_ERR(pinctrl_state_active);
dev_err(&pdev->dev,"Darcy Can not lookup %s pinstate %d\n",PINCTRL_STATE_ACTIVE,rc);
}
pinctrl_state_suspend = pinctrl_lookup_state(pmk8550_gpio5_pinctrl,PINCTRL_STATE_SUSPEND);
if(IS_ERR_OR_NULL(pinctrl_state_suspend)){
rc = PTR_ERR(pinctrl_state_suspend);
dev_err(&pdev->dev,"Darcy Can not lookup %s pinstate %d\n",PINCTRL_STATE_SUSPEND,rc);
}
err_pinctrl_get:
//end
chip->regmap = dev_get_regmap(chip->dev->parent, NULL); chip->regmap = dev_get_regmap(chip->dev->parent, NULL);
if (!chip->regmap) { if (!chip->regmap) {
dev_err(chip->dev, "Getting regmap failed\n"); dev_err(chip->dev, "Getting regmap failed\n");

View File

@@ -107,7 +107,7 @@ out:
return pivot; return pivot;
} }
/*
static void print_irq_stat(struct msm_watchdog_data *wdog_dd) static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
{ {
int index; int index;
@@ -143,7 +143,7 @@ static void print_irq_stat(struct msm_watchdog_data *wdog_dd)
} }
pr_cont("\n"); pr_cont("\n");
} }
*/
static void compute_irq_stat(struct work_struct *work) static void compute_irq_stat(struct work_struct *work)
{ {
unsigned int count; unsigned int count;
@@ -249,7 +249,7 @@ static void compute_irq_stat(struct work_struct *work)
} }
} }
print_irq_stat(wdog_dd); //print_irq_stat(wdog_dd);
atomic_xchg(&wdog_dd->irq_counts_running, 0); atomic_xchg(&wdog_dd->irq_counts_running, 0);
} }

View File

@@ -153,6 +153,7 @@ struct bcl_device {
}; };
static struct bcl_device *bcl_devices[MAX_PERPH_COUNT]; static struct bcl_device *bcl_devices[MAX_PERPH_COUNT];
struct bcl_device *bcl_perph_temp;
static int bcl_device_ct; static int bcl_device_ct;
static int bcl_read_register(struct bcl_device *bcl_perph, int16_t reg_offset, static int bcl_read_register(struct bcl_device *bcl_perph, int16_t reg_offset,
@@ -918,6 +919,15 @@ static void bcl_configure_bcl_peripheral(struct bcl_device *bcl_perph)
bcl_write_register(bcl_perph, BCL_MONITOR_EN, BIT(7)); bcl_write_register(bcl_perph, BCL_MONITOR_EN, BIT(7));
} }
void bcl_configure_bcl(int enable)
{
if (enable)
bcl_write_register(bcl_perph_temp, BCL_MONITOR_EN, BIT(7));
else
bcl_write_register(bcl_perph_temp, BCL_MONITOR_EN, 0);
}
EXPORT_SYMBOL(bcl_configure_bcl);
static int bcl_remove(struct platform_device *pdev) static int bcl_remove(struct platform_device *pdev)
{ {
int i = 0; int i = 0;
@@ -949,6 +959,7 @@ static int bcl_probe(struct platform_device *pdev)
if (!bcl_devices[bcl_device_ct]) if (!bcl_devices[bcl_device_ct])
return -ENOMEM; return -ENOMEM;
bcl_perph = bcl_devices[bcl_device_ct]; bcl_perph = bcl_devices[bcl_device_ct];
bcl_perph_temp = bcl_perph;
bcl_perph->dev = &pdev->dev; bcl_perph->dev = &pdev->dev;
bcl_perph->regmap = dev_get_regmap(pdev->dev.parent, NULL); bcl_perph->regmap = dev_get_regmap(pdev->dev.parent, NULL);

View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2024, check mcu data. All rights reserved.
*/
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/ipc_logging.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/qcom-geni-se.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/suspend.h>/*包含#include <linux/freezer.h>freezer.h又包含"set_freezable"*/
#include <linux/ioctl.h>
#include <linux/pinctrl/consumer.h>
#include <linux/dma-mapping.h>
#include <linux/kthread.h>
#include <linux/kernel.h>/*printk()*/
#include <linux/sched.h>
#include <mydebug.h>
#define FRAME_POS_HEAD_1 0
#define FRAME_POS_HEAD_2 1
#define FRAME_POS_HEAD_3 2
#define FRAME_POS_HEAD_4 3
#define FRAME_POS_SEQ 4
#define FRAME_POS_CMD 5
#define FRAME_POS_LEN_LOW 6
#define FRAME_POS_LEN_HIGHT 7
#define FRAME_POS_DATA_0 8
#define FRAME_POS_DATA_1 9
#define FRAME_POS_DATA_2 10
#define FRAME_DATA_MIN 9
#define FRAME_HEAD_1 0xA5
#define FRAME_HEAD_2 0xD3
#define FRAME_HEAD_3 0x5A
#define FRAME_HEAD_4 0x3D
#define CMD_COMMOD 0x01
#define CMD_STATUS 0x02
#define CMD_IAP 0x03
#define USART_RX_BUFF_MAX 2048//20480
#define PRINT_DATA_BUFF_MAX 1024//4096
int dataLen(char* buf)
{
return (char)( (buf[FRAME_POS_LEN_LOW]&0xff) | ((buf[FRAME_POS_LEN_HIGHT] >> 8)&0xFF) );
}
int checkSumDataLen(char* buf)
{
return dataLen(buf) + 4; // data + seq length1 length2 cmd
}
int calcChecksum(char* buf)
{
int index = 0;
int sum = 0;// 定义为byte时最高位变成符号导致最高位为1时检验和为负数变成检验不通过
int len = checkSumDataLen(buf) + FRAME_POS_SEQ;
for(index=FRAME_POS_SEQ; index<len; index++){
sum ^= buf[index];
//KERNEL_ERROR("sum=0x%x, buf[%d]=%x", (sum&0xFF), index, buf[index]);
}
//KERNEL_ERROR("sum=0x%x", (sum&0xFF));
return (sum&0xFF);
}
int headFrontErr = 0;
int headErr = 0;
int checksumErr = 0;
int dataLenErr = 0;
EXPORT_SYMBOL(headFrontErr);
EXPORT_SYMBOL(headErr);
EXPORT_SYMBOL(checksumErr);
EXPORT_SYMBOL(dataLenErr);
void printfData(char errno, char *buffer, int len)
{
static char data[PRINT_DATA_BUFF_MAX] = {0};
int index = 0, pos = 0;
for(index=0; index<len; index++){
sprintf(data+pos, "%02x ", buffer[index]);
pos += 3;
if(pos >= PRINT_DATA_BUFF_MAX - 3){
break;
}
}
if(errno > 0){
KERNEL_ERROR("errno=%d, length=%d, data=%s", errno, len, data);
}
}
static char WORK_INTERVAL = 30;
static char buffer_ring[USART_RX_BUFF_MAX] = {0};
static int recvDataLen = 0;
static int procDataLen = 0;
void copyMcuData(char *buf, int length)
{
// 接收数据
if(length >= USART_RX_BUFF_MAX){
KERNEL_ERROR("length=%d, too much data, bigger %d.", length, USART_RX_BUFF_MAX);
recvDataLen = 0;
}
if(length + recvDataLen >= USART_RX_BUFF_MAX){
KERNEL_ERROR("recvDataLen=%d, length=%d, Complete verification, bigger %d.", recvDataLen, length, USART_RX_BUFF_MAX);
recvDataLen = 0;
}
memcpy(buffer_ring+recvDataLen, buf, length);
recvDataLen += length;
WORK_INTERVAL = 30;
//printfData(1, buffer_ring, recvDataLen);
}
EXPORT_SYMBOL(copyMcuData);
static void processMcuData(void)
{
char *p = buffer_ring;
int len = recvDataLen;
int checksum = 0;
int pkt_len = 0;
char printfEn = 0;
if(recvDataLen == procDataLen){
WORK_INTERVAL = 100;
return;
}
// 需要处理的数据
while(len >= FRAME_DATA_MIN){
// find a packet HEAD
while ( len >= FRAME_POS_HEAD_4 && \
((p[FRAME_POS_HEAD_1] != FRAME_HEAD_1 || \
p[FRAME_POS_HEAD_2] != FRAME_HEAD_2 || \
p[FRAME_POS_HEAD_3] != FRAME_HEAD_3 || \
p[FRAME_POS_HEAD_4] != FRAME_HEAD_4))) {
++p;
--len;
++headFrontErr;
++procDataLen;
}
if(len <= 0){ // 数据查找完成,但没有找到帧头
headErr++;
printfEn = 1;
KERNEL_ERROR("can`t find a packet HEAD\n");
break;
}
if(len < FRAME_DATA_MIN){ // 数据查找完成,但数据不完整
dataLenErr++;
printfEn = 2;
KERNEL_ERROR("The data is not complete frame. len=%d\n", len);
break;
}
pkt_len = p[FRAME_POS_LEN_LOW] + (p[FRAME_POS_LEN_HIGHT] << 8);
if(len < pkt_len + FRAME_DATA_MIN){
dataLenErr++;
printfEn = 3;
KERNEL_ERROR("The data is not complete frame. len=%d, pkt_len=%d\n", len, pkt_len);
break;
}
checksum = calcChecksum(p);
if(p[pkt_len + FRAME_POS_DATA_0] == checksum){
//KERNEL_ERROR("packet checksum Successful.");
printfEn = 5;
p += pkt_len + FRAME_DATA_MIN;
len -= pkt_len + FRAME_DATA_MIN; // 数据减少一帧
procDataLen += pkt_len + FRAME_DATA_MIN;
} else {
printfEn = 4;
checksumErr++;
p += FRAME_POS_HEAD_4;
len -= FRAME_POS_HEAD_4; // 数据减少帧头
procDataLen += FRAME_POS_HEAD_4;
KERNEL_ERROR("packet checksum=%x(%x) failed, skip it, len=%d", checksum, p[pkt_len + FRAME_POS_DATA_0], pkt_len);
}
if(printfEn != 5){
printfData(printfEn, buffer_ring, len);
printfEn = 0;
}
if(procDataLen >= USART_RX_BUFF_MAX){
procDataLen = 0;
}
}
}
static struct task_struct *detect_task = NULL;
static int readstatus_work(void *arg)
{
KERNEL_ERROR("readstatus_work start!\n");
set_freezable();
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(WORK_INTERVAL));
if (kthread_freezable_should_stop(NULL))
break;
processMcuData();
}
KERNEL_ERROR("readstatus_work exit!\n");
return 0;
}
void checkMcuRemove(void)
{
KERNEL_ERROR("remove task");
if(detect_task != NULL){
kthread_stop(detect_task);
detect_task = NULL;
}
}
EXPORT_SYMBOL(checkMcuRemove);
void checkMcuInit(void)
{
KERNEL_ERROR("init task");
if(detect_task){
KERNEL_ERROR("mcu detect: kthread_create init");
return;
}
detect_task = kthread_run(readstatus_work, NULL, "mcu detect");
if (IS_ERR(detect_task)) {
KERNEL_ERROR("mcu detect: kthread_create failed");
return;
}
}
EXPORT_SYMBOL(checkMcuInit);

View File

@@ -32,6 +32,8 @@
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <mydebug.h>
#include "check_mcu_data.c"
#include <uapi/linux/msm_geni_serial.h> #include <uapi/linux/msm_geni_serial.h>
#include <soc/qcom/boot_stats.h> #include <soc/qcom/boot_stats.h>
@@ -181,7 +183,10 @@ static bool con_enabled = IS_ENABLED(CONFIG_SERIAL_MSM_GENI_CONSOLE_DEFAULT_ENAB
*/ */
#define POLL_ITERATIONS 1000 #define POLL_ITERATIONS 1000
#define IPC_LOG_MSG(ctx, x...) ipc_log_string(ctx, x) #define IPC_LOG_MSG(ctx, x...) do { \
if (ctx) \
ipc_log_string(ctx, x); \
} while (0)
#define DMA_RX_BUF_SIZE (2048) #define DMA_RX_BUF_SIZE (2048)
#define UART_CONSOLE_RX_WM (2) #define UART_CONSOLE_RX_WM (2)
@@ -1013,6 +1018,8 @@ static void dump_ipc(struct uart_port *uport, void *ipc_ctx, char *prefix,
char data[DATA_BYTES_PER_LINE * 3]; char data[DATA_BYTES_PER_LINE * 3];
int len = 0; int len = 0;
if (!ipc_ctx)
return;
len = min(size, DATA_BYTES_PER_LINE); len = min(size, DATA_BYTES_PER_LINE);
hex_dump_to_buffer(string, len, DATA_BYTES_PER_LINE, 1, buf, hex_dump_to_buffer(string, len, DATA_BYTES_PER_LINE, 1, buf,
sizeof(buf), false); sizeof(buf), false);
@@ -2958,6 +2965,10 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport)
__func__, ret); __func__, ret);
} }
static int checkmcuEn = 0;
extern void copyMcuData(char *buf, int length);
extern void checkMcuInit(void);
extern void checkMcuRemove(void);
static int handle_rx_hs(struct uart_port *uport, static int handle_rx_hs(struct uart_port *uport,
unsigned int rx_fifo_wc, unsigned int rx_fifo_wc,
unsigned int rx_last_byte_valid, unsigned int rx_last_byte_valid,
@@ -2989,6 +3000,9 @@ static int handle_rx_hs(struct uart_port *uport,
} }
uport->icount.rx += ret; uport->icount.rx += ret;
tty_flip_buffer_push(tport); tty_flip_buffer_push(tport);
if(checkmcuEn == 1 && uport->line == 1){
copyMcuData((char *)msm_port->rx_fifo, rx_bytes);
}
dump_ipc(uport, msm_port->ipc_log_rx, "Rx", (char *)msm_port->rx_fifo, 0, dump_ipc(uport, msm_port->ipc_log_rx, "Rx", (char *)msm_port->rx_fifo, 0,
rx_bytes); rx_bytes);
return ret; return ret;
@@ -3111,6 +3125,50 @@ exit_handle_tx:
return 0; return 0;
} }
extern int headFrontErr;
extern int headErr;
extern int checksumErr;
extern int dataLenErr;
static ssize_t checkmcu_show(struct device *dev, struct device_attribute *attr, char *ubuf)
{
ssize_t size = sprintf(ubuf, "%d", checkmcuEn);
KERNEL_ERROR("cmd_read: checkmcuEn=%d, headFrontErr=%d, headErr=%d, checksumErr=%d, dataLenErr=%d", checkmcuEn, headFrontErr, headErr, checksumErr, dataLenErr);
return size;
}
static void msm_geni_serial_debug_init(struct uart_port *uport, bool console);
static ssize_t checkmcu_store(struct device *dev, struct device_attribute *attr, const char *ubuf, size_t size)
{
struct uart_port *uport;
struct msm_geni_serial_port *port = get_port_from_line(1, false);
if (IS_ERR_OR_NULL(port))
return size;
uport = &port->uport;
KERNEL_ERROR("cmd_write:%s", ubuf);
if(!strncmp(ubuf, "checkmcu ", 9) && size > 9){
if(ubuf[9] == '1'){
checkMcuInit();
checkmcuEn = 1;
if (IS_ERR_OR_NULL(port->dbg))
msm_geni_serial_debug_init(uport, 0);
} else {
checkmcuEn = 0;
checkMcuRemove();
if (!IS_ERR_OR_NULL(port->dbg)){
port->dbg = NULL;
debugfs_remove(port->dbg);
}
}
} else {
KERNEL_ERROR(KERN_ERR "muxcmd error for cmd %s", ubuf);
}
return size;
}
static DEVICE_ATTR_RW(checkmcu);
/* /*
* msm_geni_find_wakeup_byte() - Checks if wakeup byte is present * msm_geni_find_wakeup_byte() - Checks if wakeup byte is present
* in rx buffer * in rx buffer
@@ -3255,6 +3313,9 @@ static int msm_geni_serial_handle_dma_rx(struct uart_port *uport, bool drop_rx)
uport->icount.rx += rx_bytes_copied; uport->icount.rx += rx_bytes_copied;
tty_flip_buffer_push(tport); tty_flip_buffer_push(tport);
if(checkmcuEn == 1 && uport->line == 1){
copyMcuData((char *)msm_port->rx_buf, rx_bytes_copied);
}
dump_ipc(uport, msm_port->ipc_log_rx, "DMA Rx", dump_ipc(uport, msm_port->ipc_log_rx, "DMA Rx",
(char *)msm_port->rx_buf, 0, rx_bytes_copied); (char *)msm_port->rx_buf, 0, rx_bytes_copied);
/* /*
@@ -5162,9 +5223,9 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
* To Disable PM runtime API that will make ioctl based * To Disable PM runtime API that will make ioctl based
* vote_clock_on/off optional and rely on system PM * vote_clock_on/off optional and rely on system PM
*/ */
dev_port->pm_auto_suspend_disable = dev_port->pm_auto_suspend_disable = 1;
of_property_read_bool(pdev->dev.of_node, //of_property_read_bool(pdev->dev.of_node,
"qcom,auto-suspend-disable"); //"qcom,auto-suspend-disable");
if (is_console) { if (is_console) {
dev_port->handle_rx = handle_rx_console; dev_port->handle_rx = handle_rx_console;
@@ -5203,8 +5264,8 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
device_create_file(uport->dev, &dev_attr_hs_uart_operation); device_create_file(uport->dev, &dev_attr_hs_uart_operation);
device_create_file(uport->dev, &dev_attr_hs_uart_version); device_create_file(uport->dev, &dev_attr_hs_uart_version);
device_create_file(uport->dev, &dev_attr_capture_kpi); device_create_file(uport->dev, &dev_attr_capture_kpi);
device_create_file(uport->dev, &dev_attr_checkmcu);
msm_geni_serial_debug_init(uport, is_console); //msm_geni_serial_debug_init(uport, is_console);
dev_port->port_setup = false; dev_port->port_setup = false;
dev_port->uart_error = UART_ERROR_DEFAULT; dev_port->uart_error = UART_ERROR_DEFAULT;
@@ -5269,6 +5330,12 @@ static int msm_geni_serial_remove(struct platform_device *pdev)
device_remove_file(port->uport.dev, &dev_attr_xfer_mode); device_remove_file(port->uport.dev, &dev_attr_xfer_mode);
device_remove_file(port->uport.dev, &dev_attr_ver_info); device_remove_file(port->uport.dev, &dev_attr_ver_info);
device_remove_file(port->uport.dev, &dev_attr_capture_kpi); device_remove_file(port->uport.dev, &dev_attr_capture_kpi);
device_remove_file(port->uport.dev, &dev_attr_checkmcu);
if(checkmcuEn == 1){
checkMcuRemove();
}
if (!IS_ERR_OR_NULL(port->dbg))
debugfs_remove(port->dbg); debugfs_remove(port->dbg);
dev_info(&pdev->dev, "%s driver removed %d\n", __func__, true); dev_info(&pdev->dev, "%s driver removed %d\n", __func__, true);

View File

@@ -100,7 +100,7 @@ obj-$(CONFIG_SMBFS_COMMON) += smbfs_common/
obj-$(CONFIG_CIFS) += cifs/ obj-$(CONFIG_CIFS) += cifs/
obj-$(CONFIG_SMB_SERVER) += ksmbd/ obj-$(CONFIG_SMB_SERVER) += ksmbd/
obj-$(CONFIG_HPFS_FS) += hpfs/ obj-$(CONFIG_HPFS_FS) += hpfs/
obj-$(CONFIG_NTFS_FS) += ntfs/ obj-y += ntfs/
obj-$(CONFIG_NTFS3_FS) += ntfs3/ obj-$(CONFIG_NTFS3_FS) += ntfs3/
obj-$(CONFIG_UFS_FS) += ufs/ obj-$(CONFIG_UFS_FS) += ufs/
obj-$(CONFIG_EFS_FS) += efs/ obj-$(CONFIG_EFS_FS) += efs/

View File

@@ -36,7 +36,7 @@ struct mipi_dsi_msg {
u16 flags; u16 flags;
size_t tx_len; size_t tx_len;
const void *tx_buf; void *tx_buf;
size_t rx_len; size_t rx_len;
void *rx_buf; void *rx_buf;

View File

@@ -81,8 +81,9 @@
#define EXTCON_DOCK 60 #define EXTCON_DOCK 60
#define EXTCON_JIG 61 #define EXTCON_JIG 61
#define EXTCON_MECHANICAL 62 #define EXTCON_MECHANICAL 62
#define EXTCON_DEMO_A 63
#define EXTCON_NUM 63 #define EXTCON_NUM 64
/* /*
* Define the properties of supported external connectors. * Define the properties of supported external connectors.

View File

@@ -338,6 +338,7 @@ struct mmc_host {
u32 max_current_330; u32 max_current_330;
u32 max_current_300; u32 max_current_300;
u32 max_current_180; u32 max_current_180;
u32 cd_debounce_delay_ms;
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */

173
include/mydebug.h Executable file
View File

@@ -0,0 +1,173 @@
/*
* mydebug.h
*
* ============================================================================
* Copyright (c) 2011 Liuwen
*
* Use of this software is controlled by the terms and conditions found in the
* license agreement under which this software has been supplied or provided.
* ============================================================================
*/
#ifndef KERNEL_DEBUG_H
#define KERNEL_DEBUG_H
//GPIO的文件
#include <linux/io.h>
#include <linux/of_gpio.h>
// 音效ic
// 触摸
#define GPIO_DIR_OUT 0
#define GPIO_DIR_IN 1
#define GPIO_OUT_LOW 0
#define GPIO_OUT_HIGH 1
#define MCU_PWR (301+99) // 400 GPIO_99
#define MCU_BOOT (301+1) // 302 GPIO_1
#define MCU_RESET (301) // 301 GPIO_0
#define MCU_UART_PWR (301+12) // 313 GPIO_12
enum MCU_POWER_STATUS {
MCU_POWER_UNKNOWN,
MCU_POWER_ON,
MCU_POWER_OFF,
};
extern void rs_gpio_set(int pin, int value);
extern int rs_gpio_get(int pin);
#define KERNEL_PRINTK 1
#define KERNEL_PROCESS 0
#define UNWIND_BACKTRACE 0
#ifdef KERNEL_GLOBALS
unsigned int all_times;//no define static, static only at the some file.
EXPORT_SYMBOL(all_times);
#else
extern unsigned int all_times;
#endif // KERNEL_GLOBALS
//#define MY_FILE (__FILE__ + 78 + 6)
#define MY_FILE __FILE__
// static unsigned int file_times;
#if UNWIND_BACKTRACE
#ifdef KERNEL_MODULE
#define MY_UNWIND_BACKTRACE()
#else
extern void my_unwind_backtrace(struct pt_regs *, struct task_struct *);//my_unwind_backtrace(NULL, NULL);
#define MY_UNWIND_BACKTRACE() my_unwind_backtrace(NULL, NULL)
#endif
#else
#define MY_UNWIND_BACKTRACE()
#endif /*UNWIND_BACKTRACE*/
#if KERNEL_PROCESS
#include <linux/sched.h>
//#include <asm/current.h>
#include <asm/thread_info.h>//arch/arm/include/asm/thread_info.h
#define cpu_context current_thread_info()->cpu_context
#define process_info(level) \
do{ \
printk(level "state=%s, Process_num=%d, pid=%d, tgid=%d, syscall=%d, cpu=%d, \
cpu_context.pc=0x%x, r4=0x%x, r5=0x%x, r6=0x%x, r7=0x%x, r8=0x%x, r9=0x%x, sl=0x%x, fp=0x%x, sp=0x%x, extra[0]=0x%x, extra[1]=0x%x", \
(current->state == -1)?"unrunnable":(current->state > -1 && current->state == 0)? "runnable":"stopped" ,\
current->flags, current->pid, current->tgid, current_thread_info()->syscall,\
current_thread_info()->cpu, cpu_context.pc, \
cpu_context.r4, cpu_context.r5, \
cpu_context.r6, cpu_context.r7, \
cpu_context.r8, cpu_context.r9, \
cpu_context.sl, cpu_context.fp, \
cpu_context.sp, cpu_context.extra[0], cpu_context.extra[1]); \
}while(0)
//cpu_context.cpu_context.extra
#else
#define process_info(level) do { } while(0)
#endif // KERNEL_PROCESS
#define driver_printk(level, format, args...) \
do{ \
printk(level "Odin [%s:%s():%d]" format, \
MY_FILE, __FUNCTION__, __LINE__, ##args); \
process_info(level); \
MY_UNWIND_BACKTRACE(); \
printk(level "\n"); \
}while(0)
#if KERNEL_PRINTK
#define KERNEL_DEBUG(format , args...) driver_printk(KERN_DEBUG, format, ## args)
#else
#define KERNEL_DEBUG(format , args...)
#endif
#define KERNEL_INFO(format , args...) driver_printk(KERN_INFO, format, ## args)
#define KERNEL_WARN(format , args...) driver_printk(KERN_WARNING, format, ## args)
#define KERNEL_ERROR(format , args...) driver_printk(KERN_ERR, format, ## args)
#endif// KERNEL_DEBUG_H
/*
printk后便
%p(raw pointer)
%pF可打印函数指针的函数名和偏移地址
%pf只打印函数指针的函数名
printk("%pf",func[0]->action);
my_Set
%pM打印冒号分隔的MAC地址
%pm打印MAC地址的16进制无分隔
printk("%pM %pm\n", mac, mac) willprint:
2c:00:1d:00:1b:00 2c001d001b00
%I4打印无前导0的IPv4地址%i4打印冒号分隔的IPv4地址
%I6打印无前导0的IPv6地址%i6打印冒号分隔的IPv6地址
printk("%pI4 %pi4\n", ip, ip) will print:
127.0.0.1 127:0:0:1
*/
//#define KERNEL_GLOBALS
//#include <mydebug.h>
//KERNEL_DEBUG("\n\n");

View File

@@ -732,7 +732,7 @@ config LOG_BUF_SHIFT
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" int "Kernel log buffer size (16 => 64KB, 17 => 128KB)"
range 12 25 if !H8300 range 12 25 if !H8300
range 12 19 if H8300 range 12 19 if H8300
default 17 default 22
depends on PRINTK depends on PRINTK
help help
Select the minimal kernel log buffer size as a power of 2. Select the minimal kernel log buffer size as a power of 2.
@@ -741,6 +741,7 @@ config LOG_BUF_SHIFT
by "log_buf_len" boot parameter. by "log_buf_len" boot parameter.
Examples: Examples:
22 => 4096 KB
17 => 128 KB 17 => 128 KB
16 => 64 KB 16 => 64 KB
15 => 32 KB 15 => 32 KB

View File

@@ -28,12 +28,14 @@ else
TIMESTAMP=$KBUILD_BUILD_TIMESTAMP TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
fi fi
if test -z "$KBUILD_BUILD_USER"; then if test -z "$KBUILD_BUILD_USER"; then
LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/') # LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
LINUX_COMPILE_BY="Thor"
else else
LINUX_COMPILE_BY=$KBUILD_BUILD_USER LINUX_COMPILE_BY=$KBUILD_BUILD_USER
fi fi
if test -z "$KBUILD_BUILD_HOST"; then if test -z "$KBUILD_BUILD_HOST"; then
LINUX_COMPILE_HOST=`uname -n` # LINUX_COMPILE_HOST=`uname -n`
LINUX_COMPILE_HOST="ayn_server"
else else
LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST LINUX_COMPILE_HOST=$KBUILD_BUILD_HOST
fi fi

View File

@@ -1008,17 +1008,50 @@ struct avc_node *avc_compute_av(struct selinux_state *state,
rcu_read_lock(); rcu_read_lock();
return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node); return avc_insert(state->avc, ssid, tsid, tclass, avd, xp_node);
} }
extern int selinux_enforce_start;
static noinline int avc_denied(struct selinux_state *state, static noinline int avc_denied(struct selinux_state *state,
u32 ssid, u32 tsid, u32 ssid, u32 tsid,
u16 tclass, u32 requested, u16 tclass, u32 requested,
u8 driver, u8 xperm, unsigned int flags, u8 driver, u8 xperm, unsigned int flags,
struct av_decision *avd) struct av_decision *avd)
{ {
u32 scontext_len;
u32 tcontext_len;
u32 enable = enforcing_enabled(state);
char *scontext = NULL;
char *tcontext = NULL;
if (flags & AVC_STRICT) if (flags & AVC_STRICT)
return -EACCES; return -EACCES;
if (security_sid_to_context(state, ssid, &scontext, &scontext_len)){
if (enforcing_enabled(state) && } else {
if(selinux_enforce_start) {
if(strstr(scontext, "untrusted_app") != NULL) {
if (security_sid_to_context(state, tsid, &tcontext, &tcontext_len)){
if(!(avd->flags & AVD_FLAGS_PERMISSIVE)){
//printk(KERN_EMERG "%s scontext1:%s %d\n",__func__, scontext,avd->flags);
kfree(scontext);
return -EACCES;
}
} else {
if(strstr(tcontext, "pservice") == NULL) {
if(!(avd->flags & AVD_FLAGS_PERMISSIVE)){
//printk(KERN_EMERG "%s scontext:%s tcontext:%s %d\n",__func__, scontext, tcontext,avd->flags);
kfree(scontext);
kfree(tcontext);
return -EACCES;
}
}
}
}
enable = 0;
}
kfree(tcontext);
kfree(scontext);
}
if (enable &&
!(avd->flags & AVD_FLAGS_PERMISSIVE)) !(avd->flags & AVD_FLAGS_PERMISSIVE))
return -EACCES; return -EACCES;
@@ -1183,7 +1216,6 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
{ {
struct av_decision avd; struct av_decision avd;
int rc, rc2; int rc, rc2;
rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0, rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0,
&avd); &avd);

View File

@@ -64,6 +64,7 @@ enum sel_inos {
SEL_STATUS, /* export current status using mmap() */ SEL_STATUS, /* export current status using mmap() */
SEL_POLICY, /* allow userspace to read the in kernel policy */ SEL_POLICY, /* allow userspace to read the in kernel policy */
SEL_VALIDATE_TRANS, /* compute validatetrans decision */ SEL_VALIDATE_TRANS, /* compute validatetrans decision */
SEL_ENFORCE_START, /* compute validatetrans decision */
SEL_INO_NEXT, /* The next inode number to use */ SEL_INO_NEXT, /* The next inode number to use */
}; };
@@ -200,6 +201,51 @@ static const struct file_operations sel_enforce_ops = {
.write = sel_write_enforce, .write = sel_write_enforce,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
int selinux_enforce_start = 0;
static ssize_t sel_read_enforce_start(struct file *filp, char __user *buf,
size_t count, loff_t *ppos)
{
char tmpbuf[TMPBUFLEN];
ssize_t length;
length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
selinux_enforce_start);
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
}
static ssize_t sel_write_enforce_start(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *page = NULL;
ssize_t length;
int new_value;
if (count >= PAGE_SIZE)
return -ENOMEM;
/* No partial writes. */
if (*ppos != 0)
return -EINVAL;
page = memdup_user_nul(buf, count);
if (IS_ERR(page))
return PTR_ERR(page);
length = -EINVAL;
if (sscanf(page, "%d", &new_value) != 1)
goto out;
selinux_enforce_start = !!new_value;
out:
kfree(page);
return length;
}
static const struct file_operations sel_enforce_start_ops = {
.read = sel_read_enforce_start,
.write = sel_write_enforce_start,
};
static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf, static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
@@ -2080,6 +2126,8 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO}, [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops, [SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
S_IWUGO}, S_IWUGO},
[SEL_ENFORCE_START] = {"enforce_start", &sel_enforce_start_ops,
S_IRUGO|S_IWUSR},
/* last one */ {""} /* last one */ {""}
}; };