qcom platform 子系统(2)

/******************************************************************************/
/***以subsys_register为线索:
 和驱动架构里的subsys_registet的名字是重复的,driver framework中的是static的****/
/******************************************************************************/
kernel/drivers/base/bus.c
static int subsys_register(struct bus_type *subsys,
  const struct attribute_group **groups,
  struct kobject *parent_of_root)
{}
/**
 * subsys_system_register - register a subsystem at /sys/devices/system/
 * @subsys: system subsystem
 * @groups: default attributes for the root device
 *
 * All 'system' subsystems have a /sys/devices/system/<name> root device
 * with the name of the subsystem. The root device can carry subsystem-
 * wide attributes. All registered devices are below this single root
 * device and are named after the subsystem with a simple enumeration
 * number appended. The registered devices are not explicitly named;
 * only 'id' in the device needs to be set.
 *
 * Do not use this interface for anything new, it exists for compatibility
 * with bad ideas only. New subsystems should use plain subsystems; and
 * add the subsystem-wide attributes should be added to the subsystem
 * directory itself and not some create fake root-device placed in
 * /sys/devices/system/<name>.
 */
int subsys_system_register(struct bus_type *subsys,
  const struct attribute_group **groups)
{
return subsys_register(subsys, groups, &system_kset->kobj);
}
EXPORT_SYMBOL_GPL(subsys_system_register);




/******************************************************************************/
kernel/drivers/soc/qcom/subsystem_restart.c


static int __init subsys_restart_init(void)
{
int ret;


ssr_wq = alloc_workqueue("ssr_wq", WQ_CPU_INTENSIVE, 0);
/*registet bus_type*/
ret = bus_register(&subsys_bus_type);
/*create debugfs: msm_subsys*/
ret = subsys_debugfs_init();


char_class = class_create(THIS_MODULE, "subsys");


ret = atomic_notifier_chain_register(&panic_notifier_list,
&panic_nb);
return 0;


}
arch_initcall(subsys_restart_init);




static struct device_attribute subsys_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(state),
__ATTR_RO(crash_count),
__ATTR(restart_level, 0644, restart_level_show, restart_level_store),
__ATTR(firmware_name, 0644, firmware_name_show, firmware_name_store),
__ATTR(system_debug, 0644, system_debug_show, system_debug_store),
__ATTR_NULL,
};


static struct bus_type subsys_bus_type = {
.name = "msm_subsys",
.dev_attrs = subsys_attrs,
};


/**
 * struct subsys_desc - subsystem descriptor
 * @name: name of subsystem
 * @fw_name: firmware name
 * @depends_on: subsystem this subsystem depends on to operate
 * @dev: parent device
 * @owner: module the descriptor belongs to
 * @shutdown: Stop a subsystem
 * @powerup: Start a subsystem
 * @crash_shutdown: Shutdown a subsystem when the system crashes (can't sleep)
 * @ramdump: Collect a ramdump of the subsystem
 * @free_memory: Free the memory associated with this subsystem
 * @is_not_loadable: Indicate if subsystem firmware is not loadable via pil
 * framework
 * @no_auth: Set if subsystem does not rely on PIL to authenticate and bring
 * it out of reset
 * @ssctl_instance_id: Instance id used to connect with SSCTL service
 * @sysmon_pid: pdev id that sysmon is probed with for the subsystem
 * @sysmon_shutdown_ret: Return value for the call to sysmon_send_shutdown
 * @system_debug: If "set", triggers a device restart when the
 * subsystem's wdog bite handler is invoked.
 * @edge: GLINK logical name of the subsystem
 */
struct subsys_desc {
const char *name;
char fw_name[256];
const char *depends_on;
struct device *dev;
struct module *owner;


int (*shutdown)(const struct subsys_desc *desc, bool force_stop);
int (*powerup)(const struct subsys_desc *desc);
void (*crash_shutdown)(const struct subsys_desc *desc);
int (*ramdump)(int, const struct subsys_desc *desc);
void (*free_memory)(const struct subsys_desc *desc);
irqreturn_t (*err_fatal_handler) (int irq, void *dev_id);
irqreturn_t (*stop_ack_handler) (int irq, void *dev_id);
irqreturn_t (*wdog_bite_handler) (int irq, void *dev_id);
int is_not_loadable;
int err_fatal_gpio;
unsigned int err_fatal_irq;
unsigned int err_ready_irq;
unsigned int stop_ack_irq;
unsigned int wdog_bite_irq;
int force_stop_gpio;
int ramdump_disable_gpio;
int shutdown_ack_gpio;
int ramdump_disable;
bool no_auth;
int ssctl_instance_id;
u32 sysmon_pid;
int sysmon_shutdown_ret;
bool system_debug;
const char *edge;
};


/**
 * struct subsys_device - subsystem device
 * @desc: subsystem descriptor
 * @work: context for subsystem_restart_wq_func() for this device
 * @ssr_wlock: prevents suspend during subsystem_restart()
 * @wlname: name of wakeup source
 * @device_restart_work: work struct for device restart
 * @track: state tracking and locking
 * @notify: subsys notify handle
 * @dev: device
 * @owner: module that provides @desc
 * @count: reference count of subsystem_get()/subsystem_put()
 * @id: ida
 * @restart_level: restart level (0 - panic, 1 - related, 2 - independent, etc.)
 * @restart_order: order of other devices this devices restarts with
 * @crash_count: number of times the device has crashed
 * @dentry: debugfs directory for this device
 * @do_ramdump_on_put: ramdump on subsystem_put() if true
 * @err_ready: completion variable to record error ready from subsystem
 * @crashed: indicates if subsystem has crashed
 * @notif_state: current state of subsystem in terms of subsys notifications
 */
struct subsys_device {
struct subsys_desc *desc;
struct work_struct work;
struct wakeup_source ssr_wlock;
char wlname[64];
struct work_struct device_restart_work;
struct subsys_tracking track;


void *notify;
struct device dev;
struct module *owner;
int count;
int id;
int restart_level;
int crash_count;
struct subsys_soc_restart_order *restart_order;
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
#endif
bool do_ramdump_on_put;
struct cdev char_dev;
dev_t dev_no;
struct completion err_ready;
bool crashed;
int notif_state;
struct list_head list;
};


struct subsys_device *subsys_register(struct subsys_desc *desc)
{
struct subsys_device *subsys;
struct device_node *ofnode = desc->dev->of_node;
int ret;


subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);


subsys->desc = desc;
subsys->owner = desc->owner;
subsys->dev.parent = desc->dev;
subsys->dev.bus = &subsys_bus_type;
subsys->dev.release = subsys_device_release;
subsys->notif_state = -1;
subsys->desc->sysmon_pid = -1;
strlcpy(subsys->desc->fw_name, desc->name,
sizeof(subsys->desc->fw_name));


subsys->notify = subsys_notif_add_subsys(desc->name);


snprintf(subsys->wlname, sizeof(subsys->wlname), "ssr(%s)", desc->name);
wakeup_source_init(&subsys->ssr_wlock, subsys->wlname);
INIT_WORK(&subsys->work, subsystem_restart_wq_func);
INIT_WORK(&subsys->device_restart_work, device_restart_work_hdlr);
spin_lock_init(&subsys->track.s_lock);


subsys->id = ida_simple_get(&subsys_ida, 0, 0, GFP_KERNEL);
dev_set_name(&subsys->dev, "subsys%d", subsys->id);


mutex_init(&subsys->track.lock);


ret = subsys_debugfs_add(subsys);


ret = device_register(&subsys->dev);




ret = subsys_char_device_add(subsys);


if (ofnode) {
}
return subsys
}


root@gemini:/sys/bus/msm_subsys/devices # ls -al
lrwxrwxrwx root     root              1970-02-23 07:58 subsys0 -> ../../../devices/soc/ce0000.qcom,venus/subsys0
lrwxrwxrwx root     root              1970-02-23 07:58 subsys1 -> ../../../devices/soc/soc:qcom,kgsl-hyp/subsys1
lrwxrwxrwx root     root              1970-02-23 07:58 subsys2 -> ../../../devices/soc/soc:qcom,cnss/subsys2
lrwxrwxrwx root     root              1970-02-23 07:58 subsys3 -> ../../../devices/soc/9300000.qcom,lpass/subsys3
lrwxrwxrwx root     root              1970-02-23 07:58 subsys4 -> ../../../devices/soc/1c00000.qcom,ssc/subsys4
lrwxrwxrwx root     root              1970-02-23 07:58 subsys5 -> ../../../devices/soc/2080000.qcom,mss/subsys5


root@gemini:/sys/bus/msm_subsys/devices/subsys0 # ls -al
-r--r--r-- root     root         4096 2016-10-31 17:58 crash_count
-rw-r--r-- root     root         4096 2016-10-31 17:58 firmware_name
-r--r--r-- root     root         4096 1970-02-23 07:58 name
drwxr-xr-x root     root              1970-02-23 07:58 power
-rw-r--r-- root     root         4096 1970-02-23 07:58 restart_level
-r--r--r-- root     root         4096 2016-10-31 17:58 state
lrwxrwxrwx root     root              2016-10-31 17:58 subsystem -> ../../../../bus/msm_subsys
-rw-r--r-- root     root         4096 2016-10-31 17:58 system_debug
-rw-r--r-- root     root         4096 1970-02-23 07:58 uevent
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值